Releases: Agents365-ai/zotero-cli-ai
Release list
zot-cli-bridge (plugin updates)
Rolling release for the zot-cli-bridge Zotero plugin's update channel.
Assets:
update.json— the update manifest the plugin'supdate_urlpoints at (source:extension/zot-cli-bridge/update.json)zot-cli-bridge.xpi— current build (v0.4.1, Zotero 7–10)
Manual install: Zotero → Tools → Plugins → ⚙ → Install Plugin From File…
v0.4.1
Embedding configuration cleanup. The provider-specific Aliyun key
(aliyun_api_key / ZOT_EMBEDDING_ALIYUN_KEY) and the implicit
provider="auto" mode were leaking the multi-provider routing
implementation into the user-facing config without a symmetrical
counterpart for Jina. Single-provider, single-key surface is cleaner.
Changed
[embedding] providerdefault is now"jina"(was"auto"). Set
provider = "aliyun"(orZOT_EMBEDDING_PROVIDER=aliyun) to use
Aliyun DashScope.
Removed (Breaking, very rare)
[embedding] aliyun_api_keyconfig key — use the unified
[embedding] api_keyinstead.ZOT_EMBEDDING_ALIYUN_KEYenv var — useZOT_EMBEDDING_KEYinstead.provider = "auto"mode — pick a provider explicitly.
If you upgraded to 0.4.0 within the past hour and were already using
the Aliyun-specific key, rename it to api_key /
ZOT_EMBEDDING_KEY and set provider = "aliyun".
v0.4.0
PDF extraction overhaul, envelope routing for the rest of the --json surface,
typed exit codes wired up across all command error paths, and a CI repair pass.
schema_version bumps to 1.1.0.
Added
- MinerU PDF extractor alongside the existing pymupdf-based extractor, with
a newBasePdfExtractorabstract class and automatic fallback when MinerU
fails (zot pdf KEY --extractor mineru). Configure via[pdf] extractor,
[pdf] mineru_token, orMINERU_TOKEN/ZOT_PDF_EXTRACTORenv vars. zot pdf --outline— list every heading in the document as a numbered
outline so agents can navigate without dumping the full text.zot pdf --section N— extract just the content under the N-th heading
from--outline. Useful for "show me the methods section" workflows.zot workspace index --extractor— choose the PDF extractor used during
RAG indexing.- Embedding provider router with first-class support for Aliyun
(DashScope, OpenAI-compatible) and Jina endpoints. Routes via the new
[embedding] provider,[embedding] aliyun_api_keyconfig keys plus
ZOT_EMBEDDING_PROVIDER/ZOT_EMBEDDING_ALIYUN_KEYenv vars. - Attachment resolver that handles
storage:paths,file://URLs,
Zotero'sattachments:paths, Windows drive letters, and base-attachment
prefs. PDFs in non-default storage directories now resolve correctly. progress_callbackplumbing through the PDF extraction path so MinerU
batch operations and per-PDF extraction surface progress to the caller.
Changed
- Envelope routing extended to the remaining
--jsoncommands:
zot pdf(incl.--outline/--section),zot workspace list,
zot workspace query, andzot config cache listnow emit the standard
{ok, data, meta}envelope.workspace querydatabecomes
{mode, results}rather than the bare results list. schema_version1.0.0 → 1.1.0 to reflect the envelope-coverage extension
and the typed-exit-code parity.docs/agent-interface.mdupdated.- Typed exit codes wired across all command error paths. Previously many
error paths calledprint_error(...); return, printing the error message
but silently exiting 0. They now useemit_error(...)with the appropriate
typed code:not_found(4): item / PDF / workspace / collection / profile / index /
section missing — affectscite,export,summarize,open,pdf,
workspace delete/add/remove/show/export/import/search/index/query,
config profile_set.validation_error(3): bad page range inpdf, missing required source
flag inworkspace import, invalid workspace name.auth_missing(2): alltag/trash restore/collection
write commands when API credentials aren't configured.conflict(6):workspace newwhen the workspace already exists,
andzot duplicatesnow exits 6 when duplicates are found so
agents can branch onif zot duplicates …; then …; else act_on_dups; fi.runtime_error(1): caughtPdfExtractionErrorinpdfand
ZoteroWriteErrorincollection move/delete/rename.
zot relate KEYwith no related items is now a normal exit-0 outcome
(matchingzot searchon no matches) rather than an error message.config cache listrobustness: graceful fallback when the cache DB is
unreachable; closes the connection in afinallyblock.
Fixed
- 20 pre-existing test failures on
mainrepaired (some were envelope-shape
drift between tests and production; the rest were genuine exit-code
regressions covered by the migration above). Theci.ymlpytest run goes
green again. tests/test_extracts_textno longer breaks on hosts without
~/.config/zot/config.toml. The previous over-broadPath.existsmock
also patchedload_pdf_config's file-existence check; tightened to a
targetedload_pdf_configmock.
Breaking
- Tools / agents parsing
--jsonoutput fromzot pdf,zot workspace list,zot workspace query, orzot config cache listneed to unwrap
the standard envelope (result["data"]). Other commands were already
enveloped; this brings the rest of the surface into line. - Error paths that previously exited 0 with a printed message now exit
with their typed code (1, 2, 3, 4, or 6). Scripts that ran
zot cite NONEXIST && echo okand similar will now correctly fail. zot duplicatesexits 6 (CONFLICT) when duplicates are detected.
Scripts that ignored the exit code or usedif zot duplicates; then
will need to invert the branch.
v0.3.0 — Agent-native CLI interface
Agent-native CLI interface. zot now serves humans, AI agents (Claude Code,
Codex), and orchestrators from a single surface. See docs/agent-interface.md
for the full contract.
Added
- Stable JSON envelope for every command:
{"ok": true, "data": ..., "meta": {...}}on success,{"ok": false, "error": {"code", "message", "retryable"}, "meta": {...}}on failure,{"ok": "partial", "data": {"succeeded", "failed"}}for batch operations. - TTY auto-detection:
--jsonis now implicit when stdout is not a TTY. Agents pipingzotoutput always get parseable JSON without remembering a flag. Override withZOT_FORMAT=json|table|text. - Typed exit codes: 0 success, 1 runtime error, 2 auth error, 3 validation error, 4 not-found, 5 network error, 6 conflict. Orchestrators can route failures deterministically.
zot schema [command...]— machine-readable introspection for the full CLI tree. Each entry carriesname,params(typed),safety_tier,since,deprecated, and nestedsubcommands. Agents can discover every command without a README.- Safety tiers in
--help: top-level help groups commands into Read / Write (MUTATES LIBRARY) / Destructive sections. Destructive command help carries a "MUTATES LIBRARY" warning. --dry-runon all mutating commands:add,update,note --add,attach,delete,trash restore. Preview shape:{"ok": true, "dry_run": true, "data": {"would": ...}}.--idempotency-keyonadd,update,note --add,attach,delete. SQLite-backed cache at$ZOT_CACHE_DIR/idempotency.db(default~/.cache/zotero-cli-cc) with 24h TTL. Retried calls carrying the same key return the original envelope and never duplicate the upstream mutation.metaslot on every envelope:request_id(uuid),latency_ms,schema_version,cli_version. Mutating commands also setsync_required: true.nexthints in success envelopes:add,update,delete,note --add,attachsuggest plausible follow-up commands so the agent saves a planning turn.retryablefield on every error: network / 5xx / rate-limit →retryable: true; not-found / validation / 4xx →retryable: false.ZoteroWriteErrorcarriescode,retryable,retry_after_seconds.--streammode onsearch,list,recent— emits NDJSON (one item per line) plus a summary line. Agents can process long result sets incrementally.- Structured stderr progress events for long-running commands (
add --from-file,summarize-all): NDJSON{event, phase, done, total, elapsed_ms, request_id}so agents can detect liveness without blocking on the final stdout envelope. - Confirmation-required guard on destructive commands:
zot delete K1with non-interactive stdin and no--yes/--dry-runreturns a structuredconfirmation_requirederror instead of blocking. - New
exit_codes.py,core/idempotency.pymodules. - 43 new tests across
test_agent_interface.py,test_agent_p1.py,test_agent_p2.py.
Changed
format_error/format_items/format_item_detail/format_collections/format_notes/format_duplicatesnow wrap JSON output in the envelope. Callers that parsed raw arrays must unwrap viaenv["data"].- Human error messages moved from stdout to stderr via the new
print_errorhelper. ErrorInfodataclass gainscodeandretryablefields.- Top-level CLI group uses a custom
TieredGrouphelp renderer.
Breaking
- JSON output contract: callers parsing bare arrays or dicts must now read from
env["data"]. Error responses now nest underenv["error"]withcode/message/retryablefields instead of a flat{"error": "..."}. - Exit codes: previously
1for all failures; now distinct codes per failure class. Scripts checking for any non-zero exit remain valid.
v0.2.2
- Add Python version classifiers for PyPI badge
- Fix ruff lint and format issues
- Fix mypy type errors in rag and workspace modules
v0.2.1
Changes since v0.2.0
New Commands
workspace export— export as markdown/json/bibtex for AI consumptionworkspace import— bulk import from collection, tag, or searchworkspace search— metadata search within a workspace
Performance
- 178x faster SQLite reads with
immutable=1(eliminates WAL lock contention with running Zotero desktop) - PDF markdown cache for workspace index rebuilds
Fixes
- Config directory now consistently
~/.config/zot/on all platforms - Fix Jina embedding API calls (User-Agent header required)
- Remove
platformdirsdependency
Docs
- README workspace section with design rationale
- Chinese README synced
- SKILL.md v0.5.0
v0.2.0 — Workspace & RAG
What's New
Workspace Management
Organize Zotero items by research topic with local workspaces — no Zotero API needed.
zot workspace new <name>— create workspace with optional descriptionzot workspace add <name> KEY...— add items (validates against Zotero DB)zot workspace remove <name> KEY...— remove itemszot workspace show <name>— display items with full metadatazot workspace list— list all workspaceszot workspace delete <name>— delete workspace
Workspace RAG (Retrieval-Augmented Search)
Built-in lightweight RAG over workspace papers — zero new dependencies.
zot workspace index <name>— build BM25 index from metadata + PDF fulltextzot workspace query "question" --workspace <name>— natural language search- BM25 keyword search always available (pure Python, no new deps)
- Optional semantic search via external embedding API (Jina AI default, 10M free tokens)
- Hybrid mode fuses BM25 + semantic via reciprocal rank fusion
- PDF converted to Markdown via pymupdf4llm (if installed) for better chunking
Configuration
# Optional: enable semantic search
export ZOT_EMBEDDING_URL="https://api.jina.ai/v1/embeddings"
export ZOT_EMBEDDING_KEY="your-key"Full Changelog
- feat: workspace command group (new, delete, add, remove, list, show)
- feat: RAG engine with BM25, chunking, embedding client, hybrid fusion
- feat: EmbeddingConfig with Jina defaults and env overrides
- docs: SKILL.md v0.5.0 with workspace docs, removed rak section
v0.1.11
What's Changed
Improved --collection help text (#8)
- Clarified that
--collectionfilters by Zotero collection/folder name, not by keyword - Added hint:
Use 'zot collection list' to see available names - Updated examples in
search --helpandlist --helpto show the two-step workflow:zot collection list— see your collectionszot search "query" --collection "Name"— search within a collection
Full Changelog: v0.1.10...v0.1.11
v0.1.10
What's Changed
Bug Fixes (#7, #8)
--limitnow works after subcommand name:zot list --limit 10andzot search "query" --limit 5now work as expected. Previously--limithad to be placed before the subcommand.--collectionshows helpful error when not found: Instead of silently returning empty results, displays all available collection names.--collectionhelp text clarified: Now says "Zotero collection (folder) name" to avoid confusion with keyword search.- Collection lookup filters by library ID: Fixes potential cross-library mismatch with group libraries.
CI Fixes
- Fixed ruff import sort order in
writer.py - Fixed mypy type errors in
tag.py,note.py,pdf_extractor.py,mcp_server.py - CI pipeline now fully green (was broken since v0.1.5)
Upgrade
pip install --upgrade zotero-cli-ccv0.1.8 — Friendly API Error Messages
Bug Fixes
- fix(writer): Catch pyzotero API errors with user-friendly messages (#6)
403 Write access denied→ clear message to enable write permissions on API key400 Invalid user ID→ guidance to use numeric userID instead of username- All other pyzotero errors now show clean messages instead of raw tracebacks
- Applied to all 14 writer methods (add, delete, tags, collections, etc.)