lets show
Reads files, line ranges, anchors and symbols. Several targets in one call, so an agent that needs two files or two functions gets both in one round trip instead of two.
lets show [OPTIONS] <TARGETS>...
What it does
Renders each target as a numbered block with a header naming the range shown out of the file’s
total, and a footer summarizing the whole call. Replaces cat, head, sed -n and the Read
tool. See target grammar (path, path:40, path:40-80,
path@'regex', path#name).
Flags
| Flag | Meaning | Default |
|---|---|---|
--window <N> |
cap lines shown per whole-file target | 200 |
--all |
disable the window; print a cost line before the content | off |
-A <N> |
lines of context after a :line or @'regex' target |
— |
-B <N> |
lines of context before | — |
-C <N> |
lines of context on both sides | — |
--no-numbers |
omit line numbers, for content piped onward | off |
--json |
one JSON object on stdout | off |
--jsonl |
one JSON object per target, plus a trailing stats/omitted record | off |
--budget <N> |
shape the whole answer to ~N tokens, trimming the largest target first | unset |
--max-bytes <N> |
refuse (exit 4) if content exceeds N bytes and no --budget given |
65536 |
--max-file-bytes <N> |
files larger than this are refused | 8388608 |
--no-ignore |
do not honor .gitignore (only matters when a target resolves through a directory scan) |
off |
--allow-outside |
permit a target outside the working tree | off |
--no-check |
no effect on show (shared flag; show never runs a checker) |
off |
-q, --quiet |
(shared flag; show already prints only the footer plus content) |
off |
Output shape
── <target> (<start>-<end> of <total>[ · window W · :x-y not shown][ · via R])[ · crlf][ · non-UTF-8 lines …] · sha:xxxxxxxxxxxx
<n> <line text>
...
── showed <N> targets · <lines> lines[ · <cost>]
sha:is the first twelve hex of the file’s blake3 hash. Pass it back toedit --if sha:…to refuse the edit if the file changed since thisshow.- An empty file is a valid target, not a missing one: it exits 0 with a zero-line block.
- Invalid UTF-8 bytes are replaced lossily for display; the header names which lines held them
(
· non-UTF-8 lines 3, 7, at most five numbers then(+N more)). - A file whose dominant line ending is CRLF gets
· crlfin its header, since the rendered lines otherwise hide\rentirely. - A line over 1,000 bytes is cut at a UTF-8 boundary and marked with
…; the footer names how many lines this touched (N long lines cut). --json/--jsonlbodies carryomitted(the machine-readable footer) andstats(lines,bytes,tokens_est) alongside the target-specific fields. See –json and –jsonl.
Exit codes
| Exit | Slug | Means |
|---|---|---|
| 0 | — | shown |
| 1 | not_found |
a target matched nothing (other targets in the same call are still shown) |
| 2 | ambiguous |
a #name target matched more than one symbol; every candidate listed |
| 4 | over_budget |
content exceeded --max-bytes and no --budget was given |
| 6 | outside_tree |
the target is outside the working tree; pass --allow-outside |
| 7 | unsupported_file |
binary, hardlinked, or a directory given as a target |
| 64 | usage |
malformed command line |
Examples
Read several files in one call, numbered, with a size estimate:
$ lets show src/usage.ts src/config.ts
── src/usage.ts (1-13 of 13) · sha:75d31d847ffb
1 import { usageCap } from './config'
2
3 export function usage(id: string) {
4 const now = Date.now()
5 const cap = 10
...
13 }
── src/config.ts (1-2 of 2) · sha:4f49d457dfea
1 export const usageCap = 10
2 export const retries = 3
── showed 2 targets · 15 lines · ~74 tokens
Read exactly one function, found by parsing the file, instead of guessing a line range:
$ lets show src/usage.ts#usage
── src/usage.ts#usage (3-9 of 13 · via tree-sitter) · sha:75d31d847ffb
3 export function usage(id: string) {
4 const now = Date.now()
5 const cap = 10
6 if (!id) return
7 if (count(id) > cap) return
8 return total(id, now)
9 }
── showed 1 target · 7 lines · ~38 tokens
Find a line by regex and read context around it in the same call:
$ lets show "src/usage.ts@'const cap'" -A 2
── src/usage.ts@'const cap' (5-7 of 13) · sha:93b5daea8ace
5 const cap = 20
6 if (!id) return
7 if (count(id) > cap) return
── showed 1 target · 3 lines · ~16 tokens
A file over the default window is truncated and the footer names what was left out:
$ lets show big.ts
── big.ts (1-200 of 212 · window 200 · :201-212 not shown) · sha:e37232c09d01
...
── showed 1 target · 200 lines · :201-212 not shown
Two missing targets alongside one that resolved — the call still exits 1, but everything found is still printed:
$ lets show nope1.ts small.md:3 nope2.ts
? 1
── small.md:3 (3-3 of 15) · sha:[..]
3 One grammar every verb speaks.
── showed 1 target · 1 line · nope1.ts failed (not_found) · nope2.ts failed (not_found)
nope1.ts: No such file or directory (os error 2)
nope2.ts: No such file or directory (os error 2)
ERROR_CODE=not_found
An empty file is a normal result, not an error:
$ lets show empty.md
── empty.md · sha:af1349b9f5f9
── showed 1 target · 0 lines
Back to the top of lets show