Install from a release tag
How spezl (or anyone) depends on the publish = false crates:
- Pin a release tag, nothing else.
etalk = { git = "https://github.com/Niach/exponential", tag = "etalk-v0.2.4" }. Neverbranch, never master; arevonly to try an unreleased fix, and only until the next tag. Every crate of one lib uses the SAME tag. - One tag = one version of every crate of the lib. The release workflow
refuses a tag that disagrees with any of the crates’
version; tags are cut from master after the bump PR merged, and a tag is never moved or deleted (consumers’Cargo.lockpins its commit). - Semver, 0.x style. A breaking API change bumps the minor (
0.2→0.3), anything else the patch; the lib’s CHANGELOG / GitHub release says what broke. A gpui revision change is breaking for the gpui crates (etalk-gpui, likeeui-gpui). - No path escapes the checkout. A consumable crate’s path dependencies
are crates of its OWN lib only, never an app crate (
ui,theme,domain,sync,api,app, …): gated per crate (tests/dependency_gate.rsineagentandetalk-gpui). Fixtures come in withinclude_str!frompackages/, which a git checkout carries. Another lib comes in through ITS release tag (#EXP-1460):etalk-gpuitakeseui-core/eui-gpuiwithgit = "https://github.com/Niach/exponential", tag = "eui-v…"andepilot/epilot-screenatepilot-v…, andepilot/epilot-screentakeemcpatemcp-v…(#EXP-1492); a path dependency would resolve inside the etalk tag’s checkout and hand a consumer a second eui-gpui whose types never unify with its own. The one exception is eCore (ecore, types only, no tag yet):emcptakes it by path (#EXP-1517), so it resolves inside the emcp tag’s checkout. The desktop workspace’s[patch."https://github.com/Niach/exponential"]builds them from the local crates. A consumer ofetalk-gpuipins eUI and ePilot at the tagsetalk-gpui’s Cargo.toml names (same URL, same tag): Cargo then sees one source and keeps one copy. - gpui consumers copy two things (a dependency’s
[patch]and lock never reach its consumers): the ztracing patch and the zed pin, exactly asapps/desktop/crates/eui-gpui/README.md“gpui revisions” says. The non-gpui crates (etalk,etalk-codec,etalk-engine,epilot,epilot-screen,emcp,eagent) need neither. - Proven per release. Each lib’s release workflow runs
scripts/libs/git-consumer-smoke.sh <lib> <commit>: a scratch crate outside this workspace depends on every crate of the lib throughgit+ the commit, with the patch and the lock copied, and must build. eTalk’s run also pins eUI and ePilot at the tagsetalk-gpuinames, like a consumer of all three, and fails on a second copy of any crate of this repo (cargo tree -d). Run it locally before tagging.
| lib | tag | crates under it | workflow |
|---|---|---|---|
| eTalk | etalk-v* |
etalk, etalk-codec, etalk-engine, etalk-crispasr, etalk-wakeword, etalk-gpui (+ npm @exponential_app/etalk, SwiftPM ExponentialTalk, Maven at.exponential:etalk) |
release-etalk.yml |
| ePilot | epilot-v* |
epilot, epilot-screen |
release-epilot.yml |
| eMCP | emcp-v* |
emcp |
release-emcp.yml |
| eAgent | eagent-v* (+ agent-runtime-v* for one release) |
eagent, exponential-agent-runtime (the shim, one release) |
release-eagent.yml |
Every new name was checked free on 2026-10-30: crates.io eui-core, eui-gpui,
enet-core, etalk, epilot, and npm @exponential_app/eui*, @exponential_app/enet,
@exponential_app/etalk.