jq builtin
Bashkit ships an embedded jq JSON processor backed by jaq with a thin
compatibility shim layered on top. This guide documents which jq features
are supported so callers (and LLM agents that generate jq filters against
bashkit) can avoid surprises.
Reported version
jq --version prints jq-1.8. Filters generated for stedfan/jq 1.7 and 1.8
are the intended target.
Command-line flags
Implemented:
| Flag | Description |
|---|---|
-r, --raw-output | Strings are written without quotes |
-R, --raw-input | Each line of input becomes a JSON string |
-s, --slurp | Read every input value into one array |
-n, --null-input | Use null as the (single) input value |
-c, --compact-output | One JSON value per line, no pretty-printing |
-S, --sort-keys | Sort object keys recursively |
-e, --exit-status | Set exit code based on the output |
-j | Like -r but suppresses trailing newlines |
--tab | Use tabs for indentation |
--arg name value | Bind $name to a string |
--argjson name json | Bind $name to a parsed JSON value |
-V, --version | Print the version |
-h, --help | Print help |
Combined flags like -snr | Treated as the union of the individual flags |
Variables
| Variable | Behaviour |
|---|---|
$ENV | Bound to the shell environment as an object — same map as the env filter. (#1486) |
$name | Variables defined with --arg / --argjson are passed through. |
Notable filters
The full jq stdlib is mostly available via jaq-std. The compatibility
shim adds or overrides:
| Filter | Notes |
|---|---|
env | Reads from the shell env map (not the host process env), avoiding the unsafe std::env::set_var path. |
setpath(p; v) | Bashkit ships a recursive definition because jaq’s stdlib doesn’t expose one. |
leaf_paths | Defined as paths(scalars) since jaq’s stdlib lacks it. |
match(re; flags) / match(re) | Overridden to add "name": null to unnamed captures, matching jq output. |
scan(re; flags) / scan(re) | Overridden so scan defaults to global (“g”) matching, matching jq. |
input_filename | Stub returning null (#1486). Bashkit reads inputs as a single concatenated stream via shell redirection, so per-input filenames are not tracked. |
input_line_number | Stub returning 0 (#1486). Per-line input tracking is not implemented. |
input / inputs | Real jaq implementations — pull from the shared input iterator. |
| Most other 1.7/1.8 stdlib filters | Forwarded from jaq-std (getpath, paths, to_entries, group_by, ltrimstr/rtrimstr, splits, test, now, debug, limit, etc.). |
Errors
Filter parse failures and runtime errors return exit code 3 and 5
respectively, matching jq. Long error operands are summarised so failures
do not blow up an LLM context window — see
#1485.
Known gaps
Bashkit’s jq is intentionally minimal in places where the host model differs from upstream jq:
- File inputs are concatenated into a single stream by the shell, so
per-file metadata (
input_filename,input_line_number) is stubbed. - Exotic numeric formatting modes (
@base32,@base64d, etc.) follow whateverjaq-jsonships.
If you hit a missing builtin, please open an issue with the failing filter.
See also
compatibility_scorecard— overall builtin coverage table.threat_model— security model forjqagainst malicious input.