v0.3.3
What changed
Say that the tag is what publishes a release
The publish workflow fires on a pushed version tag and on nothing else, so
a "Release X.Y.Z" commit left on main publishes nothing and reports no
failure, because no run happened. 0.3.2 sat unpublished on main for that
reason. Write the tag step down where a release is prepared, along with
how to confirm the release actually landed and how to retry one whose
later jobs failed.
CLAUDE.md stays a pointer rather than a second copy, but names the tag
rule directly, since that is the part that gets missed.
fix(herdr): let herdr see the agent Ditto launched
herdr works out which agent is in a pane from the name of that pane's
foreground process, and what that agent is doing from the title the tool
writes. Running the tool in a pseudoterminal costs it both answers at
once: the foreground process becomes ditto-cli, the tool moves to a
session of its own where herdr does not look, and the title arrives with
ditto:<profile> in front of it, which no longer matches rules anchored
to the first character — Claude Code's spinner rule is one. A pane
running Claude Code listed no agent at all, and every herdr agent
command lost sight of it.
Reporting the agent over herdr's socket does not answer this. A
lifecycle report is accepted and then ignored unless herdr detected the
agent itself, so the only thing that brings detection back is not being
in front of the tool. Under herdr Ditto therefore hands the terminal
straight over, exactly as DITTO_NO_PROXY already does, keyed off the
HERDR_PANE_ID that herdr sets in every pane it opens.
That leaves the profile unsaid, so it goes to herdr as display-only pane
metadata, which is the one kind herdr takes from a source that is not
the agent. Failure there is ignored down to herdr not being installed:
a label is worth much less than a launch, and Ditto is in the middle of
one. Nothing is reported about the agent, which is the detection Ditto
has just stepped out of the way of.
Distribute through npm, and let cargo binstall find the archives
Anyone running Claude Code or Codex already has npm, and it is the one
channel that reaches macOS, Linux and Windows at once. npm cannot publish
a single package carrying four platforms' binaries, so a release is five
of them: a wrapper every platform installs, and a binary package per
platform that npm passes over unless os and cpu match. The binary
packages publish first, because a wrapper reaching the registry ahead of
the optional dependencies it names is a version that installs and then
has nothing to run.
They are rendered from the archives the release published rather than
built a second time, on the same reasoning as the tap: what npm serves is
byte for byte what the releases page serves. The scope is there because
plain ditto-cli on npm belongs to an unrelated project.
cargo binstall needs no job at all, only the archive names written down,
since the ones it guesses are not the ones the workflow writes. It earns
its four lines: a source build compiles a bundled SQLite before it links
anything.
ditto-cli update would have shelled out to cargo for a copy cargo
cannot replace, leaving a second one in Cargo's bin directory and the
choice between them to whatever PATH reached first. The launcher says
how this copy arrived, and update names the npm command instead. --git
asks for a source build in so many words, and still gets one.
Install
brew install reyanshgupta/tap/ditto-cli # or: brew upgrade ditto-cli
npm install -g @reyanshgupta/ditto-cli@0.3.3
cargo binstall ditto-cli # or: cargo install ditto-cliThe archives below are the same binaries every channel installs; SHA256SUMS covers them.
Full Changelog: v0.3.2...v0.3.3