Scripting & CI (non-interactive use)
gth ask and gth exec are the non-interactive verbs: they take input from arguments, files, or
a pipe, stream the result to stdout, and set the process exit code (0 on success, 1 on error).
That makes them safe to call from a shell script or CI step — capture the output, branch on $?,
and nothing waits for a human.
Pick the right command
Section titled “Pick the right command”ask/exec are the one-shot verbs this page covers, but they are not the only non-interactive
ones — and a shell loop around them is usually the wrong tool:
ask/exec— one prompt, one answer, exit0/1: the rest of this page.batch— the same prompt over many rows or models; don’t write the fan-out loop yourself: Fan out one prompt over inputs and models.eval— grade the answers and gate CI on the result (three-way exit code): Evaluate your agent.workflow— several agent calls with logic between them, in JS; don’t pipegthintogthfrom bash: Orchestrate agent calls from a script.review/pr— content-gate a diff or pull request: Review code and pull requests.
Which binary name in scripts
Section titled “Which binary name in scripts”gth, gsloth, and gaunt-sloth are the same binary. Interactively, type the short one — but in
CI and checked-in scripts, prefer the long gaunt-sloth form: it self-documents in CI logs
(nobody has to ask what gth is), and an AI agent later editing the script won’t “auto-correct”
the unfamiliar gth to gh — a real, observed failure mode with the short name.
The main use case: diagnose a build log from a script
Section titled “The main use case: diagnose a build log from a script”Goal: a CI step pipes a failing build log into gth, captures the diagnosis, and stops the script
if gth itself errored (network/provider failure) rather than continuing with empty output.
export ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY"
diagnosis=$(gth ask "Summarise the root cause of this build failure in two sentences." < build.log)status=$?
if [ "$status" -ne 0 ]; then echo "gth ask failed (exit $status)" >&2 exit "$status"fi
echo "$diagnosis"gth ask combines everything it is given, in order: the content of any -f files, then whatever
is piped on stdin, then the [message] argument. Here the message frames the task and build.log
arrives on stdin, so the model sees both. At least one of the three (file, stdin, or message) is
required — with none, ask errors out.
status is 1 when the run failed (a provider error, or the process couldn’t produce an answer)
and 0 when it succeeded. That is a signal about the run, not a verdict on the content — to
fail a job when the content itself is bad (a review that doesn’t pass, an eval assertion that
fails), see Review code and pull requests and
eval.
Deterministic runs with exec
Section titled “Deterministic runs with exec”When the prompt is fixed and you want the same input to give as close to the same output as the
provider allows, use exec instead of ask. exec runs a markdown “prompt-executable” and, unlike
ask, cannot be interrupted with ESC (there is no interactive user). Pass -t 0 to pin the sampling
temperature to its most deterministic setting:
gth exec -m "List the section headings in CHANGELOG.md as a bullet list." -t 0 < CHANGELOG.mdThe script itself resolves in precedence order: -m/--message inline text wins, then a [script]
file path, then stdin. So a checked-in prompt file is just as valid a scripted invocation:
gth exec scripts/release-notes.md -f CHANGELOG.md-m and a positional [script] path are mutually exclusive — pass one or the other, not both.
Writing the output to a file
Section titled “Writing the output to a file”ask honours the global -w/--write-output-to-file. Pass a filename to write there, or true for
a timestamped gth_<timestamp>_ASK.md (under .gsloth/ if that directory exists, otherwise the
project root):
gth -w diagnosis.md ask "Summarise the root cause of this build failure." < build.logexec currently writes no report file — -w has no effect on it (a known limitation with a fix
tracked). Its result streams to stdout, so to save an exec result, redirect it:
gth exec scripts/release-notes.md > RELEASE_NOTES.mdStdin in CI
Section titled “Stdin in CI”ask and exec read piped stdin, so on a non-TTY with an open-but-idle stdin they wait for EOF.
If a scripted gth ask "…" that takes its input from arguments (no pipe) appears to hang in CI,
close stdin (gth ask "…" < /dev/null) or pass the global --no-pipe flag to skip the wait.
Examples
Section titled “Examples”# Capture a one-line answer into a shell variable, branch on the exit codeanswer=$(git --no-pager log -1 --stat | gth ask "Summarise this commit in one sentence.")[ $? -eq 0 ] && echo "$answer"
# Deterministic inline prompt, result redirected to a filegth exec -m "Rewrite README.md's intro as three bullet points." -t 0 < README.md > intro.md
# Run a checked-in prompt script with an extra context filegth exec scripts/lint-summary.md -f eslint-report.json
# Pipe a prompt script on stdincat scripts/triage.md | gth execRelated
Section titled “Related”- Fail a CI job when a review or PR doesn’t pass (content gating, not just run success): Review code and pull requests.
- Every
ask/execflag, the exit-code table, and output-file naming: Commands. - Grade your whole agent with pass/fail assertions and a three-way exit code in CI: Evaluate your agent.