fj/docs/jq.md
Stephen Way d87a30bb29
docs: CLAUDE.md, CONTRIBUTING.md, CHANGELOG.md, docs/
* CLAUDE.md: project layout, key conventions, where to look first.
  Captures the non-obvious things a future session needs.
* CONTRIBUTING.md: build/test workflow, how to add a subcommand
  (concrete walkthrough), code style.
* CHANGELOG.md: history. 0.1.0 entry covers initial feature set;
  Unreleased captures stability + optimization batch.
* docs/architecture.md: module graph, layering rules, the HTTP funnel,
  pager + SIGINT, repo resolution, test strategy.
* docs/jq.md: --jq syntax cheatsheet (dot paths, brackets, negative
  indices, pipes, what's not supported).
* docs/troubleshooting.md: keychain re-prompts, debug logging, pager
  opt-out, alias precedence, hook bypass, common 401s.
* README.md: links into docs/ and updates binary size to 4 MB.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:48:46 -07:00

77 lines
2.2 KiB
Markdown

# `fj api --jq` syntax
`fj api` ships a small jq-flavored JSON projector. It's not a full jq
implementation; it covers the 95% of cases gh users use `--jq` for.
If you need anything more complex, pipe the raw JSON through real `jq`:
```sh
fj api /repos/foo/bar | jq '.<full expression>'
```
## Stages
Expressions are split on `|` into stages. Each stage runs against the
output of the previous stage.
```
fj api /repos/foo/bar | head
# vs
fj api /repos/foo/bar -q '.owner | .login'
```
## Path segments
Within a stage, dot-separated segments traverse the JSON tree. Each
segment is one of:
| Segment | Meaning |
| ------------ | --------------------------------------------- |
| `.field` | Object field lookup |
| `.0` | Array index (positional) |
| `.[0]` | Same as `.0`, bracket form |
| `.[-1]` | Last element of an array |
| `.[-2]` | Second-to-last element |
Bracket form and dot form are interchangeable: `.data.0.name` and
`.data[0].name` mean the same thing.
## Examples
Given:
```json
{
"data": [
{"id": 1, "owner": {"login": "alice"}},
{"id": 2, "owner": {"login": "bob"}}
],
"total": 2
}
```
| Query | Output |
| ------------------------------ | ------------------ |
| `.total` | `2` |
| `.data.0.id` | `1` |
| `.data[0].owner.login` | `"alice"` |
| `.data[-1].owner.login` | `"bob"` |
| `.data | .[0]` | first element |
| `.data[0] | .owner | .login` | `"alice"` |
## Errors
- A missing field returns a hard error with the field name.
- An out-of-range index returns a hard error with the index.
- Negative indices that overshoot (e.g. `[-5]` on a 3-element array)
also error.
## Not supported
The following are intentionally NOT implemented; reach for real jq:
- Filters like `.[] | select(.state == "open")`
- Functions: `map`, `length`, `keys`, etc.
- String interpolation
- Multiple outputs from a single expression