Skip to content

Make directory libraries reachable through the REST API - #745

Open
koppor wants to merge 272 commits into
directory-convertfrom
directory-rest-api
Open

Make directory libraries reachable through the REST API#745
koppor wants to merge 272 commits into
directory-convertfrom
directory-rest-api

Conversation

@koppor

@koppor koppor commented Jul 22, 2026

Copy link
Copy Markdown
Member

Related issues and pull requests

Phase 8 of the "directory as library" plan (PLAN.md), stacked on #744 (base branch directory-convert). No issue is closed by this PR.

PR Description

🤖 jabsrv (JabRef's REST API) identified every open library by its .bib path. A directory library has no .bib path — only a root directory — so it was invisible to the entire HTTP API: missing from GET /libraries, missing from the libraries:query existence check, and un-addressable for reading (GET /libraries/{id}/entries…) or adding (POST /libraries/{id}/entries) entries.

The whole gap was one root cause in ServerUtils, whose three id helpers (openLibraryIds, getLibraryPath, getBibDatabaseContext) all keyed off getDatabasePath() and dropped/rejected empty-path contexts. They now derive a library's id from getDatabasePath().or(getDirectoryLibraryRoot()) — the same identity the GUI session store already uses — so listing, the existence-check query, entry reads, and appends all resolve a directory library by its root. The GUI-side append matcher (selectLibraryTab) gains the same fallback, so an append targets the open directory-library tab by its root; the entries then flow through the existing write-back into sidecars and the .bib mirror (imports fire EntriesEventSource.LOCAL, which write-back already handles). No new module dependency — getDirectoryLibraryRoot() is on the model's BibDatabaseContext.

Scope note: this fixes GUI mode (JabMap and the browser extension talk to the running JabRef GUI, where directory-library tabs are open databases). Standalone jabsrv-cli still serves only the .bib files given on its command line — serving a bare directory there is separate future work, and adds require the GUI regardless.

jabref-contrib-policy:4.2:reviewed​:ok

Analogies

Like honey the label finally lists, the directory library was always in the pantry but unnamed on the jar; now the index reads it out. Like a chocolate assortment where one praline had no map coordinate, every piece can now be pointed to and picked. And like the moon answering to a name in the almanac, the library was always orbiting — it just needed an entry in the tables to be found and hailed.

Steps to test

  1. Start JabRef with the HTTP server enabled and open a folder as library (so a directory-library tab is open).
  2. GET http://localhost:23119/libraries — the directory library now appears in the list (id = <folder-name>-<hash>).
  3. POST http://localhost:23119/libraries:query with {"queries": ["doi = \"…\""]} — matches in the directory library are returned (the browser-extension / JabMap existence check).
  4. POST http://localhost:23119/libraries/<that-id>/entries with a BibTeX body — the entry lands in the directory library, and a Markdown sidecar plus the .bib mirror update on disk.

(No user-visible UI change, so no screenshot — the behaviour is exercised by ServerUtilsTest and the steps above.)

Live verification (running JabRef + HTTP server)

Enabled the HTTP server, opened a folder as library (demo-library), and drove the real API:

  • GET /libraries → the directory library now appears: "demo-library-275b20a6" (a .bib-only listing before this PR).
  • POST /libraries:query {"queries":["title = \"ZygOS: Achieving Low Tail Latency\""]}{"libraryId":"demo-library-275b20a6","entryId":"zygos"} (existence check hits the directory library); a non-matching query returns [].
  • GET /libraries/demo-library-275b20a6/entries/sidecar2026 → entry preview resolves.
  • POST /libraries/demo-library-275b20a6/entries with a BibTeX body → 204; the entry lands in the directory library, and write-back creates the Markdown sidecar Rest2026 - Added Over the REST API.md (filename pattern applied) and updates the .bib mirror. A follow-up libraries:query then finds the freshly added Rest2026 — the full loop closes.

Directory-library table after adding an entry over the REST API

Known cosmetic follow-up (not fixed here): the interactive import dialog's "Library to import into" selector shows untitled for a directory library (it derives the name from the .bib path); the import still targets the correct directory-library context.

AI usage

Claude Code (model claude-opus-4-8).

AI CHECKLIST.md walkthrough
  • No == null / != null checks.
  • No Objects.requireNonNull(...).
  • [/] New classes annotated with @NullMarked — no new production classes (methods added to existing ServerUtils).
  • Optional consumed with map / or / flatMap / orElse(false) — no isPresent() + get() (in fact this PR removes a getDatabasePath().get() block).
  • [/] StringUtil.isBlank(...) — no blank checks added.
  • No catch (Exception e).
  • No throw new RuntimeException(...).
  • [/] Logged exceptions last — no new logging.
  • [/] Withers for new BibEntry — none built.
  • Modern Java (Optional.or, streams).
  • [/] Precompiled regex — none.
  • [/] No new Thread() — none.
  • No commented-out code, no trivial comments, no AI-disclosure comments.
  • Markdown Javadoc (///) with Markdown syntax.
  • [/] Localized user-facing text — none added (id strings, not shown to users).
  • Security: the existing HtmlEscapers on the 404 id message is preserved.
  • Behavior change in jabsrv covered by ServerUtilsTest (listing, path resolution, context resolution, unknown id).
  • Tests assert with assertEquals/assertSame, plain JUnit, no @DisplayName, no caught exceptions, @TempDir.
  • ./gradlew :jabsrv:test green locally (full suite, no regressions); :jabsrv:compileJava + :jabgui:compileJava green.
  • ./gradlew checkstyleMain checkstyleTest green for touched modules.
  • ./gradlew modernizer green.
  • ./gradlew :rewriteRun applied (no diff).
  • ./gradlew traceRequirements green (req~directory-library.rest-api~1 covered impl + utest).
  • npx markdownlint-cli2 green on the changed Markdown.
  • [/] Docker IntelliJ formatter — not available; CI format job is the backstop.

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • I manually tested my changes in running JabRef (see "Live verification" above: enabled the HTTP server, listed/queried/read/added against an open directory library, and confirmed the sidecar + mirror were written on disk)
  • I added JUnit tests for changes (if applicable)
  • [/] I added screenshots in the PR description (if change is visible to the user) — no UI change
  • [/] I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • [/] I described the change in CHANGELOG.md — the directory-library feature is unreleased, so no user-visible change against any released version
  • I checked the user documentation — the docs PR is the pending phase-5 step covering the whole feature

🤖 Generated with Claude Code

koppor and others added 30 commits July 16, 2026 20:38
* Render AI summaries with MarkdownTextFlow instead of WebView

Replaces the Markdown -> HTML -> WebView pipeline in the AI summary
tab with the same Markdown -> JavaFX MarkdownTextFlow rendering
already used for AI chat messages, avoiding a second WebView instance
and giving consistent styling/selection behavior across both.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Use TODO placeholder for changelog PR link until PR exists

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Add PR verification screenshot for AI summary MarkdownTextFlow rendering

Temporary screenshot for the PR description; safe to remove after review.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Replace CHANGELOG TODO placeholder with the actual PR link

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Address review feedback: new ADR, plain-text copy, view cleanup

- Supersede ADR-0042 with a new ADR-0066 describing the MarkdownTextFlow
  rendering decision; mark ADR-0042 superseded via the standard MADR
  status field and note admonition, and fix its copy-pasted title
  ("Chat Message Content" -> "Summarization Content").
- MarkdownTextFlow: track whether content is plain text vs. Markdown.
  In plain-text mode, copy the selection verbatim instead of putting a
  rendered HTML flavor on the clipboard, and no longer parse the text as
  Markdown when only displaying it.
- Drop the redundant summaryContent pass-through property from the view
  model; the view now reads the summary content directly.
- Remove the committed PR screenshot from the repository.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Merge ADR-0066 into ADR-0042 for MarkdownTextFlow decision

Fold the MarkdownTextFlow summarization decision back into ADR-0042,
replacing the superseded WebView content, rename the file to match, and
update the ADR-0036 link. Fixes the MADR04 rationale format.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Add MarkdownTextFlow rendering tests and stale-update guard

Cover the Markdown-vs-plain-text rendering behavior of MarkdownTextFlow
with tests, and guard AiSummaryShowingView.updateContent against stale
async UI updates by stamping each request and reading content on the FX
thread.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* apply qodo suggestion

* Add test for MarkdownTextFlow

* fix selection bug

* checkstlye

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Siedlerchr <siedlerkiller@gmail.com>
#16274)

Bumps [com.autonomousapps:dependency-analysis-gradle-plugin](https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin) from 3.16.1 to 3.17.0.
- [Changelog](https://github.com/autonomousapps/dependency-analysis-gradle-plugin/blob/main/CHANGELOG.md)
- [Commits](autonomousapps/dependency-analysis-gradle-plugin@v3.16.1...v3.17.0)

---
updated-dependencies:
- dependency-name: com.autonomousapps:dependency-analysis-gradle-plugin
  dependency-version: 3.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.gradleup.shadow:shadow-gradle-plugin](https://github.com/GradleUp/shadow) from 9.5.1 to 9.6.0.
- [Release notes](https://github.com/GradleUp/shadow/releases)
- [Commits](GradleUp/shadow@9.5.1...9.6.0)

---
updated-dependencies:
- dependency-name: com.gradleup.shadow:shadow-gradle-plugin
  dependency-version: 9.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.gradleup.shadow:shadow-gradle-plugin](https://github.com/GradleUp/shadow) from 9.5.1 to 9.6.0.
- [Release notes](https://github.com/GradleUp/shadow/releases)
- [Commits](GradleUp/shadow@9.5.1...9.6.0)

---
updated-dependencies:
- dependency-name: com.gradleup.shadow:shadow-gradle-plugin
  dependency-version: 9.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
#16276)

Bumps [com.autonomousapps:dependency-analysis-gradle-plugin](https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin) from 3.16.1 to 3.17.0.
- [Changelog](https://github.com/autonomousapps/dependency-analysis-gradle-plugin/blob/main/CHANGELOG.md)
- [Commits](autonomousapps/dependency-analysis-gradle-plugin@v3.16.1...v3.17.0)

---
updated-dependencies:
- dependency-name: com.autonomousapps:dependency-analysis-gradle-plugin
  dependency-version: 3.17.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* add raw query support and tests AstrophysicsDataSystem

* test compares the full entry

* remove duplicate empty q parameter from search URL

Co-authored-by: Faneesh Juneja <willowstration@gmail.com>

* fix formatting

---------

Co-authored-by: Faneesh Juneja <willowstration@gmail.com>
Removed a redundant instruction about giving a GitHub star.
This is remnant of an older internal discussion.
* add raw query support to MedlineFetcher

* add tests for MedlineFetcher raw query search

* clarify esearch endpoint
* Improve mods importer and fix loc test

* add changelog entry

* add rate limiting

* add rate limiting

* cleanup

* changelog format

* openrewrite
* Show error dialog on critical startup failures

If start() throws before the main window exists, the exception was only
logged, leaving users with a silent crash and no way to tell what went
wrong short of digging through the log file. showStartupErrorDialog()
now surfaces it via a ControlsFX ExceptionDialog, skipping initOwner()
when the stage has no Scene yet (openWindow() sets it later), since
JavaFX throws a NullPointerException from initOwner() on a sceneless
owner. FallbackExceptionHandler is also installed earlier, before
initialize(), so background threads started during startup are covered
too.

Fixes #14967

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Use Markdown Javadoc links, drop dead null check, add UX requirement

Switches {@link} to the project's Markdown-link Javadoc convention,
removes a mainStage != null check that can never be false (mainStage
is assigned unconditionally as the first statement in start()'s try
block, before any exception this method handles can occur), and adds
a docs/requirements/ux.md entry for the startup-error-dialog guarantee
introduced in the previous commit, linked from the code via impl->req.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Address Qodo review: localize FallbackExceptionHandler message, fix NPE risk

Two issues from Qodo's review on #16281:
- "Uncaught exception occurred in " + thread was a hardcoded string;
  now goes through Localization.lang with a %0 placeholder.
- FallbackExceptionHandler's callback called DialogService directly,
  which can NPE via initOwner() the same way the startup-crash path
  did before being fixed — it can fire for a background-thread
  exception before initialize() creates DialogService, or before
  openWindow() gives mainStage a Scene. Unified both callers into
  showCriticalErrorDialog(), which already had the safe fallback.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…16280)

* Do not warn on DOI mismatch that differs only in the http(s) prefix

The DoiFetcher compared the fetched entry's raw DOI field string against
the bare requested DOI. That flagged a mismatch whenever the resolver
returned the DOI as a URL (https://doi.org/10.x vs 10.x), and the filter
was inverted so it warned on identical DOIs instead of differing ones.

Compare both sides as parsed DOI objects instead: DOI.equals already
normalizes away the http(s) prefix and letter case, so the warning now
fires only on a genuine DOI difference.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3wNLCcRSZh7oTcf2FUmLz

* Warn on present-but-unparsable DOI field instead of skipping silently

Comparing via flatMap(DOI::parse) collapsed "invalid DOI value" into the
same empty Optional as "no DOI field", so a present-but-unparsable DOI
was silently skipped by both the mismatch check and the missing-field
check. Split the three cases explicitly: missing field, present-but-
unparsable value, and parsed-but-different DOI each get their own warning.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3wNLCcRSZh7oTcf2FUmLz

* Add CHANGELOG entry for DOI warning fix

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3wNLCcRSZh7oTcf2FUmLz

* Shorten CHANGELOG entry for DOI warning fix

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3wNLCcRSZh7oTcf2FUmLz

* Merge DOI equality tests into one parameterized test

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X3wNLCcRSZh7oTcf2FUmLz

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* New translations jabref_en.properties (Finnish)

[ci skip]

* New translations jabref_en.properties (Italian)

[ci skip]
* added routing dispatch to StudyFetcher

* log uncaught raw query exceptions

* page loop on raw path

* case insensitive lookup

* scope exception to raw calls

* update tests

* fix formatting

* null value guard

* verify full page loop

* fix formatting

* added fetcher exceptions

* fix null guard order

* switch to optional and split into sub methods

* fix null guard on catalogOverride filter

* Update jablib/src/main/java/org/jabref/logic/crawler/StudyFetcher.java

Co-authored-by: Loay Tarek Mostafa <142718879+LoayTarek5@users.noreply.github.com>

* extract getCatalogOverride to dedicated method

---------

Co-authored-by: Loay Tarek Mostafa <142718879+LoayTarek5@users.noreply.github.com>
…s the main table (#16273)

* Edit special fields with the same icon controls as the main table

The entry editor rendered special fields (ranking, priority, read status,
printed, quality, relevance) as plain text fields. They now use the same
icon-based selection as the main table's special field columns: a star
rating for the ranking, one toggle per value for priority and read status,
and a single toggle for the one-value fields. Field labels and add-chips
show the localized special field names instead of the raw field names.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tbp5E2Kwn95yykHNzR8SJz

* Make SpecialFieldEditor nullness explicit with JSpecify

Annotate the class @NullMarked and mark the two genuinely-nullable fields
(entry, fieldValue — both unset until bindToEntry) @nullable instead of
relying on implicit nullable state. Collapse the three per-control-type
fields (only ever one initialized) into a single non-null value-applier
consumer, removing the mostly-null fields the previous switch dereferenced.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tbp5E2Kwn95yykHNzR8SJz

* Apply special field binding updates on the FX thread

BibEntry.getFieldBinding may fire from a background thread (e.g. autosave),
but the subscription mutated JavaFX controls directly. Dispatch the control
update via UiTaskExecutor.runInJavaFXThread when off the FX thread, matching
FieldEditorFX.establishBinding, and keep the updatingControls guard inside
the dispatched runnable so user-input listeners stay suppressed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tbp5E2Kwn95yykHNzR8SJz

* Localize the add-chip label with a placeholder

The add-field chip built its label by concatenating "+ " with the field
name, bypassing the localization system. Use Localization.lang("+ %0", ...)
with the corresponding JabRef_en.properties key so translators can reorder
and format the label naturally.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tbp5E2Kwn95yykHNzR8SJz

* Use runNowOrInJavaFXThread and space out field declarations

runNowOrInJavaFXThread already does the isFxApplicationThread check (running
synchronously when on the FX thread), so drop the inline check and the
Platform import. Also separate the field declarations with blank lines so the
documented and undocumented fields no longer run together.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tbp5E2Kwn95yykHNzR8SJz

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Bumps [org.graalvm.buildtools:native-gradle-plugin](https://github.com/graalvm/native-build-tools) from 1.1.4 to 1.1.5.
- [Release notes](https://github.com/graalvm/native-build-tools/releases)
- [Commits](graalvm/native-build-tools@1.1.4...1.1.5)

---
updated-dependencies:
- dependency-name: org.graalvm.buildtools:native-gradle-plugin
  dependency-version: 1.1.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [org.graalvm.buildtools:native-gradle-plugin](https://github.com/graalvm/native-build-tools) from 1.1.4 to 1.1.5.
- [Release notes](https://github.com/graalvm/native-build-tools/releases)
- [Commits](graalvm/native-build-tools@1.1.4...1.1.5)

---
updated-dependencies:
- dependency-name: org.graalvm.buildtools:native-gradle-plugin
  dependency-version: 1.1.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [dev.langchain4j:langchain4j-bom](https://github.com/langchain4j/langchain4j) from 1.17.2 to 1.18.0.
- [Release notes](https://github.com/langchain4j/langchain4j/releases)
- [Commits](langchain4j/langchain4j@1.17.2...1.18.0)

---
updated-dependencies:
- dependency-name: dev.langchain4j:langchain4j-bom
  dependency-version: 1.18.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.uber.nullaway:nullaway](https://github.com/uber/NullAway) from 0.13.7 to 0.13.8.
- [Release notes](https://github.com/uber/NullAway/releases)
- [Changelog](https://github.com/uber/NullAway/blob/master/CHANGELOG.md)
- [Commits](uber/NullAway@v0.13.7...v0.13.8)

---
updated-dependencies:
- dependency-name: com.uber.nullaway:nullaway
  dependency-version: 0.13.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Christoph <siedlerkiller@gmail.com>
* New translations jabref_en.properties (French)

[ci skip]

* New translations jabref_en.properties (Spanish)

[ci skip]

* New translations jabref_en.properties (Arabic)

[ci skip]

* New translations jabref_en.properties (Danish)

[ci skip]

* New translations jabref_en.properties (German)

[ci skip]

* New translations jabref_en.properties (Greek)

[ci skip]

* New translations jabref_en.properties (Finnish)

[ci skip]

* New translations jabref_en.properties (Italian)

[ci skip]

* New translations jabref_en.properties (Japanese)

[ci skip]

* New translations jabref_en.properties (Korean)

[ci skip]

* New translations jabref_en.properties (Dutch)

[ci skip]

* New translations jabref_en.properties (Norwegian)

[ci skip]

* New translations jabref_en.properties (Polish)

[ci skip]

* New translations jabref_en.properties (Portuguese)

[ci skip]

* New translations jabref_en.properties (Russian)

[ci skip]

* New translations jabref_en.properties (Swedish)

[ci skip]

* New translations jabref_en.properties (Turkish)

[ci skip]

* New translations jabref_en.properties (Ukrainian)

[ci skip]

* New translations jabref_en.properties (Chinese Simplified)

[ci skip]

* New translations jabref_en.properties (Chinese Traditional)

[ci skip]

* New translations jabref_en.properties (Vietnamese)

[ci skip]

* New translations jabref_en.properties (Portuguese, Brazilian)

[ci skip]

* New translations jabref_en.properties (Indonesian)

[ci skip]

* New translations jabref_en.properties (Persian)

[ci skip]

* New translations jabref_en.properties (Tagalog)

[ci skip]
* Improve large library switching

* Link large library fix changelog entry

* remove heaer

* checkstlye

* Address review feedback

- Avoid a redundant full-database rescan when number cells re-render
  while the initial group-count load is still in flight
- Log group-count update failures at warn instead of debug
- Document why group-count tasks go through schedule() (separate pool,
  keeps the worker pool free for preview rendering)
- Force a group-count reload when the display-group-count preference is
  re-enabled after a skipped recompute
- Confine PreviewViewer.update() to the FX thread so the unsynchronized
  updateSequence guard is safe when entry observables fire from
  background threads
- Drop the now-unused Collector implementation from TreeCollector and
  the now-unused GroupTreeNode.isSameGroupAs
- Cover the recursive grandchild-collision path in TreeCollectorTest
- Move the CHANGELOG entry from Fixed to Changed

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW1qh78rm2gy42vtixbmM4

* Use the mandated heading level for the new requirement entry

The OFT requirement template (docs/requirements/index.md, AGENTS.md)
specifies a "### <title>" heading; the file's older entries predate it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW1qh78rm2gy42vtixbmM4

* Clear stale group counts when a refresh is skipped while counts are off

The skipped recompute already invalidated the cache; also clear the
matched-entries set so rebinding the number cell never briefly shows the
outdated count, and cover the disable -> refresh -> re-enable sequence
with a test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NW1qh78rm2gy42vtixbmM4

* use ui task executor

---------

Co-authored-by: Oliver Kopp <kopp.dev@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* write study-lock.yml recording the effective query per catalog

* add tests for study-lock.yml

* use the first matching override, same as StudyFetcher

* solve lock file requirement issue

* nuild the lock from the catalogs that have a fetcher
…dout output (#16292)

* Focus pdf-to-bibtex skill on paper metadata and fix jabkit convert stdout output

The pdf-to-bibtex skill mixed two different tasks: getting a BibTeX entry
describing a PDF paper (pdfMerged and friends) and extracting the entries a
paper cites (pdfBibiliography). The latter is not a registered import format
("Unknown import format: pdfBibiliography"), so its table row is removed and
the skill is scoped to the paper's own metadata.

The separate doi-to-bibtex workflow step is dropped: pdfMerged already looks
up DOI/arXiv/ISBN identifiers found in the PDF and merges the fetched
metadata into the entry.

While verifying the documented commands, jabkit convert without --output
turned out to print the BibDatabase object reference instead of BibTeX;
it now uses ExportService.printDatabaseContextToStdOut like the other
subcommands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEJvTaG41iVdG5o1hEyBfS

* use any output format

* use any output format

* use any output format

* remove duplicate

* Pin usage error for unknown --output-format on stdout

Adds a regression test asserting exit code 2 and the "Unknown export
format" message when jabkit convert without --output is given an unknown
--output-format, and extends the CHANGELOG entry to cover the
--output-format handling on stdout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEJvTaG41iVdG5o1hEyBfS

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Siedlerchr <siedlerkiller@gmail.com>
…ilesIndexer (#16303)

* Fix uncaught ThreadInterruptedException in DefaultLinkedFilesIndexer.optimizeIndex() Closes #12388#

* Address review: fix trailing space, add interrupt handling to forceMergeDeletes(), use debug level logging
…6302)

* Fix excess/insufficient spacing around Keywords and Groups fields

AllFieldsTab.applyNaturalHeight() forced Keywords and Groups (both
TagsEditor-based) to a fixed weight-based row height, regardless of
how many lines their chips actually wrapped to. This left blank space
below a short chip list and could clip a long, wrapped one. Exempt
TagsEditor the same way LinkedFilesEditor already is, so the row
grows and shrinks with its actual content.

Fixes #12112

* Simplify CHANGELOG.md

* Update AllFieldsTab.java

---------

Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com>
)

Bumps [JetBrains/junie-github-action](https://github.com/jetbrains/junie-github-action) from 1 to 1.5.10.
- [Release notes](https://github.com/jetbrains/junie-github-action/releases)
- [Commits](JetBrains/junie-github-action@v1...v1.5.10)

---
updated-dependencies:
- dependency-name: JetBrains/junie-github-action
  dependency-version: 1.5.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [jablib/src/main/resources/csl-styles](https://github.com/citation-style-language/styles) from `439002f` to `3ad2f7d`.
- [Release notes](https://github.com/citation-style-language/styles/releases)
- [Commits](citation-style-language/styles@439002f...3ad2f7d)

---
updated-dependencies:
- dependency-name: jablib/src/main/resources/csl-styles
  dependency-version: 3ad2f7ddd9d13da9c7bc2dd67afd3107897ad3e1
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Document optional native JBang install in jabkit skill

Setting JBANG_USE_NATIVE=true makes the JBang installer fetch the native
launcher, which skips the bootstrap JDK download entirely. Kept optional:
native builds exist only for linux-x64, mac-aarch64 and windows-x64, and
the variable is read on every launch, not only at install time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XvNRUGfJHT9BAPWbJGCGLp

* Make the native JBang note shell-neutral

The note followed a PowerShell installer snippet but used Unix-only
wording, leaving the Windows path non-actionable despite windows-x64
being one of the supported native targets.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XvNRUGfJHT9BAPWbJGCGLp

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jabsrv identified every library by its .bib path, so directory
libraries - which have no .bib path, only a root directory - were
invisible to the whole HTTP API: absent from the library listing and
the existence-check query, and un-addressable for reading or adding
entries.

ServerUtils now derives a library's id from getDatabasePath() or, for
a directory library, its root directory (the same identity the GUI
session store uses), so listing, the batch query, entry reads, and
appends all resolve it. The GUI append matcher gains the same
fallback, so an append targets the open directory-library tab by its
root; the entries then flow through the normal write-back into
sidecars and the mirror.

Standalone-server mode still serves only .bib files (adds require the
GUI regardless).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDcHNMt9fPWnpYaHheFvry
* Generalize fetcher rate limiting

Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>

* Address rate limiter review feedback

Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>

---------

Signed-off-by: Arnab Nandy <arnab_nandy7@yahoo.com>
subhramit and others added 30 commits August 16, 2026 14:01
* Add ability to create group from selection

Signed-off-by: subhramit <subhramit.bb@live.in>

* Better docs

Signed-off-by: subhramit <subhramit.bb@live.in>

* Add PR link

Signed-off-by: subhramit <subhramit.bb@live.in>

* Openrewrite

Signed-off-by: subhramit <subhramit.bb@live.in>

* Check box by default

Signed-off-by: subhramit <subhramit.bb@live.in>

---------

Signed-off-by: subhramit <subhramit.bb@live.in>
* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})
* Close stale PRs based on the age of the stale label

actions/stale measures days-before-close against the GitHub field
updated_at, which is bumped by activity that is not the contributor's.
PRs whose updated_at keeps moving are therefore never closed. The stale
label carries a fixed timestamp, so the closing is done from that.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XubvYCwnYXvmX8ZbRoBovx

* Do not exempt "dev: no-bot-comments" from the stale process

The label usually stays on a pull request even after
"status: changes-required" was set, so exempting it took most pull
requests out of the process.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XubvYCwnYXvmX8ZbRoBovx

* Do not cap the candidate list at 100 pull requests

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XubvYCwnYXvmX8ZbRoBovx

* Re-check the required labels before closing

The candidate list is a snapshot; a label can be removed while the list
is being processed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XubvYCwnYXvmX8ZbRoBovx

* Do not close pull requests that saw activity after the stale label

Nothing removes the stale label when a pull request from a branch of
this repository is pushed to: pr-comment.yml only does that for pull
requests from forks, and a human comment never removes it. Closing by
label age alone would therefore have closed active pull requests - three
of the five current candidates.

A push or a comment by a human after the label now drops the label
again, so the marking step can start a new round.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XubvYCwnYXvmX8ZbRoBovx

* Update .github/workflows/stale.yml

Co-authored-by: Subhramit Basu <subhramit.bb@live.in>

* Count review comments and reviews as activity; guard last_commit against null

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019jLLBgzTkt7w2riFaiRN5C

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Subhramit Basu <subhramit.bb@live.in>
Follow-up to #16551: the exception message was correctly removed from
the notification popup, but it disappeared from the tab's list
placeholders as well. Restore the details there, keeping the
notification short.


Claude-Session: https://claude.ai/code/session_017pWaf5YCnQiUHdNSaPtaxh

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Bumps [cc.jilt:jilt](https://github.com/skinny85/jilt) from 1.9.1 to 1.9.2.
- [Changelog](https://github.com/skinny85/jilt/blob/master/Changelog.md)
- [Commits](skinny85/jilt@1.9.1...1.9.2)

---
updated-dependencies:
- dependency-name: cc.jilt:jilt
  dependency-version: 1.9.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…16605)

* fix equals in group tree viewmodel and add run config for jabref gui

* Update GroupTreeViewModel.java
* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})
Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com>
Bumps [com.dlsc.gemsfx:gemsfx](https://github.com/dlsc-software-consulting-gmbh/GemsFX) from 4.4.0 to 4.4.1.
- [Commits](dlsc-software-consulting-gmbh/GemsFX@v4.4.0...v4.4.1)

---
updated-dependencies:
- dependency-name: com.dlsc.gemsfx:gemsfx
  dependency-version: 4.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com>
Bumps [tools.jackson:jackson-bom](https://github.com/FasterXML/jackson-bom) from 3.2.1 to 3.2.2.
- [Commits](FasterXML/jackson-bom@jackson-bom-3.2.1...jackson-bom-3.2.2)

---
updated-dependencies:
- dependency-name: tools.jackson:jackson-bom
  dependency-version: 3.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com>
Bumps [dev.langchain4j:langchain4j-bom](https://github.com/langchain4j/langchain4j) from 1.18.1 to 1.19.0.
- [Commits](langchain4j/langchain4j@1.18.1...1.19.0)

---
updated-dependencies:
- dependency-name: dev.langchain4j:langchain4j-bom
  dependency-version: 1.19.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com>
Bumps [io.github.classgraph:classgraph](https://github.com/classgraph/classgraph) from 4.8.191 to 4.8.192.
- [Commits](classgraph/classgraph@classgraph-4.8.191...classgraph-4.8.192)

---
updated-dependencies:
- dependency-name: io.github.classgraph:classgraph
  dependency-version: 4.8.192
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com>
* Implemented fetcher for ScholarApi for List Api

* fixed the load more error in fetch page and removed overridden validKey method relying on the pre-defined method

* fixed formatting error and un-used imports

* fixed the fetchers.md

* fixed thr jabgui errors

* Implemented all requested changes

* fixed checkstyle errors

* fixed all jabgui related errors

* fixes modernizer error

* fixes checkstyle errors

* did the asked chnages

* fixed formatting error

* add deleted texts in fetchers.md

* did all asked chnages and fixed fetchers.md

* fixed fetchers.md

* did all asked changes

* Update jablib/src/test/java/org/jabref/logic/importer/fetcher/ScholarFetcherTest.java

* Remove stray carriage returns from test JSON

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011pjk3bgog1dY62UzcExWXJ

* Update fetchers.md

* Compare full expected BibEntry in test; use setField in ScholarFetcher

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011pjk3bgog1dY62UzcExWXJ

* Sort API key entries alphabetically in BuildInfo and build.properties

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011pjk3bgog1dY62UzcExWXJ

---------

Co-authored-by: Subhramit Basu <subhramit.bb@live.in>
Co-authored-by: Oliver Kopp <kopp.dev@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com>
…16598)

* Reintroduce custom entry editor tabs with two-column preferences UI

The entry editor rework (#16166) dropped user-defined tabs. Bring them
back with a preferences UI modeled on the Custom entry types tab: a
"Tabs" column (visibility checkboxes for built-in tabs, add/remove for
custom tabs, drag reordering for all) and a "Fields" column editing the
selected custom tab's ordered field list. Field names may be regular
expressions (e.g. comment-.*), which capture every matching set field of
the entry, refreshed live on field changes. A field listed on more than
one tab is marked with a warning sign.

Custom tabs are persisted under the pre-rework preference keys, so tabs
configured in older versions are picked up again without migration; the
combined tab order is stored in a new entryEditorTabOrder key.

Fixes #16594

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

* Keep duplicate-named custom tabs when applying stored tab order

Persisted data can contain custom tabs sharing a name (older versions or
hand-edited stores; the preferences UI prevents new duplicates). The
order map keyed by tab ID silently dropped all but the last such tab, so
queue tabs per ID instead and consume one per matching order entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

* Unregister entry listener when field tabs are disposed

BibEntry's event bus holds listeners strongly, so AllFieldsTab and
UserDefinedFieldsTab instances stayed registered (and retained) after
EntryEditorViewModel.disposeTabs() dropped them. Release the
subscription in dispose().

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

* Coalesce deferred refreshes of user-defined field tabs

A burst of field changes (imports, fetchers) queued one Platform.runLater
per event. Track a pending-refresh flag so only one callback is queued,
and read the entry's state at callback time instead of the event payload,
so a queued refresh can never apply stale state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

* Revert unrelated doc comment reindentation

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

* Fix CHANGELOG link style (heylogs dot-space-link-style)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

* Store custom entry editor tabs as JSON map in a single preference key

Replace the low-level parallel numbered series (customTabName_i /
customTabFields_i) with one entryEditorCustomTabs key holding a JSON
object {"tab name": ["field pattern", ...], ...} in display order,
serialized with Jackson (already required by jabgui). The old series is
still read as a migration fallback and purged on the next store.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

* Move old custom-tab format handling into PreferencesMigrations

Convert the pre-v6.0-alpha.7 numbered series (customTabName_i /
customTabFields_i) to the entryEditorCustomTabs JSON key once at startup
in the migrations package, instead of a read-time fallback in
JabRefGuiPreferences. The old keys are kept for use by older JabRef
versions and ignored once the new key exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

* Keep custom-tab preference key private to JabRefGuiPreferences

The migration hardcodes the key name locally (V6_0_* convention), like
the other migrations, instead of exposing the constant publicly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011R3RHnvsmkk2CHm4uEjVDa

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Bumps [com.squareup.okhttp3:okhttp](https://github.com/lysine-dev/okhttp) from 5.4.0 to 5.5.0.
- [Changelog](https://github.com/lysine-dev/okhttp/blob/main/CHANGELOG.md)
- [Commits](lysine-dev/okhttp@parent-5.4.0...parent-5.5.0)

---
updated-dependencies:
- dependency-name: com.squareup.okhttp3:okhttp
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.6.0-jre to 33.7.0-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-version: 33.7.0-jre
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…16629)

Bumps [JetBrains/junie-github-action](https://github.com/jetbrains/junie-github-action) from 1.7.0 to 1.7.4.
- [Release notes](https://github.com/jetbrains/junie-github-action/releases)
- [Commits](JetBrains/junie-github-action@v1.7.0...v1.7.4)

---
updated-dependencies:
- dependency-name: JetBrains/junie-github-action
  dependency-version: 1.7.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [com.google.guava:guava](https://github.com/google/guava) from 33.7.0-jre to 33.7.1-jre.
- [Release notes](https://github.com/google/guava/releases)
- [Commits](https://github.com/google/guava/commits)

---
updated-dependencies:
- dependency-name: com.google.guava:guava
  dependency-version: 33.7.1-jre
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps org.glassfish.hk2:hk2-locator from 4.0.1 to 4.0.2.

---
updated-dependencies:
- dependency-name: org.glassfish.hk2:hk2-locator
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps org.glassfish.hk2:hk2-api from 4.0.1 to 4.0.2.

---
updated-dependencies:
- dependency-name: org.glassfish.hk2:hk2-api
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps org.glassfish.hk2:hk2-utils from 4.0.1 to 4.0.2.

---
updated-dependencies:
- dependency-name: org.glassfish.hk2:hk2-utils
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [net.bytebuddy:byte-buddy](https://github.com/raphw/byte-buddy) from 1.18.11 to 1.18.12.
- [Release notes](https://github.com/raphw/byte-buddy/releases)
- [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md)
- [Commits](raphw/byte-buddy@byte-buddy-1.18.11...byte-buddy-1.18.12)

---
updated-dependencies:
- dependency-name: net.bytebuddy:byte-buddy
  dependency-version: 1.18.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [gradle-wrapper](https://github.com/gradle/gradle) from 9.7.0 to 9.7.1.
- [Release notes](https://github.com/gradle/gradle/releases)
- [Commits](gradle/gradle@v9.7.0...v9.7.1)

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.7.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…16638)

Bumps org.itsallcode.openfasttrace from 3.1.2 to 3.2.0.

---
updated-dependencies:
- dependency-name: org.itsallcode.openfasttrace
  dependency-version: 3.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* New translations {fileName} ({languageName})

* New translations {fileName} ({languageName})
* Fix multi-way merge dialog colors

* Add changelog entry for multi-way merge dialog fix

---------

Co-authored-by: chyi0205 <chyi0205@uni.sydney.edu.au>
# Conflicts:
#	jabgui/src/main/java/org/jabref/gui/frame/MainMenu.java
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.