All notable changes to this project are documented here. The format follows Keep a Changelog, and this project adheres to Semantic Versioning.

[0.1.1] - 2026-08-22

First external review of this package — every sibling had between one and four rounds; this one shipped with none, and the round found two real defects.

Fixed

  • A broken tool was reported as installed, with a version read out of its own error message. Exit status was ignored whenever the default pattern found any dotted number in the output — documented as deliberate, and wrong: failure output routinely contains one. A Homebrew ffmpeg dying in the dynamic loader reported {:ok, "265.215.0"}, parsed from libx265.215.dylib in the dyld error, and satisfied >= 4.0.0. A non-zero exit is now an error, {:check_failed, status, output}. Tools that genuinely report their version with a non-zero exit — ssh -V exits 255 — declare allow_nonzero: true.
  • A version command that waited on stdin hung the check forever. System.cmd/3 has no timeout, and the moduledoc itself places checks on a request path behind an expiring cache. The subprocess now runs under a Port with a ten-second default (:timeout per tool), is killed by OS pid on expiry rather than abandoned, and is unlinked so a trapping caller never receives its EXIT as a stray handle_info.
  • Output accumulation is capped at 64 KB, keeping the head. A misconfigured executable that streams (yes measured 2.1 GB in one second through a port) filled the heap for the whole timeout budget. The head is kept — the opposite end from a converter's error tail — because a version banner sits at the start of output.
  • install: "one bare string" crashed install_hint/1 — but only on the failure path, so it survived every machine where the tool existed. Now accepted as [default: hint].

Documented

  • An "Awkward tools" section: ssh (allow_nonzero), elixir (the OTP banner's erts version precedes "Elixir x.y.z", so the default pattern reads the wrong number — :pattern fixes it), and slow-first-run tools (:timeout).

[0.1.0] - 2026-08-21

Initial release.

Added

  • use CliDeps with a tool/2 macro for declaring external command-line dependencies.
  • check/1, check!/1, available?/1, explain/1, report/0, all_available?/0, invalidate/1.
  • Version requirements via Version requirement strings, with extraction from real-world --version output.
  • Per-OS install hints (:macos, :linux, :windows, :default) surfaced in error messages.
  • Result caching in :persistent_term with a one-hour default TTL, monotonic clock, and per-tool or global invalidation.
  • mix cli_deps.check task that exits non-zero when anything is missing, for use as a CI or container-build gate.
  • Compile-time validation of version requirements, regex patterns, and duplicate tool names.