| name | release-soothe |
| description | Release Soothe packages (soothe, soothe-cli, soothe-daemon, soothe-sdk, soothe-plugins) and language clients (Python, TypeScript, Go, Rust). Handles version bumping, changelog maintenance, git tagging, publishing (PyPI / npm / crates.io / Go modules), and monorepo submodule bumps. Use when preparing a new release, hotfix, client SDK release, or when the user asks to cut a release. |
Release Soothe
Manage Soothe releases: version bumps, changelog updates, git tags, registry
publishing, and language-client releases (separate repos under client/).
When to Use
- User asks to release a new version (
v0.8.0, v0.7.17, etc.)
- User asks to prepare release notes or update CHANGELOG.md
- User asks to publish packages to PyPI / npm / crates.io
- User asks to release a language client (
soothe-client-python, Go, TS, Rust)
- User asks how to bump versions or tag a release
Version Convention
Soothe uses Semantic Versioning (semver):
MAJOR (v1.0.0): Breaking changes in public API
MINOR (v0.8.0): New features, backward-compatible
PATCH (v0.7.17): Bug fixes, backward-compatible
Version format: vMAJOR.MINOR.PATCH (e.g., v0.7.16)
Changelog Principles
The project follows Keep a Changelog format.
Section Order
Always maintain this order:
Added — New features
Changed — Changes to existing functionality
Deprecated — Soon-to-be removed features
Removed — Removed features
Fixed — Bug fixes
Security — Security-related changes
Entry Guidelines
- Use imperative mood:
Added not Added new feature or Adds
- Be specific:
Fixed token tracking in daemon/TUI streams not Fixed bugs
- Group related changes: Combine related fixes under one bullet
- No internal references: Never expose IG-XXX/RFC-XXX in user-facing text
- Timestamp format:
YYYY-MM-DD (e.g., 2026-07-13)
Example Entry
## [v0.7.17] - 2026-07-13
### Added
- Skillify embedding resilience with automatic retry and fallback
### Changed
- Pass 1 continuation routing fixes with response-language detection
### Fixed
- Token tracking in daemon/TUI streams
Monorepo Core Release Workflow
1. Determine Version
cat VERSION
rg '^version = ' packages/soothe-sdk/pyproject.toml
rg '^version = ' packages/soothe-plugins/pyproject.toml
2. Update CHANGELOG.md
Insert new version block at top (below header, above existing entries):
## [vX.Y.Z] - YYYY-MM-DD
### Added
- (new features)
### Changed
- (modifications)
### Fixed
- (bug fixes)
[Compare with previous version]: https://github.com/mirasoth/soothe/compare/vX.Y.W...vX.Y.Z
3. Update Version Files
Synchronize the monorepo VERSION for core packages. soothe-sdk and soothe-plugins keep standalone version = "..." in their own pyproject.toml and are only bumped when those packages intentionally change:
echo "X.Y.Z" > VERSION
4. Commit, Tag, Publish
git add VERSION CHANGELOG.md packages/*/pyproject.toml
git commit -m "Release vX.Y.Z"
git tag -a vX.Y.Z -m "Release vX.Y.Z"
git push origin main --tags
./scripts/build.sh
twine upload dist/soothe-*.whl dist/soothe-*.tar.gz
Or use the release workflow in .github/workflows/.
Package Inventory (monorepo)
| Package | Directory | Version source | Publishes |
|---|
| soothe-core | packages/soothe/ | Root VERSION | PyPI: soothe |
| soothe-cli | packages/soothe-cli/ | Root VERSION | PyPI: soothe-cli |
| soothe-daemon | packages/soothe-daemon/ | Root VERSION | PyPI: soothe-daemon |
| soothe-sdk | packages/soothe-sdk/ | Own pyproject.toml | PyPI: soothe-sdk |
| soothe-plugins | packages/soothe-plugins/ | Own pyproject.toml | PyPI: soothe-plugins |
Language Client Releases
Clients live in separate git repos, checked out as submodules under client/.
Each client has its own version line — do not tie them to monorepo VERSION.
Docs hub: docs/wiki/clients.md.
When to release a client
- Wire / event / RPC surface changes that apps consume
- Compatibility fixes for a new daemon /
soothe-sdk constraint
- Feature parity across languages (prefer releasing all affected clients together)
Client release checklist (per language)
Work inside the submodule (its own git remote):
- Bump version in the source listed above (and any mirrored handshake constant).
- Update
CHANGELOG.md (Keep a Changelog; no IG-/RFC- in user-facing notes).
- Verify locally:
make verify (or language equivalent: cargo test, etc.).
- Commit on
main: Release vX.Y.Z (or package-appropriate message).
- Tag annotated:
git tag -a vX.Y.Z -m "Release vX.Y.Z".
- Push branch + tag:
git push origin main && git push origin vX.Y.Z.
- GitHub Release (triggers
.github/workflows/release.yml):
export GH_TOKEN="${GITHUB_PAT:-$GH_TOKEN}"
gh release create "vX.Y.Z" --title "vX.Y.Z" --notes "$(cat <<'EOF'
## Changed
- …
**Full Changelog**: https://github.com/mirasoth/soothe-client-<lang>/compare/vA.B.C...vX.Y.Z
EOF
)"
Publish targets by workflow:
| Client | On release: published |
|---|
| Python | PyPI trusted publishing (soothe-client-python) |
| TypeScript | npm trusted publishing (@mirasoth/soothe-client) |
| Go | Verify only (ClientVersion must match tag); consumers use the git tag |
| Rust | cargo publish (soothe-client, needs CARGO_REGISTRY_TOKEN) |
After client release: bump monorepo submodule
Back in the soothe monorepo:
cd client/<lang>
git fetch origin && git checkout <release-sha-or-main>
cd ../..
git add client/<lang>
git commit -m "chore(client): bump <lang> submodule to vX.Y.Z"
git push origin main
Compatibility pitfalls
soothe-sdk pin: If core bumps soothe-sdk major (e.g. >=1.0.0) but a published client still requires soothe-sdk<1.0.0, Docker / install resolution can fail. Release a matching client patch before or with the Docker image rebuild.
- Event / subagent renames: Keep wire constants aligned across all four clients (
explorer, deep_research, …) and release each language that still ships legacy names.
- Go:
ClientVersion in protocol.go must equal the release tag (CI enforces this).
Quick version checks
cat client/python/VERSION
node -p "require('./client/typescript/package.json').version"
rg 'const ClientVersion' client/go/protocol.go
rg '^version = ' client/rust/Cargo.toml
Troubleshooting
- Version mismatch: Root
VERSION drives soothe/cli/daemon only; do not expect soothe-sdk, soothe-plugins, or clients to match unless you bump them
- Changelog merge conflicts: Preserve existing entries; add new version at top
- PyPI / npm upload fails: Verify OIDC trusted publishing env and that the version is not already published
- crates.io publish fails: Check
CARGO_REGISTRY_TOKEN and that Cargo.toml version is unique
- Go release “fails” publish: Expected — Go releases verify + tag; no artifact upload
- Docker build fails after core release: Check client ↔
soothe-sdk version constraints; release a client patch if needed
- Missing changes: Search git log since last tag:
git log v0.7.15..HEAD --oneline
Quick Reference
| Task | Command |
|---|
| Check monorepo version | cat VERSION |
| Check soothe-sdk version | rg '^version = ' packages/soothe-sdk/pyproject.toml |
| Check soothe-plugins version | rg '^version = ' packages/soothe-plugins/pyproject.toml |
| Check client versions | See “Quick version checks” above |
| List recent tags | git tag -l 'v0.8.*' | tail -5 |
| View tag details | git show v0.8.3 |
| Compare versions | git log v0.8.2..v0.8.3 --oneline |
| Build monorepo packages | ./scripts/build.sh |