Expand description
A command’s own output: the tail of the file the CLI streams it to.
The CLI’s local-bash tasks write the command’s stdout to a file on disk
rather than sending it over the wire (confirmed in
~/Projects/forge/.claude/skills/claude-cli-upgrade/reference-captures/monitor.jsonl),
so the tail is a file read. The readers are the transport - which
resolves the path from its held conversation and answers a view’s
ReadCallOutput with the result - and the views that hold a path already
(a view tails a Monitor’s file on its own tick).
Two ways a path is found, and the ending frame’s own word wins when both
exist: task_notification.output_file names the file when the task ends,
and until then the path is composed from the task id the wire carries
(compose_task_output_path, under task_output_base - both crate-internal,
so named rather than linked). Neither reads the launch sentence: forge
resolves the file structurally, never from prose.
Constants§
- CALL_
OUTPUT_ MAX_ LINES - How many lines of a call’s output a
ReadCallOutputanswers with. - TAIL_
WINDOW_ BYTES - Largest slice of the file read at a time. Output files grow without bound (cargo build, npm install) and this runs inline on a view’s own tick, so the read seeks to within this window of the end rather than reading the whole file each time. 64 KiB comfortably holds the last few lines at any realistic line length.
Functions§
- read_
output_ file_ tail - Read the last
max_lineslines ofpathinto aVecordered oldest-first. ReturnsNoneon any read error (file missing, permission denied, a read that failed) so the caller can distinguish “could not read, keep the tail already held” from “the file is genuinely empty”. The empty-file case returnsSome(vec![]). - resolve_
call_ output_ path - The file a call’s output went to, from the frames a conversation carries.