v0.3.2
What changed
Distribute through Homebrew, and say what the crate is for
The GitHub description and the crate description had fallen behind the
tools Ditto supports, naming only Claude Code and Codex. Both now say what
someone searching for this would type, and homepage points at the
project page rather than repeating repository.
Homebrew installs the binary the release workflow already builds, so it
needs no Rust toolchain. The formula lives in reyanshgupta/homebrew-tap
and is rendered there on each release from the template added here, with
checksums read from the release's own SHA256SUMS so it cannot describe
archives nobody published. A release does not fail when the tap token is
missing; the channel is optional and says so.
update only replaces a copy in Cargo's bin directory, so the README now
sends Homebrew installs to brew upgrade rather than leaving them to
discover a second, shadowed binary.
Render the Homebrew formula from the tooling, not the tagged tree
The tap job checked out the release tag, so its first real run — against
v0.3.1, a tag cut before the formula tooling existed — died with exit 127
looking for a render script that was not in that tree, and the tap has
been updated by hand ever since. The formula is rendered from a version
number and the checksums the release itself published, so it needs
nothing from the tag's own tree. Checking out the ref the workflow runs
from instead costs a tag push nothing, and lets a fix to the template be
re-run against a tag that predates the fix.
A tap that has never carried the formula would have gone quiet in the
same way for a different reason: git diff reports no change in a file
Git is not yet tracking, so the first release to a fresh tap would have
called itself up to date and pushed nothing. The guard now reads
git status --porcelain, which sees the untracked file.
Share what a profile is not signed in as
Pointing a tool at a profile's configuration directory moved everything
in it, not just the account. A profile started with none of the skills,
subagents, slash commands, hooks, or plugins its owner had set up once
and expected everywhere, so it was a different working environment
rather than the same one signed in as somebody else.
Those paths are now linked back to the user's own configuration by
shared.rs, for every tool: Claude Code, Codex, opencode and OMP. Links
rather than copies, so a skill written tomorrow is in every profile the
moment it is saved, with nothing to sync and no copies to drift apart.
Credentials and session state stay inside the profile, which is the
whole of what a profile keeps to itself.
What is shared is a named list rather than everything-but-the-known-
credentials. Learning about a new extension directory late costs a
missing feature; sharing a new credential file by accident would cost
the isolation the tool exists for, and only one of those is worth
risking. A test asserts no account-bearing name is ever on the list, and
another asserts that deleting a profile unlinks rather than following a
link out into the configuration it points at.
The status line was lost the same way for a different reason: the entry
names the profile it was installed for, so settings::copy skipped the
key outright and a profile's indicator had nothing to draw in front of.
What travels now is the status line underneath it, with the new
profile's own indicator wrapped around that, which is what the Alongside
outcome was built for and never reached. settings.json stays a copy
rather than a link because Ditto writes that key into it, and linking
would mean writing it into the user's own file.
Profiles made before this have real directories where the links go.
sync reports them and leaves them alone; --adopt points them at the
user's own, moving what was there aside rather than deleting it.
Install
brew install reyanshgupta/tap/ditto-cli # or: brew upgrade ditto-cli
npm install -g @reyanshgupta/ditto-cli@0.3.2
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.1...v0.3.2