Skip to main content

ZotFlow 1.5.0

This release is built around a broad cleanup of ZotFlow's backlog under the official Obsidian ESLint rules. Most of the work is internal, but resolving the warnings also touched sync, readers, embedded editors, settings, workers and file handling, and surfaced the behavior changes documented below.

Updating is safe. No migration or settings reset is required; the fixes take effect the next time the affected operation runs.

Obsidian 1.13.4 is required

ZotFlow 1.5.0 raises its minimum supported Obsidian version from 1.11.4 to 1.13.4. Obsidian will not load this release on older app versions; update the app before installing ZotFlow 1.5.0.

A broad Obsidian ESLint cleanup

This update eliminates a large number of Obsidian ESLint warnings and replaces the old partial lint ratchet with a repository-wide lint check. In the process, it tightens unsafe boundaries, makes asynchronous failures explicit, uses Obsidian's mobile and pop-out-safe APIs where appropriate, and removes legacy hand-maintained Obsidian declarations in favor of maintained typings.

The sections below list the changes that can affect behavior. Pure typing, formatting and lint-configuration changes are intentionally omitted.

Please watch for regressions

The important behavior changes have focused regression tests, and the complete test suite plus the production plugin build pass. Tests still cannot reproduce every vault, platform, pop-out window, PDF, WebDAV server or Obsidian internal state. Please keep an eye out for unexpected behavior after updating and include the Activity Center logs when reporting a problem.

Highlights

  • The Obsidian lint backlog is largely gone. The cleanup now covers the whole repository rather than only a list of previously clean files.
  • Desktop users can read Zotero-stored attachments directly. Stored attachments can be opened from Zotero's local storage directory without downloading another copy through Zotero Storage or WebDAV.
  • Rejected sync writes leave local data untouched. Building an upload no longer edits the stored item before Zotero accepts it.
  • External PDF annotations keep their tags and dates. Extracted annotations now reach the reader without a lossy conversion through Zotero item data.
  • Background failures are recorded. Reader loading, annotation updates, note saves and settings writes now report rejected promises to the Activity Center log instead of disappearing silently.
  • File deletion follows your Obsidian preference. ZotFlow no longer forces generated files into the system trash when your vault is configured differently.

Safer sync failures

When ZotFlow prepared an item for upload, it shallow-copied the item envelope but kept sharing its nested data object with the stored database row. Stamping the outgoing version and modification time therefore edited the local item before Zotero had accepted anything.

A successful upload hid the problem because the server response replaced the row. A rejected upload or conflict did not: the failed attempt could leave the stored modification time changed and remove the annotationIsExternal flag. Upload payloads now copy the nested data before modifying it, so failed and conflicting writes preserve the original local state.

PDF and annotation reliability

  • External annotation tags are preserved. Tags no longer arrive under an intermediate field name that the reader does not understand.
  • External annotation dates are preserved. The PDF modification timestamp is retained, and is also used as the creation timestamp when the PDF does not provide one.
  • Valid empty PDF-worker results are accepted. A successful response that contains 0, false or another empty value is no longer mistaken for a worker error.
  • Malformed PDF-worker messages fail explicitly. Invalid CMap, font and rendered-annotation requests now produce controlled errors rather than failing later with an unrelated exception.

Read attachments directly from Zotero storage

Desktop users who run Zotero and Obsidian on the same computer can now have ZotFlow read stored attachments directly from Zotero's local storage directory. Enable Use Zotero Storage Directory under General → Source Notes → Library Source Note, then enter the complete absolute path to the storage directory.

This mode does not require Zotero File Syncing. ZotFlow still requires Zotero Data Sync for item and attachment metadata, but users without a cross-device attachment workflow can keep files local and avoid setting up Zotero Storage or WebDAV solely for ZotFlow.

This applies to Zotero-managed imported_file and imported_url attachments. ZotFlow reads the file from disk each time, before checking its attachment cache or configured sync service, and does not create a second cached copy. Linked files continue to use their own absolute path or Linked Attachment Base Directory. Mobile devices ignore this desktop-only option and continue through the configured Zotero Storage or WebDAV path.

If Zotero has not downloaded an attachment locally, direct reading fails with a clear message instead of silently downloading it. Download the file in Zotero, correct the configured path, or disable the option to use the normal sync-service path.

The original implementation of this feature was contributed by David Crandall (@Triquetra) in PR #102, based on Feature Request #101. Thank you, David, for contributing this feature.

Reliability and compatibility

  • Reader loading, rendering, navigation, annotation saves/deletes and live refreshes now log asynchronous failures with the operation that failed.
  • Debounced note saves and refreshes, editable-region syncing, reader reconnection, view-state persistence and Activity Center refreshes now use Obsidian's window-safe timer pattern for better pop-out compatibility.
  • Reader iframes and other UI elements are created from the correct owner document where required. Android also loads the inlined reader document through that document's window.
  • Linked external files remain desktop-only, but attempting to use one on mobile now fails with a clear unsupported-operation error instead of trying to call unavailable Node.js APIs.
  • Malformed zotero-key or zotflow-local-attachment frontmatter values are ignored safely instead of being indexed or passed into link resolution.

Native, searchable settings

ZotFlow's settings now use Obsidian 1.13's declarative settings API. The previous horizontal tab bar has been replaced by native pages for General, Sync, WebDAV, Cache, Citation and CSL Render. Every setting can now be found through Obsidian's global settings search.

No settings migration or reset is required. ZotFlow continues to use its existing data structure for normal settings, reader state and custom themes, while API keys and WebDAV credentials remain in Obsidian's SecretStorage.

Dynamic pages such as Sync, WebDAV, Cache and CSL Render now create their UI immediately and populate worker-backed data in the background. This avoids settings-page stalls while preserving verification-before-save behavior for credentials.

Interface fixes

  • Annotation comment editors work across themes. With Minimal Theme active, clicking anywhere in the comment editor now focuses it, rather than only the area around the “Add comment” placeholder.
  • Citation template examples match the real Liquid context. Examples now use root-level notePath and annotations, keep Zotero metadata under item, and fall back from item.citationKey to item.key.
  • Citation template editors have more room. The template text areas are wider on desktop while remaining responsive in narrower settings windows.
  • Cache limits handle unlimited mode correctly. A value of 0 remains visible as unlimited, while empty or non-integer values are rejected.
  • ZotFlow callouts follow Obsidian 1.13's color format. Custom callout colors now use valid CSS colors and render correctly after the app update.
  • Clipboard success means success. Activity Center only shows “copied” after the clipboard write completes; failures are recorded in the log.
  • Image extraction starts in the correct order. “Extract annotation images” now waits for the source note to be created or updated before it starts the extraction task, avoiding a race between the two operations.
  • The command palette label is shorter. “Open ZotFlow Activity Center” is now “Open Activity Center”, since Obsidian already displays the plugin name beside the command.
  • Insert Citation is unbound by default. The previous Alt+C default has been removed to avoid conflicts with personal or Obsidian hotkeys. Assign a shortcut from Settings → Hotkeys if desired.

Smaller fixes

  • Generated source-note paths now strip the DEL character (U+007F) along with the other control characters that are invalid or unsafe in filenames.
  • Errors raised while loading readers, verifying Zotero/WebDAV settings or handling ZotFlow links now retain useful messages even when the rejected value is not a normal JavaScript Error object.