The GitHub fallback for curl was a 404 written untested: curl tags its
releases with underscores in the version, 8.22.0 becoming curl-8_22_0,
while the asset name keeps the dots. Derive the tag from the version
rather than assuming the two match. Verified by making the primary host
unresolvable and letting the fallback carry the fetch; the tarball
passes xz -t and extracts to curl-8.22.0/.
The README troubleshooting section was a definition list. It is now a
three-column table, matching the reference sections elsewhere in the
file, with a row added for make static-deps failing to download, which
had no coverage despite the script fetching two tarballs.
Two of its entries were wrong:
- One documented "cannot find -lcares", which the Makefile can no longer
produce. The recipe passes the explicit path static-deps/libcares.a
and the prerequisite check fails first with its own message. Verified
by moving the archive aside and reading what make actually says.
- The ares_* entry gave one diagnostic for two causes that read opposite
ways. `nm -u static-deps/libcurl.a | grep -c ares_` returns zero when
the archive was built without c-ares, and nonzero when c-ares is in
there and the failure is link order. Split them apart.
main.c is the whole agent: a readline REPL that talks to any OpenAI-compatible
/chat/completions endpoint and exposes exactly one tool, bash(command). Commands
run through the user's shell with stdout and stderr merged, a hard timeout, and
a process-group kill; the output and an exit marker go back to the model until
it answers without calling a tool.
make static-deps builds curl and c-ares from source into static-deps/, so
`make static` can link a fully static binary on distros that get in the way: the
distro libcurl.a drags in libpsl, brotli, zstd and nghttp2, whose static objects
are GCC 14 LTO bytecode a newer linker cannot read, and a minimal system often
ships no libcares.a at all.
Two details worth keeping in mind when editing mkstaticdeps.sh. curl 8.22 takes
--enable-ares=PREFIX rather than the older --with-cares, and it only warns
about options it does not recognise, so the wrong spelling turns off async DNS
in silence instead of failing. And link order is load-bearing: libcares.a has
to come after libcurl.a or ares_* stays undefined.