Add Agent Skills for JabKit usage and JabRef development - #16162
Conversation
Provides SKILL.md files discoverable by AI agents and the skills.sh registry, grouped into users/ (pdf-to-bibtex, bibtex-library-management, jabkit) and developers/ (jabref-contributor). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PR Summary by QodoAdd Agent Skills (SKILL.md) for jabkit usage and JabRef contribution workflow
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
Code Review by Qodo
1. Porcelain/debug flags mispositioned
|
Bare filenames do not resolve once the skill is installed outside a JabRef checkout; use full GitHub URLs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each skill can be installed standalone, so each carries the same self-contained bootstrap: JBang universal one-liners (Linux/macOS and Windows) followed by jbang app install. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| ```bash | ||
| jabkit convert --input library.bib --output library.html --output-format html | ||
| ``` | ||
|
|
||
| `--output-format` defaults to `bibtex`. Use `--input-format "*"` to auto-detect the input. Apply field formatters during conversion with `--field-formatters`. |
There was a problem hiding this comment.
1. Convert example missing input-format 🐞 Bug ≡ Correctness
The bibtex-library-management skill shows jabkit convert without --input-format, but the convert command passes a null input format into ImportService.importFile(...), which then fails with an unknown import format. Copy/pasting the example can therefore error instead of converting the .bib file.
Agent Prompt
## Issue description
`jabkit convert` requires an explicit import format (or `"*"` for auto-detection). The skill’s conversion example omits `--input-format`, which can cause an “Unknown import format” error.
## Issue Context
In the CLI implementation, `Convert` forwards the `--input-format` value directly into `ImportService.importFile(Path, format, ...)`. When the option is not supplied, the value is `null`, and the import layer cannot resolve an importer.
## Fix Focus Areas
- skills/users/bibtex-library-management/SKILL.md[69-76]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| | `pseudonymize` | Replace identifying data in a library (writes a key file for reversal) | | ||
| | `search` | Search in a library using JabRef's search syntax | | ||
|
|
||
| Input files are passed positionally or via `--input`; both forms are equivalent. `--input-format "*"` auto-detects the input format. |
There was a problem hiding this comment.
2. --input claim wrong for check 🐞 Bug ≡ Correctness
The jabkit skill claims input files can be passed positionally or via --input equivalently, but the top-level check command only defines a positional FILE parameter and no --input option. Following the documented pattern jabkit check --input library.bib will fail with an unknown option.
Agent Prompt
## Issue description
The skill text over-generalizes `--input` support. `jabkit check` (without subcommand) accepts only a positional `FILE`, not `--input`.
## Issue Context
Other commands use the shared `InputOption` mixin to support `--input`, but `Check` uses its own positional parameter instead.
## Fix Focus Areas
- skills/users/jabkit/SKILL.md[60-60]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
Code review by qodo was updated up to the latest commit 3aa6a9d |
TL;DR: With this, we are listed at https://www.skills.sh/
Related issues and pull requests
None — searched jabref/issues and jabref-koppor/issues for related issues on agent skills; no match found.
PR Description
Adds Agent Skills (
SKILL.mdfiles) to the repository so AI agents such as Claude Code can discover how to usejabkitand how to work on the JabRef codebase. Skills are grouped intoskills/users/(pdf-to-bibtex,bibtex-library-management,jabkit) andskills/developers/(jabref-contributor) — a two-level catalog layout supported by the skills CLI, which also makes them installable vianpx skills add JabRef/jabrefand discoverable on skills.sh for searches such as "bibtex", "biblatex", "papers", and "jabref". All command examples were written against the currentjabkitpicocli command classes (e.g.citationkeys generate,--input-format "*"for auto-detection), not against possibly stale docs.Analogies
Like honey, this PR is the product of many small foraging trips (through the picocli command classes) concentrated into something that keeps. Like chocolate, it is best consumed one square at a time - one skill per task. And like the moon, it emits no light of its own: it only reflects what jabkit already does.
jabref-contrib-policy:4.2:reviewed:ok
Steps to test
Run
npx skills add JabRef/jabref@add-agent-skills(or point the CLI at a local checkout) and confirm all four skills are discovered, including the category subdirectories.Spot-check the command examples in the skill files against
jabkit --helpoutput, e.g.:npx markdownlint-cli2 "skills/**/*.md"— passes with 0 errors.AI usage
Claude Code (models claude-sonnet-5 and claude-fable-5). The skill contents were derived from the
jabkitsource code,AGENTS.md,CHECKLIST.md, anddocs/and reviewed by the contributor.AI CHECKLIST.md walkthrough
This change adds Markdown files only (new
skills/directory; no Java, no build files, no application behavior change), so code and Gradle items are marked not applicable. Markdown was verified withnpx markdownlint-cli2 "skills/**/*.md"(0 errors; the new files are outside the default globs).1. Code self-review
Read your own diff once, top to bottom, and confirm each point.
Nullability and control flow
== null/!= nullchecks — JSpecify annotations (@NullMarked,@Nullable,@NonNull) used instead.Objects.requireNonNull(...)— nullability expressed via JSpecify annotations.@NullMarked(org.jspecify.annotations.NullMarked).Optionalconsumed withifPresent/ifPresentOrElse/map/orElseThrow— neverorElse(unusedValue)nor anisPresent()+get()block.StringUtil.isBlank(...)used instead ofs == null || s.isBlank().Exceptions
catch (Exception e)— only specific exceptions are caught.throw new RuntimeException(...)/IllegalStateException(...)— these tear down the whole application.LOGGER.info("...", e)), not concatenated into the message string.Style and idioms
BibEntryobjects built with withers (withField, notsetField).List.of()/Map.of()/Set.of(),Path.of(),SequencedCollection/SequencedSet, text blocks.Pattern.compile(...)constant, notString.matches(...).org.jabref.logic.util.BackgroundTask, notnew Thread().///) uses Markdown syntax, not JavaDoc inline tags:`code`instead of{@code},[ClassName]instead of{@link}.User-facing text
Localization.langin Java,%prefix in FXML).!; labels do not end with:."...: %0"), not string concatenation.Security
text/htmlresponse — including exception/error messages, not just the success body (XSS).Tests
org.jabref.model/org.jabref.logichave added or updated tests.assertEquals), use plain JUnit asserts (not AssertJ), have no@DisplayName, do not catch exceptions (let them propagate so JUnit reports setup/teardown failures directly), and use@TempDirinstead of manual temp directories.2. Verification commands
Run in this order — cheapest first. Each must pass.
./gradlew :jablib:check(or./gradlew checkfor all modules)../gradlew checkstyleMain checkstyleTest checkstyleJmh../gradlew modernizer../gradlew --no-configuration-cache :rewriteDryRunreports no changes (run./gradlew rewriteRunto fix)../gradlew javadoc.npx markdownlint-cli2 "docs/**/*.md" "*.md"(only if Markdown changed).rewriteRun:docker run -v $(pwd):/github/workspace ghcr.io/leventebajczi/intellij-format:master "*.java" "" ".idea/codeStyles/Project.xml".3. Documentation
CHANGELOG.mdentry added if the change is visible to the user (end-user wording, no extra blank lines). UseTODOas the issue/PR reference placeholder when no issue is known and the PR is not yet created — never a fake number.TODO(nocloses/fixesfor merely-similar issues).docs/requirements/<area>.mdif the change is a new feature or significant bug fix (skip for refactors, minor fixes, and internal changes).docs/updated if behavior or architecture changed.4. Pull request
.github/PULL_REQUEST_TEMPLATE.md, every section filled.[x],[ ], or[/].gh pr create --body-file <file>(not--body).CHANGELOG.mdused aTODOplaceholder, it was replaced with the real PR-number link after PR creation, then committed and pushed.Checklist
jabkitcommand sources insteadCHANGELOG.mdin a way that can be understood by the average user (if change is visible to the user)