dsh-zotero
AGENTS.md69 starsChanged 8 days agoMITView on GitHub
dsh-zotero is a DeepSeek Harness plugin: agents search, read, cite, and (when enabled and approved) write a local Zotero library through the loopback Local API (127.0.0.1:23119/api). It ships three Cordis bundle components: core, dsh-zotero/library (enabled), dsh-zotero/scholarly (disabled). Read docs/product-model.md before naming a component, surface, or scope. Keep docs/x.md and docs/x.en.md in lockstep. Tool-call examples in README*.md and the docs listed in tests/host/doc-examples.spec.ts are validated against the tools' parameter schemas. Interactive launches (full plugin vs host-only HMR) and the opt-in write…
- Installs packages
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
The file
We split this AGENTS.md into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 27
Test lanes, fixtures, verification levels, guards: tests/README.md: required before adding, moving, or refactoring tests or helpers.
- Very specific: line 30
Keep docs/x.md and docs/x.en.md in lockstep.
- Very specific: line 67
Never commit dev.cordis.yml or dev-lib.cordis.yml.
- Distinctive: line 75
No PR workflow runs the suite.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
dsh-zotero is a DeepSeek Harness plugin: agents search, read, cite, and (when enabled and approved) write a local Zotero library through the loopback Local API (127.0.0.1:23119/api). It ships three Cordis bundle components: core, dsh-zotero/library (enabled), dsh-zotero/scholarly (disabled). Read docs/product-model.md before naming a component, surface, or scope.
Repository map
| Path | Ownership |
src/ | Host runtime: ZoteroService (ctx.zotero), HTTP transport, provider |
src/local/ | Local API domain pipelines behind the provider: search, browse, retrieve, export, changes, write |
src/library/ | dsh-zotero/library component: ctx.zoteroLibrary panel endpoints and config |
src/scholarly/ | dsh-zotero/scholarly component: external search, fusion, fulltext, citations (7 tools) |
src/tools/ | The 23 host tools: 8 read + 15 write (write tools disabled by default) |
src/client/ | Browser half bundled into lib/client.js: settings, 文献轨迹, 文献面板, tool cards |
tests/ | Seven declared lanes by ownership and verification level; rules in tests/README.md |
docs/ | Product and technical docs, maintained as zh/en pairs |
scripts/ | Build, pack verification, harness pinning, test lint, smoke probes |
lib/ | Generated output from tsc and esbuild; never edited |
Sources of truth
- Product model, vocabulary, component boundaries:
docs/product-model.md. - Architecture, data flow, service layers:
docs/architecture.md: read before changing services, jobs, the provider, or client surfaces. - Tool contracts, schemas, errors:
docs/tools.md: read before changing any tool. - Configuration schemas and defaults:
docs/configuration.md. - Build, launch, debug, release:
docs/development.md. - Test lanes, fixtures, verification levels, guards: tests/README.md: required before adding, moving, or refactoring tests or helpers.
- Upstream harness contracts: this repo is normally developed as a sibling checkout of
../deepseek-harness; its docs and types outrank this file.
Keep docs/x.md and docs/x.en.md in lockstep. Tool-call examples in README*.md and the docs listed in tests/host/doc-examples.spec.ts are validated against the tools' parameter schemas.
Commands
npm install # also builds lib/ through prepare
npx vitest run <spec> # focused spec while iterating
npm run typecheck # harness pin/lock checks + node, test, and client tsc
npm run build:client # browser bundle only; required after src/client changes
npm test # test-lint guards + full vitest suite
npm run test:integration # live read spec against Zotero on 127.0.0.1:23119
npm run format # prettier --write; verify with format:check
npm run harness:check # pin, lockfile, and upstream artifact freshness
npm run style:check # client stylesheet guards against the token snapshot
npm run tokens:write # refresh the token snapshot after a harness upgrade
npm run deps:check # direct dependencies behind the registry; harness-owned ones excluded
npm run release:check # full gate: format, strict harness, lint, typecheck, coverage, build, packInteractive launches (full plugin vs host-only HMR) and the opt-in write probe (ZOTERO_WRITE_PROBE=1) are documented in docs/development.md. Run npm run link:local-harness when the sibling harness is ahead of the registry.
Invariants
- Harness pin: every
@deepseek-ai/dsh-*independencies,devDependencies, andoverridesis an exact version;peerDependenciesandengines.dshuse>=. Never hand-edit versions: runnpm run harness:pin -- <ver>, thennpm install --package-lock-only. Vendoredcordis,cosmokit,schemastery, andcordis-plugin-*floors must match the sibling'svendor/<pkg>/package.json. The browser bundle's third-party runtime dependencies mirror the sibling'spackages/client/*declarations and move with the harness, never on their own;npm run deps:checkexcludes them. - Component authorization: mounting
dsh-zotero/scholarlyauthorizes external scholarly retrieval, its 7 tools, and its prompt section. User-initiated URL PDF reading has separatelibrary.allowUrlPdfReadauthorization and grants no scholarly tools or prompt. The core is request-driven: no external calls, background pollers, or load-time network I/O. - Write seam: every write targets the personal library (
zotero://user/0/) and passes throughctx.zotero: capability gate →ctx.approval.request→ plan-review card. No bypass; a stalewriteConfirm: falsecannot opt out. Writes never retry:committed-unverifiedis reconciled, not retried. Shell commands that write to the Local API are intercepted bysrc/shell-write-detector.ts. - Client graph: browser code may value-import only
src/client/**and the pure modules allowlisted inscripts/client-graph-authority.mjs; never@deepseek-ai/schemastery,src/config.ts,src/status-codec.ts, orsrc/typert.ts. Keepzodexternal: the build refuses an inlined copy.src/client/index.tsmustawait ctx.remote.$mountbefore injecting onremote.zotero. - Zotero wire:
src/search-text.tsmust keep mirroring Zotero'snormalizeForSearch. A bare/items/{key}/childrennever returns annotations; request?itemType=annotation. Server-paged listings require a validTotal-Resultsheader, and collection and saved-search pages additionally require a validLast-Modified-Version. - 文献轨迹: a read-only ledger projected from
ChatSnapshot; it records read calls and exports, never writes or external results. - 文献面板: reaches the library only through
ctx.zoteroLibrary/ctx.remote.zotero(browse,collectionPath,search,item,childPage,export,write,readUrlPdf,releaseUrlPdf). The web UI never dispatches model tools;exportis read-only and shares the core export domain. - Client styling: feature CSS consumes the host design system and defines none of it: no
--dsw-*declaration, no literal colour outside amask-image, no literal size outside the 16px@media (pointer: coarse)focus-zoom guard, and the reader's--dsh-content-font-*axis on every body-text surface. State borders are 1px, every full-round radius pairscorner-shape: round, and every transition is reduced underprefers-reduced-motion: reduce. Every control is an@deepseek-ai/dsh-client-ui-primitivesButton; icon-only controls use the localIconButtonadapter, which composesButton. AclassNamemay carry layout only, never geometry or colour; text-link actions use the singlesrc/client/components/link.module.css.npm run style:check(spec:tests/unit/style-guard.spec.ts) enforces it against the token snapshot intests/fixtures/style-tokens.json; a host upgrade meansnpm run tokens:write. - Teardown: disposing the plugin does not abort in-flight foreground requests; they settle on provider deadlines. The plugin's own background jobs are the exception: teardown kills them (
ZoteroJobRunner.killAll), aborting their in-flight work by design.
Development rules
- Tests: one behaviour per spec; never
.only,.skip, or.todo(use.runIf); synchronize on owned promises (deferred()), never sleeps; build fixtures withtests/helpers/server/objects.ts.tests/README.mdowns the full rules and ratchets. - Commits:
<type>(<scope>): <emoji> <subject>: scope optional, lowercase type, imperative subject; body after a blank line, as bullet points explaining what and why. - Never commit
dev.cordis.ymlordev-lib.cordis.yml; both carry absolute paths. Edit the.exampletemplates.
Validation
- Iterating: focused spec +
npm run typecheck; addnpm run build:clientforsrc/client/**. - Behaviour changes:
npm test. - Cross-cutting, test-infrastructure, or release-bound:
npm run release:check. - Docs-only:
npm run format:checkandnpm run lint:test. - No PR workflow runs the suite; treat local validation as the gate. Report live checks you did not run.
Safety
- Loopback only:
resolveConfigrejects a non-loopbackbaseUrl; redirects are refused. External hosts are governed by the scholarly allowlist (src/scholarly/transport/hosts.ts); PDF exceptions are explicit user reading underlibrary.allowUrlPdfReadand the open-access PDF fulltext arm (allowPublicPdf), which may contact any public HTTP(S) host under the two-gate public-address check (lexical gate inallowlist.ts, connect-time public-DNS resolution and pinning innetwork.ts, ports 80/443 only, per-hop redirect re-validation). - Credentials: the Zotero write grant lives in the harness credentials seam (
dsh-credentials), never in plugin config. Never log, commit, or expose it. Scholarly API keys are credential references only:src/scholarly/credentials.tsresolves them throughctx.credentialsper call, and a configured reference that does not resolve fails the call rather than degrading to anonymous access. - Generated output:
lib/is produced bytscandesbuild; rebuild instead of editing.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

