dsh-zotero 0.3.1 → 0.4.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.en.md +80 -174
- package/README.md +79 -170
- package/lib/client.js +2113 -1230
- package/lib/client.js.map +4 -4
- package/lib/config.d.ts +1 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +30 -2
- package/lib/config.js.map +1 -1
- package/lib/constants.d.ts +16 -0
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +16 -0
- package/lib/constants.js.map +1 -1
- package/lib/evidence.d.ts +16 -4
- package/lib/evidence.d.ts.map +1 -1
- package/lib/evidence.js +87 -14
- package/lib/evidence.js.map +1 -1
- package/lib/export-items.d.ts +29 -0
- package/lib/export-items.d.ts.map +1 -0
- package/lib/export-items.js +61 -0
- package/lib/export-items.js.map +1 -0
- package/lib/export-mapping.d.ts +80 -0
- package/lib/export-mapping.d.ts.map +1 -0
- package/lib/export-mapping.js +215 -0
- package/lib/export-mapping.js.map +1 -0
- package/lib/http-client.d.ts.map +1 -1
- package/lib/http-client.js +5 -3
- package/lib/http-client.js.map +1 -1
- package/lib/normalize.d.ts.map +1 -1
- package/lib/normalize.js +4 -0
- package/lib/normalize.js.map +1 -1
- package/lib/presentation-meta.d.ts +93 -6
- package/lib/presentation-meta.d.ts.map +1 -1
- package/lib/presentation-meta.js +72 -7
- package/lib/presentation-meta.js.map +1 -1
- package/lib/prompt.d.ts +8 -4
- package/lib/prompt.d.ts.map +1 -1
- package/lib/prompt.js +13 -13
- package/lib/prompt.js.map +1 -1
- package/lib/provider-local.d.ts +54 -15
- package/lib/provider-local.d.ts.map +1 -1
- package/lib/provider-local.js +272 -84
- package/lib/provider-local.js.map +1 -1
- package/lib/tools/export.d.ts +54 -4
- package/lib/tools/export.d.ts.map +1 -1
- package/lib/tools/export.js +41 -8
- package/lib/tools/export.js.map +1 -1
- package/lib/tools/retrieve.d.ts +6 -0
- package/lib/tools/retrieve.d.ts.map +1 -1
- package/lib/tools/retrieve.js +12 -3
- package/lib/tools/retrieve.js.map +1 -1
- package/lib/tools/search.d.ts +3 -0
- package/lib/tools/search.d.ts.map +1 -1
- package/lib/tools/search.js +5 -1
- package/lib/tools/search.js.map +1 -1
- package/lib/types.d.ts +52 -4
- package/lib/types.d.ts.map +1 -1
- package/package.json +3 -2
package/README.en.md
CHANGED
|
@@ -1,224 +1,130 @@
|
|
|
1
|
-
<
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
+
# dsh-zotero
|
|
4
|
+
|
|
5
|
+
<img
|
|
6
|
+
src="https://readme-typing-svg.demolab.com?font=JetBrains+Mono&weight=500&size=18&pause=2000&color=CC2936¢er=true&vCenter=true&width=760&lines=%3E+Zotero+as+an+evidence+store+for+agents."
|
|
7
|
+
alt="dsh-zotero"
|
|
8
|
+
/>
|
|
3
9
|
<p align="center">
|
|
4
|
-
<
|
|
10
|
+
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/v/dsh-zotero" alt="npm version" style="max-width:100%;"></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/dm/dsh-zotero" alt="npm downloads" style="max-width:100%;"></a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/l/dsh-zotero" alt="license" style="max-width:100%;"></a>
|
|
13
|
+
<a href="https://awesome-dsh-plugin.com"><img src="https://awesome-dsh-plugin.com/badge.svg" alt="Awesome DSH Plugin"></a>
|
|
5
14
|
</p>
|
|
15
|
+
</div>
|
|
6
16
|
|
|
7
17
|
<p align="center">
|
|
8
|
-
<a href="
|
|
9
|
-
<img src="https://img.shields.io/npm/v/dsh-zotero" alt="npm version">
|
|
10
|
-
<img src="https://img.shields.io/npm/dm/dsh-zotero" alt="npm downloads">
|
|
11
|
-
<img src="https://img.shields.io/npm/l/dsh-zotero" alt="license">
|
|
18
|
+
<a href="README.md"><b>中文</b></a> · <b>English</b>
|
|
12
19
|
</p>
|
|
13
20
|
|
|
14
|
-
|
|
21
|
+
dsh-zotero is a [Zotero](https://www.zotero.org) plugin designed for agent research workflows. Agents can search your library directly, view metadata and notes, extract evidence passages relevant to a question, open source PDFs, and generate citations and bibliographies.
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img src="docs/images/header-collage.png" width="70%" alt="dsh-zotero UI: sources panel, evidence extraction, export view">
|
|
25
|
+
</p>
|
|
17
26
|
|
|
18
27
|
## Tools
|
|
19
28
|
|
|
20
|
-
| Tool | Purpose
|
|
21
|
-
| ------------------- |
|
|
22
|
-
| `zotero_search` |
|
|
23
|
-
| `zotero_get` |
|
|
24
|
-
| `zotero_retrieve` |
|
|
25
|
-
| `zotero_attachment` |
|
|
26
|
-
| `zotero_export` |
|
|
27
|
-
|
|
28
|
-
## Usage example
|
|
29
|
+
| Tool | Purpose |
|
|
30
|
+
| ------------------- | ------------------------------------------------------------------------------- |
|
|
31
|
+
| `zotero_search` | Search by title/creator/year; `everything` mode also searches indexed full text |
|
|
32
|
+
| `zotero_get` | Read one item's metadata, optionally with notes, annotations, and attachments |
|
|
33
|
+
| `zotero_retrieve` | Return the most relevant evidence passages for a query |
|
|
34
|
+
| `zotero_attachment` | Resolve a ref to a verified on-disk path or linked URL |
|
|
35
|
+
| `zotero_export` | Generate citations, bibliographies, BibTeX/BibLaTeX/RIS/CSL JSON |
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
> User: "Find papers about FlashAttention."
|
|
33
|
-
> Agent → `zotero_search`, returning candidates with refs.
|
|
34
|
-
>
|
|
35
|
-
> User: "What is the first one? Have I read it before?"
|
|
36
|
-
> Agent → `zotero_get`: metadata, 17 annotations, 2 notes, limited previews.
|
|
37
|
-
>
|
|
38
|
-
> User: "What did I think about its evaluation?"
|
|
39
|
-
> Agent → `zotero_retrieve(query:"evaluation", sources:["annotations","notes"])`, returning matching note and annotation evidence.
|
|
40
|
-
>
|
|
41
|
-
> User: "How does the paper itself explain memory efficiency?"
|
|
42
|
-
> Agent → `zotero_retrieve(query:"memory efficiency", sources:["fulltext","abstract"])`, returning abstract and full-text passages.
|
|
43
|
-
>
|
|
44
|
-
> User: "Show me the original PDF."
|
|
45
|
-
> Agent → `zotero_attachment(item ref)`, returning the verified file path; if the composition has a PDF/file reader, the Agent hands it off for further analysis.
|
|
46
|
-
>
|
|
47
|
-
> User: "Generate an APA bibliography for these three."
|
|
48
|
-
> Agent → `zotero_export(format:"bibliography", style:"apa")`.
|
|
49
|
-
|
|
50
|
-
## Command
|
|
51
|
-
|
|
52
|
-
`/zotero status` reports connectivity, API/schema versions, and the database identity (Server ID, Zotero 10+). This is the only health check. Ordinary calls fail with typed domain errors.
|
|
53
|
-
|
|
54
|
-
## Requirements
|
|
55
|
-
|
|
56
|
-
- Zotero desktop with the local API enabled: **Settings → Advanced → "Allow other applications on this computer to communicate with Zotero"**.
|
|
57
|
-
- Read access is unauthenticated on `http://127.0.0.1:23119/api`. V1 has no path that modifies library data (items, notes, tags, collections).
|
|
58
|
-
- Zotero ≥ 7 speaking local API version 3. Upgrade if the status command reports a version mismatch.
|
|
37
|
+
[Full tool reference →](docs/tools.md)
|
|
59
38
|
|
|
60
39
|
## Install
|
|
61
40
|
|
|
62
|
-
### By package name
|
|
63
|
-
|
|
64
41
|
```sh
|
|
65
42
|
dsh plugin --profile <name> add dsh-zotero
|
|
66
43
|
```
|
|
67
44
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
### From a local tarball
|
|
45
|
+
From GitHub source:
|
|
71
46
|
|
|
72
47
|
```sh
|
|
73
|
-
|
|
74
|
-
npm pack
|
|
75
|
-
dsh plugin --profile <name> add ./dsh-zotero-0.1.0.tgz
|
|
48
|
+
dsh plugin --profile <name> add github:Vncntvx/dsh-zotero
|
|
76
49
|
```
|
|
77
50
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
### From the GitHub source
|
|
51
|
+
From a local tarball:
|
|
81
52
|
|
|
82
53
|
```sh
|
|
83
|
-
dsh
|
|
54
|
+
cd dsh-zotero && npm pack
|
|
55
|
+
dsh plugin --profile <name> add ./dsh-zotero-*.tgz
|
|
84
56
|
```
|
|
85
57
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```yaml
|
|
89
|
-
allowBuilds:
|
|
90
|
-
dsh-zotero: true
|
|
91
|
-
```
|
|
58
|
+
After installing, start a new session so the agent picks up the Zotero tools.
|
|
92
59
|
|
|
93
|
-
|
|
60
|
+
The plugin provides a settings card under **Settings → Plugins** where you can adjust the API address, concurrency limits, full-text retrieval toggle, and more. Changes take effect on save. See [Configuration](docs/configuration.md).
|
|
94
61
|
|
|
95
|
-
|
|
62
|
+
[Installation details →](docs/getting-started.md)
|
|
96
63
|
|
|
97
|
-
##
|
|
64
|
+
## Requirements
|
|
98
65
|
|
|
99
|
-
|
|
66
|
+
- Zotero ≥ 7 with local API enabled: **Settings → Advanced → "Allow other applications on this computer to communicate with Zotero"**
|
|
67
|
+
- Node.js ≥ 22.19 (or ≥ 24)
|
|
68
|
+
- Local API at `http://127.0.0.1:23119/api`, unauthenticated, read-only
|
|
100
69
|
|
|
101
|
-
|
|
102
|
-
| ---------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
103
|
-
| `baseUrl` | `http://127.0.0.1:23119/api` | Local API base URL. Plain loopback HTTP only. |
|
|
104
|
-
| `provider` | `local` | Provider id to select. |
|
|
105
|
-
| `timeoutMs` | `5000` | Per-request provider deadline. |
|
|
106
|
-
| `maxSearchResults` | `20` | Upper bound for `zotero_search` `limit`. |
|
|
107
|
-
| `maxNoteScanRecords` | `200` | Upper bound for note records scanned for body matches by `zotero_search`. |
|
|
108
|
-
| `maxEvidenceChars` | `6000` | Total character budget for retrieved evidence. |
|
|
109
|
-
| `maxEvidencePassages` | `4` | Upper bound for evidence passage counts. |
|
|
110
|
-
| `maxDetailChars` | `3000` | Character budget for `zotero_get` abstract previews. |
|
|
111
|
-
| `maxNoteBodyChars` | `30000` | Character budget for a note item's own body returned by `zotero_get`. |
|
|
112
|
-
| `maxNoteChars` | `2000` | Character budget per note preview in `zotero_get`. |
|
|
113
|
-
| `maxNoteRecords` | `50` | Upper bound for note records returned by `zotero_get`. |
|
|
114
|
-
| `maxAnnotationRecords` | `100` | Upper bound for annotation records returned by `zotero_get`. |
|
|
115
|
-
| `fulltextChunkWords` | `200` | Word count per full-text passage entering evidence ranking. |
|
|
116
|
-
| `maxFulltextChars` | `250000` | Full text accepted into evidence ranking. |
|
|
117
|
-
| `maxResponseBytes` | `16777216` | Streaming byte bound for every API response. |
|
|
118
|
-
| `maxExportChars` | `1000000` | Export output hard limit. Never mid-truncated. |
|
|
119
|
-
| `maxExportRefs` | `1000` | Upper bound for refs in one `zotero_export` call; keeps the request line under the server's HTTP header limit. |
|
|
120
|
-
| `defaultStyle` | `apa` | CSL style for citation/bibliography formats. |
|
|
121
|
-
| `defaultLocale` | `en-US` | CSL locale for citation/bibliography formats. |
|
|
122
|
-
| `webEnabled` | `true` | Enables the dedicated Zotero conversation tab; the gate is read once per page load. |
|
|
70
|
+
## Usage example
|
|
123
71
|
|
|
124
|
-
|
|
72
|
+
The agent calls tools step by step during a conversation. Each result becomes context for the next step.
|
|
125
73
|
|
|
126
|
-
|
|
74
|
+
```text
|
|
75
|
+
User: Find papers about Risk
|
|
76
|
+
Agent → zotero_search(query: "Risk", itemType: "journalArticle")
|
|
77
|
+
5 matches; user picks the first 3
|
|
127
78
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
- Compositions without a settings service (pure headless) never register the namespace, and the plugin behaves exactly as if unconfigured.
|
|
79
|
+
User: What does the first one's abstract say?
|
|
80
|
+
Agent → zotero_get(ref: 1, fields: ["abstractNote"])
|
|
81
|
+
Returns the full abstract
|
|
132
82
|
|
|
133
|
-
|
|
83
|
+
User: Find the methodology discussion in this paper
|
|
84
|
+
Agent → zotero_retrieve(query: "methodology", sources: ["fulltext", "notes"])
|
|
85
|
+
Returns relevant passages with page numbers
|
|
134
86
|
|
|
135
|
-
|
|
87
|
+
User: Export all three as BibTeX
|
|
88
|
+
Agent → zotero_export(refs: [1,2,3], format: "bibtex")
|
|
89
|
+
Generates BibTeX entries, ready to copy or download
|
|
90
|
+
```
|
|
136
91
|
|
|
137
|
-
|
|
138
|
-
- Below it, the session's **Zotero tool activity**: every search, read, retrieve, attachment, and export call renders as a rich card (expandable, copyable refs, evidence passages labeled by source), fully replay-driven from the conversation snapshot — the same transcript renders the same cards, and missing meta degrades to the raw content.
|
|
139
|
-
- The **Web → Session tool cards** toggle in the settings page (`webEnabled`, default on) controls the tab's registration; the gate is read once per page load, so a toggle change applies after the page reloads. When off, Zotero calls show as dsh's built-in generic cards in the trajectory.
|
|
92
|
+
More examples in [Features](docs/features.md).
|
|
140
93
|
|
|
141
94
|
## Limits
|
|
142
95
|
|
|
143
|
-
- Read-only library
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
-
|
|
147
|
-
-
|
|
96
|
+
- **Read-only library**: all operations are reads; items, notes, tags, and collections are unchanged
|
|
97
|
+
- **Loopback only**: network requests go only to `127.0.0.1:23119`
|
|
98
|
+
- **Evidence ranking is term-based**: BM25 ranks passages by query-term frequency match
|
|
99
|
+
- **Exports are static text**: returned as text, ready to copy into your target document
|
|
100
|
+
- **Full-text evidence depends on Zotero's index**: unindexed PDFs yield no full-text passages
|
|
101
|
+
- **Attachment depth depends on the harness**: `zotero_attachment` returns the file location; reading the PDF further needs a matching host capability
|
|
102
|
+
|
|
103
|
+
## Documentation
|
|
104
|
+
|
|
105
|
+
| Doc | Covers |
|
|
106
|
+
| ------------------------------------------ | ------------------------------------------------------ |
|
|
107
|
+
| [Getting Started](docs/getting-started.md) | Installation, prerequisites, first verification |
|
|
108
|
+
| [Features](docs/features.md) | Sources panel, chat integration, evidence, exports |
|
|
109
|
+
| [Tool Reference](docs/tools.md) | Parameters, return values, error codes for all 5 tools |
|
|
110
|
+
| [Configuration](docs/configuration.md) | 20 config fields, defaults, hot-reload |
|
|
111
|
+
| [Architecture](docs/architecture.md) | Data flow, layer responsibilities, design boundaries |
|
|
112
|
+
| [Development](docs/development.md) | Build, test, local development |
|
|
113
|
+
| [Troubleshooting](docs/troubleshooting.md) | 11 common issues with symptoms and fixes |
|
|
148
114
|
|
|
149
115
|
## Development
|
|
150
116
|
|
|
151
|
-
### Commands
|
|
152
|
-
|
|
153
117
|
```sh
|
|
154
|
-
npm install
|
|
155
|
-
npm test
|
|
156
|
-
npm run
|
|
157
|
-
npm run
|
|
158
|
-
npm run
|
|
159
|
-
npm run
|
|
160
|
-
npm run dev:client # watch the browser half (pair with the hot-swap overlay)
|
|
161
|
-
npm run format # prettier --write across the repo
|
|
162
|
-
npm run format:check # verify formatting (run before committing)
|
|
118
|
+
npm install --no-workspaces # this repo lives inside the deepseek-harness workspace
|
|
119
|
+
npm test # vitest unit tests against the mock Zotero server
|
|
120
|
+
npm run typecheck # tsc --noEmit for node, test, and client projects
|
|
121
|
+
npm run build # tsc emits node half into lib/; esbuild emits browser half lib/client.js
|
|
122
|
+
npm run dev # tsc --watch for host half hot reload
|
|
123
|
+
npm run dev:client # esbuild --watch for browser half hot reload
|
|
163
124
|
```
|
|
164
125
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
Integration tests run against a live Zotero and stay skipped unless enabled:
|
|
168
|
-
|
|
169
|
-
```sh
|
|
170
|
-
npm run test:integration
|
|
171
|
-
# or: ZOTERO_INTEGRATION=1 npx vitest run tests/integration/zotero.integration.spec.ts
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
### Running locally
|
|
175
|
-
|
|
176
|
-
#### From a dsh source checkout
|
|
177
|
-
|
|
178
|
-
Build the checkout once (`pnpm install && pnpm run build`), then load the plugin source through the dev overlay:
|
|
179
|
-
|
|
180
|
-
```sh
|
|
181
|
-
pnpm dsh web --patch ./dsh-zotero/dev.cordis.yml
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
`dev.cordis.yml` points the plugin entry at the absolute `src/index.ts`. The dsh source launch loads that TypeScript entry through tsx, so the plugin requires no prebuild. Update the absolute path when the checkout location differs.
|
|
185
|
-
|
|
186
|
-
#### With the npm-installed dsh
|
|
187
|
-
|
|
188
|
-
This plugin builds in two halves: the **Node side** (`lib/`, emitted by `tsc`, holds the service, tools, provider, and other logic) and the **browser side** (`lib/client.js`, emitted by `esbuild`, holds the dsh web configuration card and the Zotero tab view). The three flows below cover the common cases.
|
|
189
|
-
|
|
190
|
-
- `npm run build` emits both halves; `npm run build:client` rebuilds only the browser side.
|
|
191
|
-
- The rest of this section assumes `npm run build` has been run at least once so `lib/` exists.
|
|
192
|
-
|
|
193
|
-
**① Resident instance verification (tarball install)**
|
|
194
|
-
|
|
195
|
-
Pack a tarball and install it into a profile. The plugin runs from the tarball's built artifacts; code updates require re-packing and re-installing. Verify with the production-stack smoke after install:
|
|
196
|
-
|
|
197
|
-
```sh
|
|
198
|
-
npm pack
|
|
199
|
-
dsh plugin --profile <name> add ./dsh-zotero-0.1.0.tgz
|
|
200
|
-
cd ~/.dsh/profiles/<name>
|
|
201
|
-
node --input-type=module < /path/to/dsh-zotero/scripts/smoke.mjs
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
The smoke must be run inside the profile directory, so bare imports resolve from the profile's flat `node_modules`. It verifies `status`, `search`, `get`, `retrieve`, `export`, the policy prompt section, and the registration of all five tools; `SMOKE PASS` indicates the packed plugin passes the installed-path checks.
|
|
205
|
-
|
|
206
|
-
**② Node-side hot-swap development**
|
|
207
|
-
|
|
208
|
-
The `dev-lib.cordis.yml` overlay disables the profile's tarball row (id `zotero`), inserts a `zotero-dev` row pointing at this checkout's `lib/index.js`, and re-enables HMR. The production web profile disables loader HMR by default, and HMR's watch root lives in the profile directory, so the overlay sets `base` explicitly. When the build output changes, HMR disposes the old instance and reconstructs the plugin in the same process — no dsh restart needed:
|
|
209
|
-
|
|
210
|
-
```sh
|
|
211
|
-
cd ./dsh-zotero # from the deepseek-harness checkout
|
|
212
|
-
npm run dev & # tsc --watch: rebuild lib on src changes
|
|
213
|
-
dsh web --patch ./dev-lib.cordis.yml --port 3307
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Hot swap only affects the instance started with `--patch`; the resident instance keeps running the tarball version, independently.
|
|
217
|
-
|
|
218
|
-
**③ Browser-side development**
|
|
219
|
-
|
|
220
|
-
The web frontend only scans loader rows whose `name` is a bare package name (npm-resolvable to `package.json`) to load the browser-side bundle. `dev-lib.cordis.yml` uses an absolute-path row, which does not trigger browser-side loading, so the card does not appear in the ② dev instance. To develop the card, first install this checkout into the profile (`npm install <this repo path>` as a `file:` dependency, or pack and install the tarball), then pair `npm run dev:client` (esbuild watch) with the hot-swap overlay: browser-bundle changes make HMR re-fetch `/plugins/dsh-zotero/client.js`.
|
|
126
|
+
Build output splits into `lib/` (Node side) and `lib/client.js` (browser side — settings card + Zotero tab). For full plugin development with both halves, use the `dev-lib.cordis.yml` overlay. See [Development](docs/development.md) for details.
|
|
221
127
|
|
|
222
128
|
## License
|
|
223
129
|
|
|
224
|
-
MIT
|
|
130
|
+
[MIT](./LICENSE) — free to use, modify, and distribute.
|
package/README.md
CHANGED
|
@@ -1,221 +1,130 @@
|
|
|
1
|
-
<
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
+
# dsh-zotero
|
|
4
|
+
|
|
5
|
+
<img
|
|
6
|
+
src="https://readme-typing-svg.demolab.com?font=JetBrains+Mono&weight=500&size=22&pause=2000&color=CC2936¢er=true&vCenter=true&width=760&lines=%3E+Zotero+as+an+evidence+store+for+agents."
|
|
7
|
+
alt="dsh-zotero"
|
|
8
|
+
/>
|
|
3
9
|
<p align="center">
|
|
4
|
-
<a href="
|
|
10
|
+
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/v/dsh-zotero" alt="npm version" style="max-width:100%;"></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/dm/dsh-zotero" alt="npm downloads" style="max-width:100%;"></a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/dsh-zotero"><img src="https://img.shields.io/npm/l/dsh-zotero" alt="license" style="max-width:100%;"></a>
|
|
13
|
+
<a href="https://awesome-dsh-plugin.com"><img src="https://awesome-dsh-plugin.com/badge.svg" alt="Awesome DSH Plugin"></a>
|
|
5
14
|
</p>
|
|
15
|
+
</div>
|
|
6
16
|
|
|
7
17
|
<p align="center">
|
|
8
|
-
<a href="
|
|
9
|
-
<img src="https://img.shields.io/npm/v/dsh-zotero" alt="npm version">
|
|
10
|
-
<img src="https://img.shields.io/npm/dm/dsh-zotero" alt="npm downloads">
|
|
11
|
-
<img src="https://img.shields.io/npm/l/dsh-zotero" alt="license">
|
|
18
|
+
<a href="README.en.md"><b>English</b></a> · <b>中文</b>
|
|
12
19
|
</p>
|
|
13
20
|
|
|
14
|
-
|
|
21
|
+
dsh-zotero 是面向 Agent 研究工作流的 [Zotero](https://www.zotero.org) 插件。Agent 可以直接从你的文献库中搜索文献、查看元数据和笔记、提取与问题相关的证据段落、打开原文 PDF,并生成引用和参考文献表。
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
<p align="center">
|
|
24
|
+
<img src="docs/images/header-collage.png" width="70%" alt="dsh-zotero 界面:来源面板、证据提取、导出视图">
|
|
25
|
+
</p>
|
|
17
26
|
|
|
18
27
|
## 工具
|
|
19
28
|
|
|
20
|
-
| 工具 | 用途
|
|
21
|
-
| ------------------- |
|
|
22
|
-
| `zotero_search` |
|
|
23
|
-
| `zotero_get` |
|
|
24
|
-
| `zotero_retrieve` |
|
|
25
|
-
| `zotero_attachment` |
|
|
26
|
-
| `zotero_export` |
|
|
27
|
-
|
|
28
|
-
## 使用示例
|
|
29
|
-
|
|
30
|
-
Agent 按需求逐层深入,一段典型对话:
|
|
31
|
-
|
|
32
|
-
> 用户:「帮我找 FlashAttention 相关论文」
|
|
33
|
-
> Agent → `zotero_search`,返回候选条目与 ref。
|
|
34
|
-
>
|
|
35
|
-
> 用户:「第一篇是什么?我以前读过吗?」
|
|
36
|
-
> Agent → `zotero_get`:元数据、17 条批注、2 条笔记与有限预览。
|
|
37
|
-
>
|
|
38
|
-
> 用户:「我当时对 evaluation 有什么意见?」
|
|
39
|
-
> Agent → `zotero_retrieve(query:"evaluation", sources:["annotations","notes"])`,返回相关笔记与批注证据。
|
|
40
|
-
>
|
|
41
|
-
> 用户:「论文自己怎么解释 memory efficiency?」
|
|
42
|
-
> Agent → `zotero_retrieve(query:"memory efficiency", sources:["fulltext","abstract"])`,返回摘要与全文片段。
|
|
43
|
-
>
|
|
44
|
-
> 用户:「我要看原 PDF」
|
|
45
|
-
> Agent → `zotero_attachment(条目 ref)`,返回已验证的文件路径;若当前 Harness 配置了 PDF/file 读取能力,再交给该能力继续分析。
|
|
46
|
-
>
|
|
47
|
-
> 用户:「把这三篇生成 APA 参考文献表」
|
|
48
|
-
> Agent → `zotero_export(format:"bibliography", style:"apa")`。
|
|
49
|
-
|
|
50
|
-
## 命令
|
|
51
|
-
|
|
52
|
-
`/zotero status` 报告连通性、API/schema 版本和数据库身份标识(Server ID,Zotero 10+)。这是唯一的健康检查。普通调用失败时返回带类型的领域错误。
|
|
29
|
+
| 工具 | 用途 |
|
|
30
|
+
| ------------------- | ------------------------------------------------------- |
|
|
31
|
+
| `zotero_search` | 按标题/作者/年份搜索,`everything` 模式连全文索引一起搜 |
|
|
32
|
+
| `zotero_get` | 读取单条文献的元数据,可选返回笔记、批注、附件清单 |
|
|
33
|
+
| `zotero_retrieve` | 按查询词返回最相关的证据段落(批注/笔记/摘要/全文) |
|
|
34
|
+
| `zotero_attachment` | 将文献 ref 解析为已验证的磁盘路径或链接 URL |
|
|
35
|
+
| `zotero_export` | 生成引用、参考文献表、BibTeX/BibLaTeX/RIS/CSL JSON |
|
|
53
36
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- 已安装 Zotero 桌面版,并启用本地 API:**设置 → 高级 → “Allow other applications on this computer to communicate with Zotero”**。
|
|
57
|
-
- 本地 API 为无认证读取,地址为 `http://127.0.0.1:23119/api`。V1 没有任何修改文献库数据(条目、笔记、标签、分类等)的路径。
|
|
58
|
-
- Zotero ≥ 7,本地 API 版本为 3。如果 status 命令报告版本不匹配,请升级。
|
|
37
|
+
[完整工具参考 →](docs/tools.md)
|
|
59
38
|
|
|
60
39
|
## 安装
|
|
61
40
|
|
|
62
|
-
### 按包名安装
|
|
63
|
-
|
|
64
41
|
```sh
|
|
65
42
|
dsh plugin --profile <name> add dsh-zotero
|
|
66
43
|
```
|
|
67
44
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
### 本地 tarball
|
|
71
|
-
|
|
72
|
-
```sh
|
|
73
|
-
cd dsh-zotero
|
|
74
|
-
npm pack
|
|
75
|
-
dsh plugin --profile <name> add ./dsh-zotero-0.1.0.tgz
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
`npm pack` 先运行 `prepare` 构建 `lib/`,适合未发布或本地试装。
|
|
79
|
-
|
|
80
|
-
### 从 GitHub 源码安装
|
|
45
|
+
从 GitHub 源码安装:
|
|
81
46
|
|
|
82
47
|
```sh
|
|
83
48
|
dsh plugin --profile <name> add github:Vncntvx/dsh-zotero
|
|
84
49
|
```
|
|
85
50
|
|
|
86
|
-
|
|
51
|
+
本地 tarball:
|
|
87
52
|
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
|
|
53
|
+
```sh
|
|
54
|
+
cd dsh-zotero && npm pack
|
|
55
|
+
dsh plugin --profile <name> add ./dsh-zotero-*.tgz
|
|
91
56
|
```
|
|
92
57
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
插件以 id `zotero` 挂载,下次启动 dsh 时生效。安装或启用插件后,如果当前会话创建于插件加载之前,请新建会话,确保 Agent 获得 Zotero 工具。
|
|
96
|
-
|
|
97
|
-
## 配置
|
|
98
|
-
|
|
99
|
-
所有值都是 `Config` 字段,可在 bundle 的 `config` 块中修改(例如通过 `dsh plugin config`)。以下为默认值。
|
|
58
|
+
安装后重启新建会话,Agent 即可使用 Zotero 工具。
|
|
100
59
|
|
|
101
|
-
|
|
102
|
-
| ---------------------- | ---------------------------- | -------------------------------------------------------------------------------------- |
|
|
103
|
-
| `baseUrl` | `http://127.0.0.1:23119/api` | 本地 API 基础 URL。仅支持纯回环 HTTP。 |
|
|
104
|
-
| `provider` | `local` | 要选择的 provider id。 |
|
|
105
|
-
| `timeoutMs` | `5000` | 每个请求的 provider 超时时间。 |
|
|
106
|
-
| `maxSearchResults` | `20` | `zotero_search` `limit` 的上限。 |
|
|
107
|
-
| `maxNoteScanRecords` | `200` | `zotero_search` 补扫笔记正文的笔记数量上限。 |
|
|
108
|
-
| `maxEvidenceChars` | `6000` | 检索证据的总字符预算。 |
|
|
109
|
-
| `maxEvidencePassages` | `4` | 证据片段数量的上限。 |
|
|
110
|
-
| `maxDetailChars` | `3000` | `zotero_get` 摘要预览的字符预算。 |
|
|
111
|
-
| `maxNoteBodyChars` | `30000` | `zotero_get` 返回 note 条目自身正文的字符预算。 |
|
|
112
|
-
| `maxNoteChars` | `2000` | `zotero_get` 单条笔记预览的字符预算。 |
|
|
113
|
-
| `maxNoteRecords` | `50` | `zotero_get` 返回笔记数量的上限。 |
|
|
114
|
-
| `maxAnnotationRecords` | `100` | `zotero_get` 返回批注数量的上限。 |
|
|
115
|
-
| `fulltextChunkWords` | `200` | 进入证据排序的全文片段词数。 |
|
|
116
|
-
| `maxFulltextChars` | `250000` | 进入证据排序的全文大小上限。 |
|
|
117
|
-
| `maxResponseBytes` | `16777216` | 每个 API 响应的流式字节上限。 |
|
|
118
|
-
| `maxExportChars` | `1000000` | 导出输出的硬上限。不会中途截断。 |
|
|
119
|
-
| `maxExportRefs` | `1000` | 单次 `zotero_export` 的 refs 数量上限,保护请求行不超服务器 HTTP 头限制。 |
|
|
120
|
-
| `defaultStyle` | `apa` | 引用/参考文献使用的 CSL 样式。 |
|
|
121
|
-
| `defaultLocale` | `en-US` | 引用/参考文献使用的 CSL locale。 |
|
|
122
|
-
| `webEnabled` | `true` | 是否在会话顶部显示 Zotero 专属标签页;开关在每次页面加载时读取,切换后需刷新页面生效。 |
|
|
60
|
+
插件在 **Settings → Plugins** 中提供配置卡片,可调整 API 地址、并发限制、全文检索开关等参数,保存即生效。详见 [配置](docs/configuration.md)。
|
|
123
61
|
|
|
124
|
-
|
|
62
|
+
[安装详情 →](docs/getting-started.md)
|
|
125
63
|
|
|
126
|
-
|
|
64
|
+
## 前置条件
|
|
127
65
|
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
- 没有设置服务的组合(纯 headless)不会注册命名空间,插件行为与未配置时完全一致。
|
|
66
|
+
- Zotero ≥ 7 桌面版,启用本地 API:**设置 → 高级 → "允许其他应用程序与 Zotero 通信"**
|
|
67
|
+
- Node.js ≥ 22.19(或 ≥ 24)
|
|
68
|
+
- 本地 API 地址 `http://127.0.0.1:23119/api`,无认证,只读
|
|
132
69
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
dsh web 的会话视图是标签页环(Chat、Trajectory、…)。插件注册一个专属 **Zotero** 标签页(`conversation.view`,id `zotero`,位于 Trajectory 与 dsh-context 之后),不触碰 dsh 自带的聊天与轨迹视图:
|
|
136
|
-
|
|
137
|
-
- 标签页顶部是**连接条**:挂载时探测一次、每次手动刷新再探测一次(请求驱动,无轮询定时器);显示连接状态、API/Schema 版本、Server ID(Zotero 10+)与上次检查时间;Zotero 不可用时显示诊断信息。
|
|
138
|
-
- 下方是本会话的 **Zotero 工具活动**:每次搜索、精读、取证、附件解析与导出调用都渲染为富卡片(可展开、ref 可复制、证据段落标注来源),完全由会话快照重放驱动——同一段记录永远渲染出同样的卡片,meta 缺失时降级为原始内容。
|
|
139
|
-
- 设置页的 **Web → 会话工具卡片** 开关(`webEnabled`,默认开启)控制标签页的注册;开关在每次页面加载时读取一次,切换后需刷新页面生效。关闭后,Zotero 调用在轨迹中显示为 dsh 内置的通用卡片。
|
|
140
|
-
|
|
141
|
-
### 限制
|
|
142
|
-
|
|
143
|
-
- 只读文献库:没有任何路径会修改条目、笔记、标签或合集。
|
|
144
|
-
- 全文证据依赖 Zotero 的索引:`everything` 搜索与 `retrieve` 的全文段落都需要已建立索引。
|
|
145
|
-
- 笔记正文搜索是客户端扫描:仅限 library/collection 作用域与第一页结果,受 `maxNoteScanRecords` 限制;超出上限的笔记永远不会命中。
|
|
146
|
-
- 附件深度取决于宿主组合:`zotero_attachment` 返回文件位置;继续阅读该 PDF 需要宿主具备对应的文件/PDF 能力。
|
|
147
|
-
- 证据排序是基于词项的相关性,而非向量或语义检索。
|
|
148
|
-
|
|
149
|
-
## 开发
|
|
150
|
-
|
|
151
|
-
### 命令
|
|
152
|
-
|
|
153
|
-
```sh
|
|
154
|
-
npm install # 使用本地 npm 缓存(见下方 workspace 说明)
|
|
155
|
-
npm test # 单元测试(mock Zotero server + 浏览器卡片测试)
|
|
156
|
-
npm run test:coverage # 对 src/ 的 100% 覆盖率门禁
|
|
157
|
-
npm run typecheck # tsc --noEmit,node / test / client 三个项目
|
|
158
|
-
npm run build # tsc 生成 node 半 lib/ + esbuild 生成浏览器半 lib/client.js
|
|
159
|
-
npm run build:client # 只重建浏览器半(含 loader 交接格式自检)
|
|
160
|
-
npm run dev:client # 浏览器半 watch 模式(配合热替换 overlay)
|
|
161
|
-
npm run format # prettier --write 全仓格式化
|
|
162
|
-
npm run format:check # 校验格式化(提交前执行)
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
> 本仓库位于 deepseek-harness workspace 树内:父目录 `package.json` 声明了 `workspaces`,npm 会向上找到它并尝试安装整个 workspace。请使用 `npm install --no-workspaces`(或在本仓库放置含 `workspaces=false` 的 `.npmrc`)。
|
|
166
|
-
|
|
167
|
-
集成测试面向真实 Zotero,默认跳过,需显式开启:
|
|
70
|
+
## 使用示例
|
|
168
71
|
|
|
169
|
-
|
|
170
|
-
npm run test:integration
|
|
171
|
-
# 或:ZOTERO_INTEGRATION=1 npx vitest run tests/integration/zotero.integration.spec.ts
|
|
172
|
-
```
|
|
72
|
+
Agent 在对话中根据用户需求逐步调用工具,每次调用的结果作为下一步的上下文。
|
|
173
73
|
|
|
174
|
-
|
|
74
|
+
```text
|
|
75
|
+
用户:帮我找 Risk 相关的论文
|
|
76
|
+
Agent → zotero_search(query: "Risk", itemType: "journalArticle")
|
|
77
|
+
5 篇匹配结果,用户选择前 3 篇
|
|
175
78
|
|
|
176
|
-
|
|
79
|
+
用户:第一篇的摘要说了什么?
|
|
80
|
+
Agent → zotero_get(ref: 1, fields: ["abstractNote"])
|
|
81
|
+
返回摘要全文
|
|
177
82
|
|
|
178
|
-
|
|
83
|
+
用户:这篇里关于方法论的讨论,帮我找出来
|
|
84
|
+
Agent → zotero_retrieve(query: "methodology", sources: ["fulltext", "notes"])
|
|
85
|
+
返回相关段落,带页码和来源
|
|
179
86
|
|
|
180
|
-
|
|
181
|
-
|
|
87
|
+
用户:把这三篇导出为 BibTeX
|
|
88
|
+
Agent → zotero_export(refs: [1,2,3], format: "bibtex")
|
|
89
|
+
生成 BibTeX 条目,可复制或下载
|
|
182
90
|
```
|
|
183
91
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
#### 使用 npm 安装的 dsh
|
|
187
|
-
|
|
188
|
-
本插件分两部分构建:**Node 端**(`lib/`,由 `tsc` 生成,包含服务、工具、provider 等逻辑)与**浏览器端**(`lib/client.js`,由 `esbuild` 生成,包含 dsh web 的配置卡片与 Zotero 标签视图)。下面三种开发流程覆盖了不同场景。
|
|
92
|
+
更多示例见 [功能概览](docs/features.md)。
|
|
189
93
|
|
|
190
|
-
|
|
94
|
+
## 限制
|
|
191
95
|
|
|
192
|
-
|
|
96
|
+
- **只读文献库**:所有操作均为读取,不修改条目、笔记、标签或分类
|
|
97
|
+
- **只访问本机**:网络请求仅发往 `127.0.0.1:23119`
|
|
98
|
+
- **证据排序是词项相关性**:基于 BM25,按查询词与 passage 的词频匹配度排序
|
|
99
|
+
- **导出是静态文本**:以文本形式返回,需要手动复制到目标位置
|
|
100
|
+
- **全文证据依赖 Zotero 索引**:未索引的 PDF 无法提供全文段落
|
|
101
|
+
- **附件深度取决于宿主**:`zotero_attachment` 返回文件位置,继续阅读 PDF 需要宿主具备对应能力
|
|
193
102
|
|
|
194
|
-
|
|
195
|
-
npm pack
|
|
196
|
-
dsh plugin --profile <name> add ./dsh-zotero-0.1.0.tgz
|
|
197
|
-
cd ~/.dsh/profiles/<name>
|
|
198
|
-
node --input-type=module < /path/to/dsh-zotero/scripts/smoke.mjs
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
smoke 脚本必须在 profile 目录内运行,这样裸导入才能从 profile 的扁平 `node_modules` 中解析。脚本依次验证 `status`、`search`、`get`、`retrieve`、`export`、策略提示词分区,以及五个工具的注册情况;输出 `SMOKE PASS` 表示打包后的插件通过了安装路径验证。
|
|
103
|
+
## 文档
|
|
202
104
|
|
|
203
|
-
|
|
105
|
+
| 文档 | 内容 |
|
|
106
|
+
| ----------------------------------- | ---------------------------------- |
|
|
107
|
+
| [快速上手](docs/getting-started.md) | 安装、前置条件、首次验证 |
|
|
108
|
+
| [功能概览](docs/features.md) | 来源面板、对话集成、证据提取、导出 |
|
|
109
|
+
| [工具参考](docs/tools.md) | 5 个工具的参数、返回值、错误码 |
|
|
110
|
+
| [配置](docs/configuration.md) | 20 个配置字段、默认值、热更新 |
|
|
111
|
+
| [架构](docs/architecture.md) | 数据流、各层职责、设计边界 |
|
|
112
|
+
| [开发指南](docs/development.md) | 构建、测试、本地开发 |
|
|
113
|
+
| [问题排查](docs/troubleshooting.md) | 11 个常见问题的症状和处理 |
|
|
204
114
|
|
|
205
|
-
|
|
115
|
+
## 开发
|
|
206
116
|
|
|
207
117
|
```sh
|
|
208
|
-
|
|
209
|
-
npm
|
|
210
|
-
|
|
118
|
+
npm install --no-workspaces # 本仓库在 deepseek-harness 工作区内,需要加 --no-workspaces
|
|
119
|
+
npm test # 单元测试(vitest,mock Zotero 服务器)
|
|
120
|
+
npm run typecheck # tsc --noEmit,覆盖 node、test、client 三个项目
|
|
121
|
+
npm run build # tsc 编译 node 部分到 lib/,esbuild 编译浏览器部分到 lib/client.js
|
|
122
|
+
npm run dev # tsc --watch,host half 热更新
|
|
123
|
+
npm run dev:client # esbuild --watch,浏览器部分热更新
|
|
211
124
|
```
|
|
212
125
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
**③ 浏览器端开发**
|
|
216
|
-
|
|
217
|
-
dsh web 只会扫描 Loader 行中 `name` 为裸包名(npm 能解析到 `package.json`)的条目来加载浏览器端 bundle。`dev-lib.cordis.yml` 使用的是绝对路径行,不会触发浏览器端加载,因此卡片不会出现在 ② 的 dev 实例中。开发卡片时需要先把本仓库装进 profile(`npm install <本仓库路径>` 作为 `file:` 依赖,或 `npm pack` 后安装 tarball),再配合 `npm run dev:client`(esbuild watch)与热替换 overlay 一起使用:浏览器 bundle 变化会触发 HMR 重新拉取 `/plugins/dsh-zotero/client.js`。
|
|
126
|
+
构建产物分两部分:`lib/` 是 Node 侧代码,`lib/client.js` 是浏览器侧(settings 卡片 + Zotero tab)。本地开发推荐用 `dev-lib.cordis.yml` overlay 实现完整插件流程,详见 [开发指南](docs/development.md)。
|
|
218
127
|
|
|
219
128
|
## 许可证
|
|
220
129
|
|
|
221
|
-
|
|
130
|
+
[MIT](./LICENSE) — 自由使用、修改和分发。
|