# ax > ax is a scriptless multitool CLI for AI agents. Use it instead of writing a > throwaway python/regex script when you need to extract data from HTML, query > JSON or YAML, process text, or do small encode/time conversions. Input is a > file path, a URL (http/https), or `-` for stdin. Output is JSON or plain > lines, capped by default to stay token-cheap. Install: curl -fsSL https://ax.yusuke.run/install | sh Agent skill (Claude Code): https://ax.yusuke.run/skill.md Source: https://github.com/yusukebe/ax ## Conventions - Source argument: file path | URL | `-` (stdin) - `--limit ` caps results (default 50); `--all` removes the cap - Hidden results are announced on stderr (never silent truncation) - Errors: single line `ax: error: ` on stderr, exit 1, often with a hint - Compose commands with pipes; every command reads stdin with `-` ## ax html — extract from HTML with CSS selectors ax html [options] --text text content per match (default) --attr attribute value per match (e.g. --attr href) --html inner HTML per match --json JSON array of {text, html, attrs} --row structured rows: 'name=sel, name2=sel@attr, ...' sel is relative to each match; @attr reads an attribute; empty sel (id=@data-id) targets the match itself --table parse into rows keyed by headers (selector optional; defaults to every table) --where filter --row/--table rows (see expressions below) --outline discovery: repeating tag.class signatures with counts --locate discovery: selector paths that contain text (also matches attribute values); returns {selector, match} --count how many elements match the selector Discovery workflow for an unknown page: 1. `ax html URL --outline` → find the repeating block (e.g. 50x div.card) 2. `ax html URL --locate 'landmark text'` → get the selector path 3. `ax html URL '.card' --count` → confirm 4. `ax html URL '.card' --row 'title=a, href=a@href'` → extract Examples: ax html page.html '.lesson a' --attr href ax html page.html '.lesson' --row 'title=a, href=a@href, level=.cefr' ax html page.html 'table.wikitable' --table --where 'Population > 1000000' ax html https://site.com/ --outline ax html https://site.com/ --locate 'BurgerBarn' ## ax json / ax yaml — query JSON or YAML with a jq-subset path language ax json [path] [options] ax yaml [path] [options] # multi-doc YAML → array of docs Path syntax: . .key .a.b.c .["weird key"] .items[] .items[0] .[0] --where filter an array result (see expressions below) --keys list keys (object) or indices (array) --len length of result --raw print scalars as bare lines instead of JSON Examples: ax json data.json '.items[].name' --raw ax json api.json '.data.users[]' --where 'active == true' --raw ax yaml docker-compose.yml '.services[].image' --raw ax yaml .github/workflows/ci.yml '.jobs' --keys ## ax text — line-oriented text processing ax text [options] --grep keep lines matching a regex --invert with --grep, keep non-matching lines -i case-insensitive --extract emit each regex match, not lines (grep -o) --freq with --extract, frequency table (uniq -c, sorted desc) --count count of matches only --head / --tail Examples: ax text app.log --grep 'ERROR|WARN' --count ax text style.css --extract '#[0-9a-fA-F]{6}' --freq ## ax enc — encode / decode / hash ax enc [input] # input from arg or stdin base64 | url | hex encode; decode with -d (base64url accepted) jwt decode header+payload (no verification), exp/iat/nbf also shown as ISO times sha256 | sha1 | md5 hex digest Examples: ax enc base64 -d 'aGVsbG8=' ax enc jwt "$TOKEN" ax enc sha256 'input' ## ax time — epoch / ISO / human time ax time [input] [--tz ] Input: (omitted)|now, epoch seconds, epoch millis, or any parseable date. Output: {epoch, epoch_ms, iso, local, relative} + optional --tz zone. Examples: ax time 1783332078 ax time '2026-07-06T19:00+09:00' --tz America/Los_Angeles ## --where expressions (json, yaml, html --row/--table) A tiny safe expression language — not eval, no side effects: price > 100 && stock != 0 name ~ /^Lesson/i || level == "A1" !archived && tags.length >= 2 Operators: == != > >= < <= ~ (regex) !~ && || ! () Values: numbers, 'strings', /regex/flags, true/false/null, dot.paths, .length String numbers compare numerically ("25000" > 100 is true). ## Etiquette for agents - One probe per shell call; no `echo "==="` banners — the call labels itself. - Respect the default cap; add `--all` only when needed. - Read the stderr note/hint before retrying anything. - Prefer `--row`/`--table` over N separate extractions + manual zipping. - Prefer `--outline`/`--locate` over dumping raw HTML into context. - Prefer `--where` over piping to another filter pass.