Repository: JabRef/jabref
Pull request #13011: JabKit build
Author: login: koppor
Labels: name: component: JabKit [cli]
Created: 2025-04-27T19:10:32Z | Merged: 2025-04-27T22:06:31Z

Follow-up to https://github.com/JabRef/jabref/pull/12990. Contributes to https://github.com/JabRef/jabref/issues/110.

Generates a `jabkit-portable_linux.tar.gz` with a `jabkit` executable. (`.zip` and `jabkit.exe` on Windows). For macOS, I have no clue: future work.

```cmd
 > C:\TEMP\JabRef\jabkit\jabkit\jabkit.exe --help
Messages are not initialized before accessing key: Display help on command line options
2025-04-27 22:36:25 [main] org.jabref.logic.search.PostgreServer.<init>()
INFO: Postgres server started, connection port: 56285
usage: jabkit[OPTIONS] [BIBTEX_FILE]

Options: [-a <FILE[.aux],FILE[.bib] FILE>] [-b] [-cc <FILE>] [-d <KEY1[,KEY2][,KEYn] | all>]
       [--debug] [--embedBibFileInPdf <CITEKEY1[,CITEKEY2][,CITEKEYn] | PDF1[,PDF2][,PDFn] | all>]
       [-f <FETCHER:QUERY>] [-g] [-h] [-i <FILE[,FORMAT]>] [-ib <BIBTEX_STRING>] [--importToOpen
       <FILE[,FORMAT]>] [-j <CITATIONKEY>] [-m <QUERY,FILE[,FORMAT]>] [-n] [-o <FILE[,FORMAT]>]
       [--output-format <FORMAT>] [-p <[FILE]>] [-porcelain] [-v] [-w
       <CITEKEY1[,CITEKEY2][,CITEKEYn] | PDF1[,PDF2][,PDFn] | all>] [--writeXmpToPdf
       <CITEKEY1[,CITEKEY2][,CITEKEYn] | PDF1[,PDF2][,PDFn] | all>] [-x <[FILE]>]
 -a,--aux <FILE[.aux],FILE[.bib] FILE>                                                 Sublibrary
                                                                                       from AUX to
                                                                                       BibTeX: '-a
                                                                                       thesis.aux,ne
                                                                                       w.bib'
 -b,--blank                                                                            Do not open
                                                                                       any files at
                                                                                       startup
```

### Mandatory checks

<!--
Go through the checklist below. It is mandatory, even for a draft pull request.

Keep ALL the items. Replace the dots inside [.] and mark them as follows: 
[x] done 
[ ] not done 
[/] not applicable
-->

