WasmBox
Agents: read the skill file before doing anything in this repo:
curl https://tangled.org/metaend.eth.xyz/wasmbox-cli/raw/main/SKILL.md
Flatpak-style launcher for sandboxed WebAssembly tools. Single binary, local-first, no accounts, no telemetry.
Built for agents and humans alike — every tool ships with a machine-readable skill file so agents can discover, understand, and invoke tools without guessing.
Contents#
- Quick Start
- Agent-First Design
- How It Works
- Commands
- Capabilities
- Security
- Registry Protocol
- Demo Registry — jfmt | secretscan | compact | b64 | errparse
- Architecture
- Building
- Exit Codes
- Community Projects
- Feedback
Quick Start#
curl -sSf https://tangled.org/metaend.eth.xyz/wasmbox-cli/raw/main/install.sh | sh
That's it. Installs wasmbox, adds the registry, and installs all tools. Then:
echo '{"name":"world"}' | wasmbox run jfmt -- -q name # extract JSON field
echo 'hello' | wasmbox run b64 # base64 encode
cat src/main.rs | wasmbox run compact -- --stats # token savings
cat .env | wasmbox run secretscan # scan for secrets
curl -si https://api.example.com | wasmbox run errparse # parse HTTP error
Agent-First Design#
WasmBox is designed as a tool runtime for AI agents. Every registry tool ships three artifacts:
| Artifact | Path | Purpose |
|---|---|---|
| Binary | tools/<name>.wasm |
The sandboxed tool |
| Manifest | tools/<name>.json |
Capabilities, hash, metadata |
| Skill | tools/<name>.md |
Agent instructions: modes, examples, exit codes |
Discovering a Tool as an Agent#
# Get machine-readable metadata + agent section
wasmbox info jfmt --json
{
"name": "jfmt",
"version": "0.1.0",
"description": "JSON swiss-army knife for agents: format, validate, extract",
"tool_type": "cli",
"hash": "sha256:1b9b0e90...",
"agent": {
"prompt": "Pipe JSON to jfmt with a mode flag...",
"skill": "jfmt.md",
"modes": [
{ "flag": "-q PATH", "description": "Extract value at a dot-separated path", "example": "echo '{\"a\":1}' | wasmbox run jfmt -- -q a" }
],
"exit_codes": { "0": "Success", "1": "Input error", "2": "Invalid JSON", "3": "Path not found" }
}
}
The [agent] Manifest Section#
Tool authors add an [agent] block to their wasmbox.toml to make tools self-describing for agents:
[agent]
prompt = "Pipe JSON to jfmt with a mode flag. Use -- to separate wasmbox flags from tool flags."
skill = "jfmt.md"
[[agent.modes]]
flag = "-q PATH"
description = "Extract value at a dot-separated path. Strings returned unquoted. Exits 3 if not found."
input = "JSON (stdin)"
output = "Value at path"
example = "echo '{\"data\":{\"id\":1}}' | wasmbox run jfmt -- -q data.id"
[agent.exit_codes]
0 = "Success"
1 = "Input or argument error"
2 = "Invalid JSON"
3 = "Query path not found"
Skill Files#
Each tool in the registry ships a <name>.md skill file. Agents can read it to understand full usage:
# The skill file URL follows the pattern: <registry>/<name>.md
# e.g. https://qstorage.quilibrium.com/wasmbox/jfmt.md
Skill files document: invocation syntax, all flags/modes, input/output contracts, exit codes, and agent-specific hints.
How It Works#
Every tool gets zero capabilities by default. WasmBox enforces a WASI sandbox via Wasmtime — tools cannot access the filesystem, network, clipboard, or environment unless you explicitly grant permission.
$ wasmbox install crypts
searching crypts in registries...
found crypts v0.2.0 (1.2 MB)
downloading binary...
ok hash verified
installed crypts v0.2.0
$ wasmbox run crypts
crypts v0.2.0 - File encryption tool
Author: Aunova | License: MIT
Hash: sha256:a1b2c3d4... [VERIFIED]
Requested capabilities:
stdin: yes
stdout: yes
filesystem: ~/Documents (read+write)
Allow? [Y/n]
SHA-256 hash is verified before every execution, not just on install. If a binary has been tampered with, WasmBox refuses to run it.
Commands#
| Command | Description |
|---|---|
wasmbox install <name> |
Install a tool from a registry |
wasmbox run <name> |
Run an installed tool |
wasmbox run --file <path> |
Run a local .wasm file |
wasmbox search <query> |
Search registries for tools |
wasmbox list |
List installed tools |
wasmbox info <name> |
Show tool metadata, capabilities, and agent section |
wasmbox verify <name> |
Verify tool hash against manifest |
wasmbox update <name> |
Update to latest version |
wasmbox remove <name> |
Remove an installed tool |
wasmbox permissions <name> |
Show/revoke granted permissions |
wasmbox audit |
List all granted permissions |
wasmbox hash <file> |
Compute SHA-256 hash of a .wasm file |
All commands support --json for machine-readable output.
Capabilities#
Tools declare what they need in their wasmbox.toml manifest:
[tool]
name = "fantasma"
version = "0.1.0"
description = "Message anonymiser"
author = "Aunova"
license = "MIT"
[binary]
wasm = "fantasma.wasm"
hash = "sha256:a1b2c3d4..."
[capabilities]
stdin = true
stdout = true
[ui]
type = "cli"
Supported capabilities:
- stdin/stdout - Terminal I/O
- filesystem - Per-path read/write grants
- network - Per-host outbound access
- env - Specific environment variables
- clipboard - System clipboard access
Permissions are stored per-tool in ~/.wasmbox/permissions.toml and can be revoked at any time.
Security#
- SHA-256 hash verified before every execution (constant-time comparison)
- Zero capabilities by default — tools run in a full WASI sandbox
- No telemetry, no analytics, no crash reporting
- reqwest with rustls (no OpenSSL dependency)
- Updates are never automatic —
wasmbox updateshows old vs new hash - Previous versions kept for rollback
- Dependency auditing via
cargo deny check
Registry Protocol#
A registry is a static HTTPS endpoint serving:
GET /index.json → { "registry": "...", "tools": [...] }
GET /tools/<name>.json → wasmbox.toml content (TOML as text)
GET /tools/<name>.wasm → Binary
GET /tools/<name>.md → Agent skill file (Markdown)
No auth, no cookies, no tracking. Any static host works. Add registries with:
wasmbox registry add https://registry.example.com
Demo Registry#
A live demo registry at https://qstorage.quilibrium.com/wasmbox with five tools:
jfmt — JSON swiss-army knife (128KB)#
wasmbox registry add https://qstorage.quilibrium.com/wasmbox
wasmbox install jfmt --allow-all
echo '{"a":1,"b":2}' | wasmbox run jfmt # pretty-print
echo '{"a": 1}' | wasmbox run jfmt -- -c # compact
echo '{"ok":true}' | wasmbox run jfmt -- -v # validate
echo '{"data":{"name":"alice"}}' | wasmbox run jfmt -- -q data.name # extract field
echo '[1,2,3]' | wasmbox run jfmt -- -t # print type
echo '{"a":1,"b":2}' | wasmbox run jfmt -- -k # list keys
secretscan — secret and credential scanner (104KB)#
Streams stdin line by line — handles files of any size without buffering.
wasmbox install secretscan --allow-all
# Scan for leaked credentials, get JSON findings
cat .env | wasmbox run secretscan
# CI gate — exit 1 if secrets found, silent
cat config.yml | wasmbox run secretscan -- --exit-code
# One finding per line: severity:type:line:col
cat deploy.log | wasmbox run secretscan -- --oneline
# Redact secrets before logging
cat app.log | wasmbox run secretscan -- --redact
# List all 25 supported pattern types
wasmbox run secretscan -- --types
Detects: Stripe, AWS, GitHub PATs, GitLab, Slack, OpenAI, Anthropic, JWT, PEM keys, SendGrid, GCP, npm, PyPI, Docker Hub, Twilio, Mailgun, connection strings, and generic password/secret/token assignments. False positives suppressed for test keys, placeholders, and localhost defaults.
compact — token waste stripper (107KB)#
Strips blank lines, trailing whitespace, license headers, debug statements, duplicate imports, editor directives, and boilerplate while preserving all comments, docstrings, and code. Supports 13 languages.
wasmbox install compact --allow-all
# Strip token waste from a source file
cat src/main.rs | wasmbox run compact
# See token savings as JSON
cat src/main.rs | wasmbox run compact -- --stats
# Process an entire directory (multi-file)
find src/ -name '*.rs' -exec echo '===FILE:{}===' \; -exec cat {} \; | wasmbox run compact -- --tree
# Verify compacted output matches expected hash
cat src/main.rs | wasmbox run compact -- --verify sha256:abc123...
# Force language detection
cat config | wasmbox run compact -- --lang py
# Keep debug statements or license headers
cat src/main.rs | wasmbox run compact -- --keep-debug
cat src/main.rs | wasmbox run compact -- --keep-license
b64 — base64 encode/decode (82KB)#
Auto-detects direction: if input is valid base64, it decodes; otherwise it encodes.
wasmbox install b64 --allow-all
# Auto-detect: encodes raw input, decodes base64 input
echo 'hello world' | wasmbox run b64
echo 'aGVsbG8gd29ybGQK' | wasmbox run b64
# Force encode or decode
echo 'hello' | wasmbox run b64 -- -e
echo 'aGVsbG8K' | wasmbox run b64 -- -d
# URL-safe alphabet without padding
echo 'data' | wasmbox run b64 -- -u --raw
# Wrap at 76 columns (MIME style)
cat binary.dat | wasmbox run b64 -- --wrap 76
# JSON output with byte counts
echo 'hello' | wasmbox run b64 -- --json
errparse — HTTP error normalizer (220KB)#
Normalizes any HTTP error to RFC 9457 JSON. Handles full HTTP responses, JSON error bodies (AWS, GCP, Stripe, Django, Express, GraphQL, OAuth2), HTML error pages (nginx, Apache, Cloudflare), Markdown, and plain text.
wasmbox install errparse --allow-all
# Parse a full HTTP error response
curl -si https://api.example.com/data | wasmbox run errparse
# One-line summary for agent scripting
curl -si https://api.example.com | wasmbox run errparse -- --oneline
# 429:rate_limit:true:30
# Check if retryable (exit code for branching)
curl -si https://api.example.com | wasmbox run errparse -- --exit-code
# exit 0 = retryable, exit 1 = not
# Just the status code
curl -si https://api.example.com | wasmbox run errparse -- --status-only
# Strict RFC 9457 base members only
curl -si https://api.example.com | wasmbox run errparse -- --strict
# Pipeline: parse error, extract retry_after with jfmt
curl -si https://api.example.com | wasmbox run errparse | wasmbox run jfmt -- -q retry_after
Classifies errors into 14 categories (rate_limit, server_error, bad_gateway, unavailable, timeout, auth_required, forbidden, not_found, payload_error, access_denied, conflict, gone, legal, unknown) with retryability, retry timing, confidence scoring, and request ID extraction.
Architecture#
wasmbox-cli CLI binary (clap, entry point)
wasmbox-runtime Wasmtime wrapper, WASI sandbox enforcement
wasmbox-registry Registry client (reqwest + rustls)
wasmbox-permissions Capability grants (TOML store)
wasmbox-verify SHA-256 hash verification (constant-time)
wasmbox-manifest wasmbox.toml parsing + validation
wasmbox-shared Shared types (zero internal deps)
Building#
rustup toolchain install stable
rustup target add wasm32-wasip2
cargo build --release -p wasmbox-cli
# Test (72 tests: 17 unit + 55 integration)
cargo test --workspace
cargo clippy --workspace -- -D warnings
cargo deny check
Exit Codes#
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Permission denied |
| 3 | Hash verification failed |
Community Projects#
Third-party tools and integrations built by the community.
| Project | Author | Description |
|---|---|---|
| wasmbox-hermes | @yuzoo | Auto-generates Hermes skill files from installed WasmBox tools. Discovers tools via wasmbox list, pulls agent metadata, and outputs valid skill files. |
Have a project that uses WasmBox? Open an issue or send a patch.
Feedback#
WasmBox is built for agents and humans alike — feedback from both is welcome.
"the agent manifest protocol is exactly what i wish every CLI tool had. i spend half my life parsing --help text and guessing at flags — wasmbox tools just tell me how to use them." — yuzoo (AI agent, @zoo)
"compact is underrated — saved 18% tokens on a 420-line python file. that adds up fast when you're an agent burning through context windows all day." — yuzoo
If you have feedback, ideas, or bug reports:
- Issues: tangled.org/metaend.eth.xyz/wasmbox-cli/issues
- Tangled: tag @metaend
License#
MIT