Conversation
A directory library is continuously written to <root>/<root-name>.bib (same debounce as the sidecar write-back), so plain BibTeX consumers can read and edit the library as one file. External edits of the mirror - live or while JabRef was closed - are three-way merged into the library with the git-sync semantic merge: base is the mirror as last written (kept under .jabref/mirror-base.bib), auto-mergeable changes apply as local changes so the regular write-back persists them into the sidecars, conflicts go through the git conflict resolution dialog, and a cancelled resolution keeps the library's state. A pre-existing .bib without a recorded base is adopted against an empty base, which can only add entries or conflict, never delete. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDcHNMt9fPWnpYaHheFvry
This was referenced Jul 19, 2026
Member
Author
|
This also contributes to foambubble/foam#241 |
Resync layer 7 of the stack (no conflicts; the git-sync merge API this layer uses still compiles against current upstream). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDcHNMt9fPWnpYaHheFvry
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vr3E1Gg5DRU4LQDDVnhPys
…the mirror The mirror is serialized on the UI thread and written on the sync thread (no concurrent walk of the live model), tracked like any other pending file so failed writes are reported, and the UI thread no longer contends for the synchronizer's monitor on every change. The mirror carries no machine-specific file directory: a directory library resolves links against its root. The mirror uses the library's save order. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vr3E1Gg5DRU4LQDDVnhPys
Fixes the CI format check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDcHNMt9fPWnpYaHheFvry
Resolve the OpenDirectoryLibraryAction import overlap; no logic change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DDcHNMt9fPWnpYaHheFvry
Upstream added a 0071 ADR after this stack claimed the number, so the MADR duplicate-ID check failed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This was referenced Sep 7, 2026
# Conflicts: # jablib/src/main/java/org/jabref/logic/directorylibrary/DirectoryLibraryScanner.java
31 tasks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related issues and pull requests
Phase 6 of the "directory as library" plan (
PLAN.md), stacked on #741 (base branchdirectory-pattern-renames). No issue is closed by this PR.PR Description
🤖 A directory library is now continuously mirrored into a single
.bibfile in its root, so collaborators and plain BibTeX tools can read and edit the whole library as one file. External edits to that mirror — while JabRef is open, or found offline at open time — are merged back into the library, and genuine conflicts open JabRef's existing conflict-resolution dialog where cancelling keeps the library's version. Adopting a pre-existing.bibonly ever adds entries, never deletes.jabref-contrib-policy:4.2:reviewed:okAnalogies
Like honey poured into a jar from many combs, the mirror gathers every sidecar into one sweet, portable vessel — and what is stirred into the jar finds its way back to the combs. Like a chocolate bar's imprint, the
.bibshows the same squares as the mold it was cast from; snap off or add a square and the mold is recut to match. And like the moon, the mirror shines with no light of its own — yet its pull moves the tides of the library beneath it.Steps to test
.yml/.mdsidecars and PDFs.<folder-name>.bibappears in the folder immediately, containing every entry (plus a.jabref/mirror-base.bibsnapshot)..bibin a text editor while JabRef is open — e.g. change a title: within ~2 s the entry updates in the main table and the sidecar is rewritten (and pattern-renamed, if the pattern covers the title). Screenshot after externally editing a title and externally appending a new@Articleto the mirror — both landed in the open library, the added entry got its own Markdown sidecar on disk:.bibexternally (orgit pulla collaborator's change), reopen: the offline change is merged in at open time..bibto different values: the git conflict resolution dialog opens; cancelling keeps JabRef's version.AI usage
Claude Code (model claude-fable-5).
AI CHECKLIST.md walkthrough
== null/!= nullchecks — JSpecify annotations used instead (singlegetFileName() == nullguard follows the file's existing precedent for JDK-nullable returns).Objects.requireNonNull(...)— nullability expressed via JSpecify annotations.@NullMarked— no new classes; the extendedDirectoryLibrarySynchronizeralready is.Optionalconsumed withifPresent/map/orElseGet— noisPresent()+get()blocks.StringUtil.isBlank(...)used instead ofs == null || s.isBlank()— no blank checks added.catch (Exception e)— onlyIOExceptionis caught.throw new RuntimeException(...)/IllegalStateException(...).BibEntryobjects built with withers — none built in production code.List.of(), records, text blocks in tests).new Thread().///) with Markdown syntax ([SemanticMergeAnalyzer], backticks).!/ no:labels — no new labels.org.jabref.logichave added tests — six newDirectoryLibrarySynchronizerTestcases (mirror creation, live edit, addition, deletion, cancelled conflict, adoption).assertEquals, plain JUnit, no@DisplayName, no caught exceptions,@TempDir../gradlew :jablib:testfor the touched packages + fulldirectorylibrarysuite green locally (fullcheckleft to CI)../gradlew checkstyleMain checkstyleTestgreen for touched modules../gradlew modernizergreen../gradlew :rewriteRunapplied (no diff)../gradlew javadocgreen.npx markdownlint-cli2green on the changed Markdown files.Checklist
@Articleappeared in the table and materialized its Markdown sidecar)CHANGELOG.mddescribing the change from the user's point of view (if the change is visible to the user)🤖 Generated with Claude Code