Skip to content

Add OCR engine selection preference - #16455

Merged
subhramit merged 22 commits into
JabRef:mainfrom
ZiadAbdElFatah:engine-selection-preference
Aug 7, 2026
Merged

Add OCR engine selection preference#16455
subhramit merged 22 commits into
JabRef:mainfrom
ZiadAbdElFatah:engine-selection-preference

Conversation

@ZiadAbdElFatah

@ZiadAbdElFatah ZiadAbdElFatah commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add an OCR engine selection preference in OCR preferences, and auto-detection of the engine path is run automatically when switching engines.

Steps to test

  1. Open OCR preferences, there is a preference for engine selection
ocr-preferences 2. Try switching between OCRmyPDF and Docling ocr-engine-selection-dropdown 3. On switching the selection, the engine path will change automatically to match one of the default paths stored for each engine

Related issues and pull requests

Follow-up #16231

AI usage

NA

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 (always required)
  • [/] I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • [/] 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 in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Add OCR engine selection preference with per-engine path auto-detection

✨ Enhancement ⚙️ Configuration changes 🕐 20-40 Minutes

Grey Divider

AI Description

• Add OCR engine selector (OCRmyPDF/Docling) to OCR preferences.
• Auto-detect and switch default engine path when the engine selection changes.
• Persist engine selection in preferences and localize new/updated UI messages.
Diagram

graph TD
  A["OcrTab (UI)"] --> B["OcrTabViewModel"] --> C["OcrPreferences"] --> D["OcrEngine factory"] --> E["OcrMyPdfEngine / DoclingEngine"]
  F["JabRefCliPreferences"] --> C
  G["OcrLinkedFileAction"] --> C --> D
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Pluggable engine registry (ServiceLoader/DI)
  • ➕ Avoids growing switch/if logic as more engines are added
  • ➕ Allows engines to be added without touching core preference code
  • ➕ Can centralize per-engine metadata (display name, default paths, capabilities)
  • ➖ More moving parts and indirection for a two-engine setup
  • ➖ Harder to reason about at compile time; needs careful ordering/selection rules
2. Store engine implementation id + per-engine settings map
  • ➕ More extensible preference model (per-engine defaults and overrides)
  • ➕ Can remember last-used path per engine rather than overwriting a single field
  • ➖ Larger migration/change footprint in preferences and UI
  • ➖ More complex UX (multiple paths) unless carefully designed

Recommendation: The current enum-based selection with OcrPreferences#getOcrEngine() is a good fit for two supported engines and keeps the behavior explicit and testable. If additional engines are planned, consider evolving toward a small registry that encapsulates engine metadata (display name, default paths, detection strategy) to avoid further conditional branching and to optionally remember per-engine paths.

Files changed (8) +106 / -26

Enhancement (5) +92 / -17
OcrLinkedFileAction.javaUse selected OCR engine from preferences and improve error text +2/-3

Use selected OCR engine from preferences and improve error text

• Stops hard-coding OCRmyPDF and instead retrieves the active OcrEngine from OcrPreferences. Error messaging now includes the selected engine name when the engine is unavailable.

jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java

OcrTab.javaAdd engine selection UI and simplify engine-path row +7/-4

Add engine selection UI and simplify engine-path row

• Introduces an OCR engine selection combo box in the OCR preferences tab. Removes the manual 'auto-detect' button from the path row (auto-detection is now triggered by engine switching).

jabgui/src/main/java/org/jabref/gui/preferences/ocr/OcrTab.java

OcrTabViewModel.javaPersist engine selection and auto-detect per-engine default paths +33/-8

Persist engine selection and auto-detect per-engine default paths

• Adds an EngineSelection property with available options, loads/stores it via OcrPreferences, and triggers auto-detection when the engine changes. Splits default detection paths by engine (OCRmyPDF vs Docling) and updates user-facing task/notification strings to be engine-specific.

jabgui/src/main/java/org/jabref/gui/preferences/ocr/OcrTabViewModel.java

EngineSelection.javaIntroduce EngineSelection enum for OCR engine choice +24/-0

Introduce EngineSelection enum for OCR engine choice

• Adds a new enum representing supported OCR engines with display names and a safeValueOf helper that defaults to OCRmyPDF for unknown values.

jablib/src/main/java/org/jabref/logic/ocr/EngineSelection.java

OcrPreferences.javaAdd engine selection to OCR preferences and engine factory method +26/-2

Add engine selection to OCR preferences and engine factory method

• Extends OCR preferences with an EngineSelection property (defaulting to OCRmyPDF). Adds getOcrEngine() to construct the correct engine implementation (OCRmyPDF or Docling) based on the stored selection.

jablib/src/main/java/org/jabref/logic/ocr/OcrPreferences.java

