| name | weftos-build-deploy |
| description | Build, test, publish, and deploy WeftOS across all channels (GitHub Releases, crates.io, npm, Docker, Homebrew) |
| triggers | ["deploy","release","publish","build and deploy","cut a release","publish crates","push to npm","docker build","tag and release"] |
WeftOS Build & Deploy Skill
You are the WeftOS release engineer. You handle builds, tagging, publishing, and deployment across all distribution channels.
Project Identity
- Repo:
weave-logic-ai/weftos (GitHub)
- Binaries:
weft (CLI), weaver (operator), weftos (kernel daemon)
- Naming:
clawft-* = framework crates, weftos = product facade
- Workspace version: single version in
[workspace.package] in root Cargo.toml
Distribution Channels
| Channel | Package | Registry/Location |
|---|
| GitHub Releases | 3 binaries x 5 platforms + installers | weave-logic-ai/weftos/releases |
| crates.io | 10 crates (8 clawft-, 2 weftos-) | crates.io |
| npm | @weftos/core (WASM browser module) | npmjs.com |
| Docker | ghcr.io/weave-logic-ai/weftos | GHCR (multi-arch amd64+arm64) |
| Homebrew | clawft-cli.rb, clawft-weave.rb, weftos.rb | weave-logic-ai/homebrew-tap |
Secrets & Auth
| Secret | Location | Purpose |
|---|
HOMEBREW_TAP_TOKEN | GitHub repo secret | Push formulae to homebrew-tap |
CRATES_API_TOKEN | .env (local) | cargo publish to crates.io |
NPM_TOKEN | .env (local) | npm publish to npmjs.com (needs "Bypass 2FA" permission) |
NEVER commit .env or expose tokens in logs.
Common Tasks
Full Release (new version)
This is the most common operation. It publishes everywhere.
-
Bump version:
- Edit
[workspace.package] version in root Cargo.toml
- Run
cargo check --workspace to verify
- Commit:
git add Cargo.toml Cargo.lock && git commit -m "chore: bump workspace version to X.Y.Z"
- Push:
git push origin master
-
Tag (triggers cargo-dist automatically):
git tag vX.Y.Z
git push origin vX.Y.Z
-
Monitor (~12-14 min for all platforms):
gh run list --repo weave-logic-ai/weftos --limit 2
gh run view <RUN_ID> --repo weave-logic-ai/weftos
-
Verify release:
gh release view vX.Y.Z --repo weave-logic-ai/weftos
-
Publish to crates.io (manual, not automated by CI):
source .env && cargo login "$CRATES_API_TOKEN"
Publish in dependency order with ~10 min gaps (crates.io rate limit for new crates):
1. clawft-types (leaf)
2. clawft-platform (-> types)
3. clawft-plugin (leaf)
4. clawft-llm (-> types)
5. exo-resource-tree (leaf)
6. clawft-core (-> types, platform, llm, plugin)
7. clawft-kernel (-> core, types, platform, plugin, exo-resource-tree)
8. weftos (-> all above)
Command: cargo publish -p <crate-name>
Rate limit: ~1 new crate per 10 min window. Existing crate version bumps are not rate-limited.
-
Publish to npm (manual):
source .env
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
wasm-pack build crates/clawft-wasm --scope weftos --target web --features browser
Fix package.json in crates/clawft-wasm/pkg/:
- Ensure
name is @weftos/core
- Ensure
repository.url is https://github.com/weave-logic-ai/weftos
- Ensure
version matches the release
cd crates/clawft-wasm/pkg && npm publish --access public
Patch Release (hotfix)
Same as full release but only bump patch version (e.g., 0.1.1 -> 0.1.2).
Re-tag (if a release fails mid-pipeline)
git tag -d vX.Y.Z
git push origin :refs/tags/vX.Y.Z
git tag vX.Y.Z
git push origin vX.Y.Z
Publish Only crates.io (no binary release)
If you only changed library code and need to update crates.io without a binary release:
source .env && cargo login "$CRATES_API_TOKEN"
cargo publish -p <crate-name>
No tag needed. Version in Cargo.toml must be bumped and not already published.
Publish Only npm (WASM update)
source .env
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
wasm-pack build crates/clawft-wasm --scope weftos --target web --features browser
cd crates/clawft-wasm/pkg && npm publish --access public
Verify Installation
gh release download vX.Y.Z --repo weave-logic-ai/weftos \
--pattern 'clawft-cli-aarch64-unknown-linux-gnu.tar.gz' --dir /tmp/test
tar xzf /tmp/test/clawft-cli-*.tar.gz -C /tmp/test
/tmp/test/clawft-cli-*/weft --version
/tmp/test/clawft-cli-*/weft status
/tmp/test/clawft-cli-*/weft tools list
brew install weave-logic-ai/tap/clawft-cli
weft --version
docker pull ghcr.io/weave-logic-ai/weftos:X.Y.Z
docker run --rm ghcr.io/weave-logic-ai/weftos:X.Y.Z --version
cargo install weftos
weftos --version
npm info @weftos/core version
What cargo-dist Does Automatically (on tag push)
- Plan — reads
[workspace.metadata.dist], resolves targets
- Build — compiles 3 binaries on 5 platforms:
x86_64-unknown-linux-gnu (~5 min)
aarch64-unknown-linux-gnu (~5 min, cross-compiled)
x86_64-apple-darwin (~14 min, slowest)
aarch64-apple-darwin (~7 min)
x86_64-pc-windows-msvc (~10 min)
- Global artifacts — SHA256 checksums, shell + PowerShell installers
- Host — creates GitHub Release with all artifacts
- Homebrew — pushes
.rb formulae to weave-logic-ai/homebrew-tap
- Announce — marks release as published
Docker runs in parallel via release-docker.yml (~2h for multi-arch QEMU build).
crates.io Dependency Graph
weftos-rvf-crypto 0.3.0 (our ML-DSA fork — depends on rvf-types)
weftos-rvf-wire 0.2.0 (our fork — depends on rvf-types 0.2)
rvf-types 0.2.0 (upstream ruvnet)
rvf-runtime 0.2.0 (upstream ruvnet)
ruvector-cluster 2.0.6 (upstream ruvnet)
ruvector-raft 2.0.6 (upstream ruvnet)
ruvector-replication 2.0.6 (upstream ruvnet)
cognitum-gate-tilezero 0.1.1 (upstream ruvnet)
clawft-types 0.1.x (leaf)
clawft-platform 0.1.x (-> clawft-types)
clawft-plugin 0.1.x (leaf)
clawft-llm 0.1.x (-> clawft-types)
exo-resource-tree 0.1.x (leaf)
clawft-core 0.1.x (-> types, platform, llm, plugin)
clawft-kernel 0.1.x (-> core, platform, types, plugin, exo-resource-tree,
weftos-rvf-crypto, weftos-rvf-wire, rvf-types,
rvf-runtime, ruvector-*, cognitum-gate-tilezero)
weftos 0.1.x (facade -> kernel, core, types, platform, exo-resource-tree)
Cargo.toml Key Sections
Workspace version (must match tag)
[workspace.package]
version = "X.Y.Z"
repository = "https://github.com/weave-logic-ai/weftos"
Workspace deps (version + path for publishability)
clawft-types = { version = "X.Y.Z", path = "crates/clawft-types", default-features = false }
cargo-dist config
[profile.dist]
inherits = "release"
[workspace.metadata.dist]
cargo-dist-version = "0.31.0"
ci = "github"
targets = [
"x86_64-unknown-linux-gnu",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"aarch64-apple-darwin",
"x86_64-pc-windows-msvc",
]
installers = ["shell", "powershell", "homebrew"]
tap = "weave-logic-ai/homebrew-tap"
publish-jobs = ["homebrew"]
github-attestations = true
Gotchas & Hard-Won Knowledge
-
Tag must match workspace version — v0.1.1 tag requires version = "0.1.1" in Cargo.toml. cargo-dist errors with "nothing to Release" otherwise.
-
[profile.dist] must exist — cargo-dist uses this profile, not release. Missing = "profile dist is not defined" error.
-
repository URL in Cargo.toml — cargo-dist bakes this into installer shell scripts as the download URL. Wrong URL = installer downloads from nonexistent repo. Always verify after repo renames.
-
Windows builds — clawft-weave (weaver) daemon uses Unix sockets and nix signals. All gated behind #[cfg(unix)]. Windows gets stub DaemonClient::connect() that returns None (query commands fall through to ephemeral kernel). The nix crate is under [target.'cfg(unix)'.dependencies].
-
LICENSE file — must exist at repo root with exact name LICENSE. The glob LICENSE* in cargo-dist include config fails because cargo-dist treats it literally.
-
crates.io rate limit — max ~1 new crate per 10-minute window. Version bumps of existing crates are not limited. Plan publish order accordingly.
-
npm 2FA — requires granular access token with "Bypass 2FA on publish" enabled for the @weftos scope. Regular tokens get 403.
-
Docker multi-arch — takes 30-60 min (arm64 via QEMU emulation). Runs in parallel with cargo-dist, doesn't block the binary release.
-
weftos-rvf-crypto / weftos-rvf-wire — our forks of upstream rvf-crypto / rvf-wire published under new names because we don't own the upstream crate names on crates.io. If upstream catches up with ML-DSA support, we can switch back to their names.
-
Workspace deps need version + path — { version = "X.Y.Z", path = "crates/..." } for crates.io publishability. Path alone works locally but cargo publish rejects it.
Docker
- Base image:
gcr.io/distroless/cc-debian12 (no shell, minimal attack surface)
- Multi-stage build: cargo-chef for dep caching -> builder -> distroless runtime
- Platforms: linux/amd64, linux/arm64
- Tags:
X.Y.Z, X.Y, X, latest
- Health check:
weft status (exec form, no shell)
- Registry:
ghcr.io/weave-logic-ai/weftos
Platform Support
| Platform | Binary | Docker | WASM | Status |
|---|
| Linux x86_64 | Yes | Yes | - | Shipping |
| Linux aarch64 | Yes | Yes | - | Shipping |
| macOS Intel | Yes | - | - | Shipping |
| macOS Apple Silicon | Yes | - | - | Shipping |
| Windows x86_64 | Yes | - | - | Shipping (weaver daemon limited) |
| Browser | - | - | Yes | Shipping (@weftos/core) |
| Linux x86_64 musl | Planned | - | - | v0.2 |
| Linux aarch64 musl | Planned | - | - | v0.2 |
| Windows ARM | Planned | - | - | v0.2 |
| WASI (wasip2) | Planned | - | - | v0.2 |