- [x] I own the copyright of the code submitted and I license it under the [MIT license](https://github.com/JabRef/jabref/blob/main/LICENSE)
- [/] Change in `CHANGELOG.md` described in a way that is understandable for the average user (if change is visible to the user)
- [/] Tests created for changes (if applicable)
- [x] Manually tested changed features in running JabRef (always required)
- [x] Screenshots added in PR description (if change is visible to the user)
- [/] [Checked developer's documentation](https://devdocs.jabref.org/): Is the information available and up to date? If not, I outlined it in this pull request.
- [/] [Checked documentation](https://docs.jabref.org/): Is the information available and up to date? If not, I created an issue at <https://github.com/JabRef/user-documentation/issues> or, even better, I submitted a pull request to the documentation repository.



Diff:
diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml
index b04e856cacb..1c4f69bb59a 100644
--- a/.github/workflows/deployment.yml
+++ b/.github/workflows/deployment.yml
@@ -43,9 +43,11 @@ jobs:
           - os: ubuntu-22.04
             displayName: linux
             archivePortable: tar -c -C jabgui/build/distribution JabRef | pigz --rsyncable > jabgui/build/distribution/JabRef-portable_linux.tar.gz && rm -R jabgui/build/distribution/JabRef
+            archivePortableJabKit: tar -c -C jabkit/build/distribution jabkit | pigz --rsyncable > jabkit/build/distribution/jabkit-portable_linux.tar.gz && rm -R jabkit/build/distribution/jabkit
           - os: windows-latest
             displayName: windows
             archivePortable: 7z a -r jabgui/build/distribution/JabRef-portable_windows.zip ./jabgui/build/distribution/JabRef && rm -R jabgui/build/distribution/JabRef
+            archivePortableJabKit: 7z a -r jabkit/build/distribution/jabkit-portable_windows.zip ./jabkit/build/distribution/jabkit && rm -R jabkit/build/distribution/jabkit
           - os: macos-13  # intel image
             displayName: macOS
             suffix: ''
@@ -101,7 +103,7 @@ jobs:
       - name: Prepare merged jars and modules dir (macOS)
         # prepareModulesDir is executing a build, which should run through even if no upload to builds.jabref.org is made
         if: (matrix.os == 'macos-13') || (matrix.os == 'macos-14') || (steps.checksecrets.outputs.secretspresent == 'NO')
-        run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" prepareModulesDir
+        run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" :jabgui:prepareModulesDir
       - name: Setup macOS key chain
         if: ((matrix.os == 'macos-13') || (matrix.os == 'macos-14')) && (steps.checksecrets.outputs.secretspresent == 'YES')
         uses: slidoapp/import-codesign-certs@1923310662e8682dd05b76b612b53301f431cd5d
@@ -180,11 +182,21 @@ jobs:
       - name: Build runtime image and installer (linux, Windows)
         if: (matrix.os != 'macos-13') && (matrix.os != 'macos-14') && (steps.checksecrets.outputs.secretspresent == 'YES')
         shell: bash
-        run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" :jabgui:jpackage :jabgui:jlinkZip
+        run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" :jabgui:jpackage
+      - name: Build JabKit
+        if: (steps.checksecrets.outputs.secretspresent == 'YES')
+        shell: bash
+        run: ./gradlew -i -PprojVersion="${{ steps.gitversion.outputs.AssemblySemVer }}" -PprojVersionInfo="${{ steps.gitversion.outputs.InformationalVersion }}" :jabkit:jpackage
+      - name: Remove JabKit build for macOS
+        if: (matrix.os == 'macos-13') || (matrix.os == 'macos-14')
+        run: rm -rf jabkit/build/distribution/jabkit.app
       - name: Package application image (linux, Windows)
         if: (matrix.os != 'macos-13') && (matrix.os != 'macos-14') && (steps.checksecrets.outputs.secretspresent == 'YES')
         shell: bash
-        run: ${{ matrix.archivePortable }}
+        run: |
+          set -e
+          ${{ matrix.archivePortable }}
+          ${{ matrix.archivePortableJabKit }}
       - name: Rename files
         if: (matrix.os != 'macos-13') && (matrix.os != 'macos-14') && (steps.checksecrets.outputs.secretspresent == 'YES')
         shell: pwsh
@@ -223,6 +235,7 @@ jobs:
         # for rsync installed by chocolatey, we need the ssh.exe delivered with that installation
         run: |
           rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' jabgui/build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
+          rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'C:\ProgramData\chocolatey\lib\rsync\tools\bin\ssh.exe -p 9922 -i sshkey -o StrictHostKeyChecking=no' jabkit/build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
       - name: Upload to builds.jabref.org (linux, macOS)
         # macOS: Negated condition of "Upload to GitHub workflow artifacts store (macOS)"
         #        Reason: We either upload the non-notarized files - or notarize the files later (and upload these later)
@@ -231,6 +244,7 @@ jobs:
         shell: bash
         run: |
           rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' jabgui/build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
+          rsync -rt --chmod=Du=rwx,Dg=rx,Do=rx,Fu=rw,Fg=r,Fo=r --itemize-changes --stats --rsync-path="mkdir -p /var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }} && rsync" -e 'ssh -p 9922 -i sshkey -o StrictHostKeyChecking=no' jabkit/build/distribution/ jrrsync@build-upload.jabref.org:/var/www/builds.jabref.org/www/${{ steps.gitversion.outputs.branchName }}/ || true
       - name: Upload to GitHub workflow artifacts store (macOS)
         if: ((matrix.os == 'macos-13')  || (matrix.os == 'macos-14')) && (steps.checksecrets.outputs.secretspresent == 'YES') && (startsWith(github.ref, 'refs/tags/') || inputs.notarization == true)
         uses: actions/upload-artifact@v4
diff --git a/jabgui/build.gradle.kts b/jabgui/build.gradle.kts
index 4c009863109..a1540355322 100644
--- a/jabgui/build.gradle.kts
+++ b/jabgui/build.gradle.kts
@@ -169,7 +169,7 @@ application {
         "--add-opens=javafx.base/javafx.collections=org.jabref",
         "--add-opens=javafx.base/javafx.collections.transformation=org.jabref",
 
-        "--enable-native-access=ai.djl.tokenizers,ai.djl.pytorch_engine,com.sun.jna,javafx.graphics,javafx.media,javafx.web,org.apache.lucene.core"
+        "--enable-native-access=org.jabref.merged.module,ai.djl.tokenizers,ai.djl.pytorch_engine,com.sun.jna,javafx.graphics,javafx.media,javafx.web,org.apache.lucene.core"
     )
 }
 
@@ -272,9 +272,7 @@ jlink {
         "--compress",
         "zip-6",
         "--no-header-files",
-        "--no-man-pages"
-    )
-    addOptions(
+        "--no-man-pages",
         "--bind-services"
     )
 
@@ -374,9 +372,6 @@ jlink {
         requires(
             "javafx.swing"
         )
-        requires(
-            "jdk.jsobject"
-        )
         requires(
             "jdk.security.jgss"
         )
@@ -483,100 +478,72 @@ jlink {
 
         if (OperatingSystem.current().isWindows) {
             // This requires WiX to be installed: https://github.com/wixtoolset/wix3/releases
-            installerType =
-                "msi"
+            installerType =  "msi"
 
             imageOptions.addAll(
                 listOf(
-                    "--icon",
-                    "${projectDir}/src/main/resources/icons/jabref.ico"
+                    "--icon", "${projectDir}/src/main/resources/icons/jabref.ico"
                 )
             )
 
             installerOptions.addAll(
                 listOf(
-                    "--vendor",
-                    "JabRef",
-                    "--app-version",
-                    "$version",
+                    "--vendor", "JabRef",
+                    "--app-version", "$version",
                     "--verbose",
-                    "--win-upgrade-uuid",
-                    "d636b4ee-6f10-451e-bf57-c89656780e36",
+                    "--win-upgrade-uuid", "d636b4ee-6f10-451e-bf57-c89656780e36",
                     "--win-dir-chooser",
                     "--win-shortcut",
                     "--win-menu",
-                    "--win-menu-group",
-                    "JabRef",
-                    "--temp",
-                    "$buildDir/installer",
-                    "--resource-dir",
-                    "$projectDir/buildres/windows",
-                    "--license-file",
-                    "$projectDir/buildres/LICENSE_with_Privacy.md",
-                    "--file-associations",
-                    "$projectDir/buildres/windows/bibtexAssociations.properties"
+                    "--win-menu-group", "JabRef",
+                    "--temp", "$buildDir/installer",
+                    "--resource-dir", "$projectDir/buildres/windows",
+                    "--license-file", "$projectDir/buildres/LICENSE_with_Privacy.md",
+                    "--file-associations", "$projectDir/buildres/windows/bibtexAssociations.properties"
                 )
             )
         } else if (OperatingSystem.current().isLinux) {
             imageOptions.addAll(
                 listOf(
-                    "--icon",
-                    "$projectDir/src/main/resources/icons/JabRef-linux-icon-64.png",
-                    "--app-version",
-                    "$version"
+                    "--icon", "$projectDir/src/main/resources/icons/JabRef-linux-icon-64.png",
+                    "--app-version", "$version"
                 )
             )
 
             installerOptions.addAll(
                 listOf(
                     "--verbose",
-                    "--vendor",
-                    "JabRef",
-                    "--app-version",
-                    "$version",
+                    "--vendor",  "JabRef",
+                    "--app-version", "$version",
                     // "--temp", "$buildDir/installer",
-                    "--resource-dir",
-                    "$projectDir/buildres/linux",
-                    "--linux-menu-group",
-                    "Office;",
-                    "--linux-rpm-license-type",
-                    "MIT",
+                    "--resource-dir", "$projectDir/buildres/linux",
+                    "--linux-menu-group", "Office;",
+                    "--linux-rpm-license-type", "MIT",
                     // "--license-file", "$projectDir/LICENSE.md",
-                    "--description",
-                    "JabRef is an open source bibliography reference manager. The native file format used by JabRef is BibTeX, the standard LaTeX bibliography format.",
+                    "--description", "JabRef is an open source bibliography reference manager. The native file format used by JabRef is BibTeX, the standard LaTeX bibliography format.",
                     "--linux-shortcut",
-                    "--file-associations",
-                    "$projectDir/buildres/linux/bibtexAssociations.properties"
+                    "--file-associations", "$projectDir/buildres/linux/bibtexAssociations.properties"
                 )
             )
         } else if (OperatingSystem.current().isMacOsX) {
             imageOptions.addAll(
                 listOf(
-                    "--icon",
-                    "$projectDir/src/main/resources/icons/jabref.icns",
-                    "--resource-dir",
-                    "$projectDir/buildres/mac"
+                    "--icon",  "$projectDir/src/main/resources/icons/jabref.icns",
+                    "--resource-dir", "$projectDir/buildres/mac"
                 )
             )
 
-            skipInstaller =
-                true
+            skipInstaller = true
 
             installerOptions.addAll(
                 listOf(
                     "--verbose",
-                    "--vendor",
-                    "JabRef",
-                    "--mac-package-identifier",
-                    "JabRef",
-                    "--mac-package-name",
-                    "JabRef",
-                    "--app-version",
-                    "$version",
-                    "--file-associations",
-                    "$projectDir/buildres/mac/bibtexAssociations.properties",
-                    "--resource-dir",
-                    "$projectDir/buildres/mac"
+                    "--vendor", "JabRef",
+                    "--mac-package-identifier", "JabRef",
+                    "--mac-package-name", "JabRef",
+                    "--app-version", "$version",
+                    "--file-associations", "$projectDir/buildres/mac/bibtexAssociations.properties",
+                    "--resource-dir", "$projectDir/buildres/mac"
                 )
             )
         }
diff --git a/jabkit/build.gradle.kts b/jabkit/build.gradle.kts
index fb8e77adba1..5d2b49756a4 100644
--- a/jabkit/build.gradle.kts
+++ b/jabkit/build.gradle.kts
@@ -5,8 +5,13 @@ plugins {
 
     // afterburner.fx
     id("org.openjfx.javafxplugin") version("0.1.0")
+
+    id("org.beryx.jlink") version "3.1.1"
 }
 
+group = "org.jabref.jabkit"
+version = project.findProperty("projVersion") ?: "100.0.0"
+
 val luceneVersion = "10.2.0"
 
 dependencies {
@@ -67,7 +72,237 @@ application {
     mainClass.set("org.jabref.cli.JabKit")
     mainModule.set("org.jabref.jabkit")
 
+    // Also passed to launcher (https://badass-jlink-plugin.beryx.org/releases/latest/#launcher)
     applicationDefaultJvmArgs = listOf(
-        "--enable-native-access=com.sun.jna"
+        "--enable-native-access=org.jabref.jabkit.merged.module,com.sun.jna,javafx.graphics,org.apache.lucene.core"
+    )
+}
+
+// This is more or less a clone of jabgui/build.gradle.kts -> jlink
+jlink {
+    // https://github.com/beryx/badass-jlink-plugin/issues/61#issuecomment-504640018
+    addExtraDependencies(
+        "javafx"
     )
+
+    // We keep debug statements - otherwise "--strip-debug" would be included
+    addOptions(
+        "--compress",
+        "zip-6",
+        "--no-header-files",
+        "--no-man-pages",
+        "--bind-services"
+    )
+
+    launcher {
+        name = "jabkit"
+    }
+
+    // TODO: Remove as soon as dependencies are fixed (upstream)
+    forceMerge(
+        "controlsfx",
+        "bcprov",
+        "jaxb",
+        "istack",
+        "stax"
+    )
+
+    mergedModule {
+        requires(
+            "com.google.gson"
+        )
+        requires(
+            "com.fasterxml.jackson.annotation"
+        )
+        requires(
+            "com.fasterxml.jackson.databind"
+        )
+        requires(
+            "com.fasterxml.jackson.core"
+        )
+        requires(
+            "com.fasterxml.jackson.datatype.jdk8"
+        )
+        requires(
+            "jakarta.xml.bind"
+        )
+        requires(
+            "java.compiler"
+        )
+        requires(
+            "java.datatransfer"
+        )
+        requires(
+            "java.desktop"
+        )
+        requires(
+            "java.logging"
+        )
+        requires(
+            "java.management"
+        )
+        requires(
+            "java.naming"
+        )
+        requires(
+            "java.net.http"
+        )
+        requires(
+            "java.rmi"
+        )
+        requires(
+            "java.scripting"
+        )
+        requires(
+            "java.security.jgss"
+        )
+        requires(
+            "java.security.sasl"
+        )
+        requires(
+            "java.sql"
+        )
+        requires(
+            "java.sql.rowset"
+        )
+        requires(
+            "java.transaction.xa"
+        )
+        requires(
+            "java.xml"
+        )
+        requires(
+            "javafx.base"
+        )
+        requires(
+            "javafx.controls"
+        )
+        requires(
+            "javafx.fxml"
+        )
+        requires(
+            "javafx.graphics"
+        )
+        requires(
+            "jdk.security.jgss"
+        )
+        requires(
+            "jdk.unsupported"
+        )
+        requires(
+            "jdk.unsupported.desktop"
+        )
+        requires(
+            "jdk.xml.dom"
+        )
+        requires(
+            "org.apache.commons.lang3"
+        )
+        requires(
+            "org.apache.commons.logging"
+        )
+        requires(
+            "org.apache.commons.text"
+        )
+        requires(
+            "org.apache.commons.codec"
+        )
+        requires(
+            "org.apache.commons.io"
+        )
+        requires(
+            "org.apache.commons.compress"
+        )
+        requires(
+            "org.freedesktop.dbus"
+        )
+        requires(
+            "org.jsoup"
+        )
+        requires(
+            "org.slf4j"
+        )
+        requires(
+            "org.tukaani.xz"
+        );
+        uses(
+            "ai.djl.engine.EngineProvider"
+        )
+        uses(
+            "ai.djl.repository.RepositoryFactory"
+        )
+        uses(
+            "ai.djl.repository.zoo.ZooProvider"
+        )
+        uses(
+            "dev.langchain4j.spi.prompt.PromptTemplateFactory"
+        )
+        uses(
+            "kong.unirest.core.json.JsonEngine"
+        )
+        uses(
+            "org.eclipse.jgit.lib.Signer"
+        )
+        uses(
+            "org.eclipse.jgit.transport.SshSessionFactory"
+        )
+        uses(
+            "org.postgresql.shaded.com.ongres.stringprep.Profile"
+        )
+
+        provides(
+            "java.sql.Driver"
+        ).with(
+            "org.postgresql.Driver"
+        )
+        provides(
+            "java.security.Provider"
+        ).with(
+            "org.bouncycastle.jce.provider.BouncyCastleProvider",
+            "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider"
+        )
+        provides(
+            "kong.unirest.core.json.JsonEngine"
+        ).with(
+            "kong.unirest.modules.gson.GsonEngine"
+        )
+        provides(
+            "ai.djl.repository.zoo.ZooProvider"
+        ).with(
+            "ai.djl.engine.rust.zoo.RsZooProvider",
+            "ai.djl.huggingface.zoo.HfZooProvider",
+            "ai.djl.pytorch.zoo.PtZooProvider",
+            "ai.djl.repository.zoo.DefaultZooProvider"
+        )
+        provides(
+            "ai.djl.engine.EngineProvider"
+        ).with(
+            "ai.djl.engine.rust.RsEngineProvider",
+            "ai.djl.pytorch.engine.PtEngineProvider"
+        )
+
+    }
+    jpackage {
+        outputDir = "distribution"
+
+        // See https://docs.oracle.com/en/java/javase/24/docs/specs/man/jpackage.html#platform-dependent-options-for-creating-the-application-package for available options
+        if (org.gradle.internal.os.OperatingSystem.current().isWindows) {
+            imageOptions.addAll(
+                listOf(
+                    "--win-console"
+                )
+            )
+           skipInstaller = true
+        } else if (org.gradle.internal.os.OperatingSystem.current().isLinux) {
+            imageOptions.addAll(
+                listOf(
+                    "--icon", "$projectDir/../jabgui/src/main/resources/icons/JabRef-linux-icon-64.png",
+                    "--app-version", "$version"
+                )
+            )
+            skipInstaller = true
+        } else if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) {
+            skipInstaller = true
+        }
+    }
 }
diff --git a/jabkit/src/main/java/org/jabref/cli/JabKitCliOptions.java b/jabkit/src/main/java/org/jabref/cli/JabKitCliOptions.java
index 6608b4aafd2..dfe33d3844a 100644
--- a/jabkit/src/main/java/org/jabref/cli/JabKitCliOptions.java
+++ b/jabkit/src/main/java/org/jabref/cli/JabKitCliOptions.java
@@ -346,11 +346,11 @@ public static void printUsage(CliPreferences preferences) {
         String footer = '\n' + importFormatsList + outFormatsList + "\nPlease report issues at https://github.com/JabRef/jabref/issues.";
 
         HelpFormatter formatter = new HelpFormatter();
-        formatter.printHelp(WIDTH, "jabref [OPTIONS] [BIBTEX_FILE]\n\nOptions:", header, getOptions(), footer, true);
+        formatter.printHelp(WIDTH, "jabkit [OPTIONS] [BIBTEX_FILE]\n\nOptions:", header, getOptions(), footer, true);
     }
 
     private String getVersionInfo() {
-        return "JabRef %s".formatted(new BuildInfo().version);
+        return "jabkit %s".formatted(new BuildInfo().version);
     }
 
     public List<String> getLeftOver() {


Reviews:
user: login: trag-bot[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-27T20:38:52Z
user: login: trag-bot[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-27T20:38:57Z
user: login: calixtus
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-27T22:06:05Z

Review comments:
diff_hunk: @@ -346,11 +346,11 @@ public static void printUsage(CliPreferences preferences) {
         String footer = '\n' + importFormatsList + outFormatsList + "\nPlease report issues at https://github.com/JabRef/jabref/issues.";
 
         HelpFormatter formatter = new HelpFormatter();
-        formatter.printHelp(WIDTH, "jabref [OPTIONS] [BIBTEX_FILE]\n\nOptions:", header, getOptions(), footer, true);
+        formatter.printHelp(WIDTH, "jabkit [OPTIONS] [BIBTEX_FILE]\n\nOptions:", header, getOptions(), footer, true);
path: jabkit/src/main/java/org/jabref/cli/JabKitCliOptions.java
user: login: trag-bot[bot]
body: The help message string should use 'BibTeX' instead of 'BIBTEX' for consistency with the rest of the application and to adhere to the special instruction on spelling. 

created_at: 2025-04-27T20:38:52Z
author_association: NONE
diff_hunk: @@ -346,11 +346,11 @@ public static void printUsage(CliPreferences preferences) {
         String footer = '\n' + importFormatsList + outFormatsList + "\nPlease report issues at https://github.com/JabRef/jabref/issues.";
 
         HelpFormatter formatter = new HelpFormatter();
-        formatter.printHelp(WIDTH, "jabref [OPTIONS] [BIBTEX_FILE]\n\nOptions:", header, getOptions(), footer, true);
+        formatter.printHelp(WIDTH, "jabkit [OPTIONS] [BIBTEX_FILE]\n\nOptions:", header, getOptions(), footer, true);
     }
 
     private String getVersionInfo() {
-        return "JabRef %s".formatted(new BuildInfo().version);
+        return "jabkit %s".formatted(new BuildInfo().version);
path: jabkit/src/main/java/org/jabref/cli/JabKitCliOptions.java
user: login: trag-bot[bot]
body: The version info string should use 'BibTeX' instead of 'jabkit' for consistency with the rest of the application and to adhere to the special instruction on spelling. 

created_at: 2025-04-27T20:38:57Z
author_association: NONE

PR comments:
user: login: trag-bot[bot]
created_at: 2025-04-27T21:42:02Z
body: @trag-bot didn't find any issues in the code! ✅✨
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-04-27T21:54:59Z
body: The build for this PR is no longer available. Please visit <https://builds.jabref.org/main/> for the latest build.
<!-- thollander/actions-comment-pull-request "download-link" -->
author_association: CONTRIBUTOR