$npx -y skills add AdamBien/airails --skill java-cli-scriptCreate zero-dependency, single-file executable Java scripts for system-wide use via PATH. Use when asked to create a single-file Java shell script, system utility, PATH-installed Java tool, or shebang-launched Java program without the .java extension. Triggers on "Java script", "
| 1 | Create or maintain a zero-dependency, single-file executable Java script using $ARGUMENTS. Apply all rules below strictly. |
| 2 | |
| 3 | ## Purpose |
| 4 | |
| 5 | These are self-contained, single-file Java scripts installed in a PATH directory (e.g., `/usr/local/bin`) and invoked like any shell command — no project structure, no build tool, no `.java` extension. |
| 6 | |
| 7 | ## Composition |
| 8 | |
| 9 | - Follow `/java-conventions` for all generic Java 25 style, syntax, naming, methods, streams, exceptions, and comments |
| 10 | - The rules below specialize `/java-conventions` for single-file source-mode scripts; when this skill is silent on a topic, `/java-conventions` applies |
| 11 | |
| 12 | ## Single-File Constraint |
| 13 | |
| 14 | - Everything lives in one file — all logic, records, enums, sealed types, and helper methods |
| 15 | - If the script grows beyond what fits comfortably in a single file, suggest switching to the `java-cli-app` skill instead |
| 16 | - No multi-file source-code programs — this skill is strictly for single-file scripts |
| 17 | |
| 18 | ## Build |
| 19 | |
| 20 | - Use Java 25 source-file mode — no build tool, no compilation step |
| 21 | - Never use the `.java` extension — scripts are executable files with a lowercase filename and a shebang |
| 22 | - Never use `--enable-preview` in the shebang — Java 25 is a GA release, all features used here are standard |
| 23 | - The shebang line is always: |
| 24 | |
| 25 | ``` |
| 26 | #!/usr/bin/env -S java --source 25 |
| 27 | ``` |
| 28 | |
| 29 | - Save with a short, descriptive, lowercase command name (e.g., `jsonformat`, `portcheck`, `sysinfo`) |
| 30 | - Never use dashes in filenames (e.g., `hello-world`) — Java source-file mode does not support them. Use camelCase instead (e.g., `helloWorld`) |
| 31 | - Mark executable: `chmod +x scriptname` |
| 32 | - Install by copying or symlinking to a PATH directory: `cp scriptname /usr/local/bin/` or `ln -s $(pwd)/scriptname /usr/local/bin/scriptname` |
| 33 | |
| 34 | ## Script Structure |
| 35 | |
| 36 | A minimal script: |
| 37 | |
| 38 | ``` |
| 39 | #!/usr/bin/env -S java --source 25 |
| 40 | |
| 41 | void main(String... args) throws Exception { |
| 42 | // ... |
| 43 | } |
| 44 | ``` |
| 45 | |
| 46 | ## Naming Convention |
| 47 | |
| 48 | - The script's filename is its application name — use it consistently in all output: version strings, help text, usage lines, and error messages |
| 49 | - Derive the application name dynamically at startup using `MethodHandles.lookup().lookupClass().getName()` — in source-file mode, the class name matches the filename, so there is nothing to hardcode or keep in sync |
| 50 | |
| 51 | ## Version Management |
| 52 | |
| 53 | - Suggest maintaining a `String version = "YYYY-MM-DD.N";` instance variable (e.g., `String version = "2026-02-20.1";`) |
| 54 | - On every change, update the date to the current date and increase the last number |
| 55 | - Print the script name and version on startup as the first line of output (e.g., `IO.println(name + " " + version);`) |
| 56 | - Support `-version` flag to print the version — only for scripts that accept additional arguments |
| 57 | |
| 58 | ## Main Method Conventions |
| 59 | |
| 60 | - Use `void main(String... args) throws Exception` — PATH-installed scripts always accept arguments; declaring `throws Exception` keeps the code clean by avoiding try-catch boilerplate for checked exceptions like `IOException` |
| 61 | - Parse arguments manually for simple scripts with few flags |
| 62 | - For scripts with multiple options or complex argument handling, use the `/zargs` skill to generate an enum-based argument parser — it remains zero-dependency and single-file |
| 63 | |
| 64 | ## Argument Handling |
| 65 | |
| 66 | - Scripts with no additional arguments: do not introduce `-help` or `-version` flags — the script should just do its work |
| 67 | - Scripts with additional arguments: support both `-help` and `-version` flags |
| 68 | - Use clear, descriptive error messages for invalid input |
| 69 | - Exit with code 0 on success, non-zero on failure |
| 70 | |
| 71 | Script with additional arguments — include `-help` and `-version`: |
| 72 | |
| 73 | ``` |
| 74 | String name = MethodHandles.lookup().lookupClass().getName(); |
| 75 | String version = "2026-02-20.1"; |
| 76 | |
| 77 | void main(String... args) throws Exception { |
| 78 | IO.println(name + " " + version); |
| 79 | if (args.length == 0 || args[0].equals("-help")) { |
| 80 | IO.println(""" |
| 81 | Usage: %s <input> [options] |
| 82 | -help Show this help |
| 83 | -version Show version |
| 84 | """.formatted(name)); |
| 85 | return; |
| 86 | } |
| 87 | if (args[0].equals("-version")) { |
| 88 | return; |
| 89 | } |
| 90 | // ... |
| 91 | } |
| 92 | ``` |
| 93 | |
| 94 | ## Convenience Scripts for an Existing java-cli-app or JAR |
| 95 | |
| 96 | When asked for an executable convenience script for a `/java-cli-app` project or an existing JAR, do not replicate the application's logic in the script. The script stays a single-file source script whose `main` calls into the JAR's classes. Instead: |
| 97 | |
| 98 | - |