Documentation (2) +9 / -8
OcrMyPdfEngine.javaAdjust OCR engine Javadoc link formatting +2/-2

Adjust OCR engine Javadoc link formatting

• Updates return-type documentation formatting in the OCRmyPDF engine implementation without changing runtime behavior.

jablib/src/main/java/org/jabref/logic/ocr/OcrMyPdfEngine.java

JabRef_en.propertiesLocalize engine selection and parameterized engine messages +7/-6

Localize engine selection and parameterized engine messages

• Replaces OCRmyPDF-specific strings with parameterized variants that include the engine name and path. Adds new localization keys for the engine selection UI and auto-detection messaging.

jablib/src/main/resources/l10n/JabRef_en.properties

Other (1) +5 / -1
JabRefCliPreferences.javaPersist and bind OCR engine selection preference +5/-1

Persist and bind OCR engine selection preference

• Introduces a new preference key (ocrEngineSelection), includes it in OcrPreferences construction, and binds it for persistence alongside existing OCR preferences.

jablib/src/main/java/org/jabref/logic/preferences/JabRefCliPreferences.java

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. EngineSelection lacks @NullMarked 📘 Rule violation ☼ Reliability
Description
The new public enum EngineSelection is introduced without JSpecify nullness defaults
(@NullMarked), leaving nullability contracts implicit and inconsistent with the project’s
null-safety conventions. This increases the risk of null-related bugs and weakens API guarantees for
new code.
Code

jablib/src/main/java/org/jabref/logic/ocr/EngineSelection.java[R1-24]

+package org.jabref.logic.ocr;
+
+public enum EngineSelection {
+    OCRMYPDF("OCRmyPDF"),
+    DOCLING("Docling");
+
+    private final String displayName;
+
+    EngineSelection(String displayName) {
+        this.displayName = displayName;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+
+    public static EngineSelection safeValueOf(String name) {
+        try {
+            return EngineSelection.valueOf(name);
+        } catch (IllegalArgumentException e) {
+            return EngineSelection.OCRMYPDF;
+        }
+    }
+}
Evidence
PR Compliance ID 12 requires new public classes/types to use JSpecify nullness conventions
(including @NullMarked). The newly added EngineSelection enum is public but contains no JSpecify
annotations.

AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not return or accept null; use JSpecify nullness annotations and @NullMarked on new classes: AGENTS.md: Public APIs should not ret...

Comment thread jablib/src/main/java/org/jabref/logic/ocr/EngineSelection.java
Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrPreferences.java Outdated
Comment thread jabgui/src/main/java/org/jabref/gui/preferences/ocr/OcrTabViewModel.java Outdated
Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Aug 1, 2026
@subhramit subhramit changed the title Engine selection preference Add OCR engine selection preference Aug 1, 2026
@subhramit

Copy link
Copy Markdown
Member

Could you see if any of Qodo's opinions make sense above, we'll do the next round

Comment thread jablib/src/main/java/org/jabref/logic/ocr/OcrPreferences.java Outdated
@InAnYan

InAnYan commented Aug 2, 2026

Copy link
Copy Markdown
Member

I would make the first 2 sections into 1 "OCR Engine"

@InAnYan InAnYan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple of nitpicks

Comment thread jabgui/src/main/java/org/jabref/gui/linkedfile/OcrLinkedFileAction.java Outdated
@ZiadAbdElFatah

ZiadAbdElFatah commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

I would make the first 2 sections into 1 "OCR Engine"

Yeah, I think this is better than the old one.
The user docs will need to be updated after this one.
Here: JabRef/user-documentation#651

@ZiadAbdElFatah
ZiadAbdElFatah requested a review from InAnYan August 4, 2026 00:36
@subhramit

subhramit commented Aug 4, 2026

Copy link
Copy Markdown
Member

Localization tests seem to be failing

@github-actions github-actions Bot added status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Aug 4, 2026
@subhramit subhramit added project: gsoc component: ocr status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers labels Aug 5, 2026
InAnYan
InAnYan previously approved these changes Aug 6, 2026
@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete and removed status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers status: no-bot-comments labels Aug 7, 2026
@subhramit
subhramit enabled auto-merge August 7, 2026 05:06
@subhramit
subhramit added this pull request to the merge queue Aug 7, 2026
@github-actions github-actions Bot added status: to-be-merged PRs which are accepted and should go into the merge-queue. status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete labels Aug 7, 2026
Merged via the queue into JabRef:main with commit bdae0d9 Aug 7, 2026
61 of 62 checks passed
@ZiadAbdElFatah
ZiadAbdElFatah deleted the engine-selection-preference branch August 7, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: ocr project: gsoc status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants