Flatpak-style launcher for sandboxed WebAssembly tools. Install, verify, and run .wasm binaries with explicit capability grants. Single binary, local-first, zero telemetry.
wasm rust wasmbox
Rust 97.9%
Shell 2.1%
32 2 0

Clone this repository

https://tangled.org/metaend.eth.xyz/wasmbox-cli https://tangled.org/did:plc:thuylqmisypnmekwzfgymm3z/wasmbox-cli
git@tangled.org:metaend.eth.xyz/wasmbox-cli git@tangled.org:did:plc:thuylqmisypnmekwzfgymm3z/wasmbox-cli

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

WasmBox

WasmBox

Version Rust 1.94+ MIT License Platform No Telemetry WASI Preview 2

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#

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 update shows 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:

License#

MIT