# atlibs atlibs runs WebAssembly modules published as atproto records: in a browser page, a Node server, a Rust server, or the `atlibs` CLI. A module plans XRPC calls; the host makes them with the user's session, held to the scope of that module's own OAuth client record. ```bash cargo install --locked --git https://knotless.dev/johnandersen777.bsky.social/atlibs --rev 88b2ba8 atlibs atlibs add bobvmbuilder.bsky.social/hello atlibs run hello count '{"did":"did:plc:ocnuqjlzgohypj3zoznermms","collection":"com.fedfork.exec.wasm.module"}' atlibs new my-module # write one ``` **[Docs](docs/README.md)**: [use](docs/start/page.md) (page, Node, CLI, Rust), [write](docs/start/write.md), [publish](docs/start/publish.md), [compose](docs/start/compose.md). ## Layout - `javascript/src/`: the JS library, no dependencies (browser and Node hosts, compositions, MCP servers, OAuth helpers); on npm as `@publicdomainrelay/atlibs` - `rust/src/abi`: the SDK modules are written against; `rust/host`: the Rust host; `rust/cli`: `atlibs`; `rust/compose`: compositions written in Rust - `examples/rust/*`: modules; `examples/web/*`: pages; `examples/node-hono`: a Node server; `examples/rust-host`: a Rust program; `examples/rust-compose`: a composition in Rust - `records/`, `lexicons/`: records to publish, and their schemas ## Test ```bash cargo wasm && cargo host && cargo loopback && cargo host-test node --test examples/rust/*/test.mjs examples/web/*/*.test.mjs examples/node-hono/test.mjs javascript/src/*/*.test.mjs rust/host/*.test.mjs docs/docs.test.mjs node --import ./rust/host/swap.mjs --test javascript/src/run-module/*.test.mjs examples/rust/*/test.mjs javascript/src/compose/compose.test.mjs javascript/src/server/server.test.mjs javascript/src/mcp/mcp.test.mjs ``` `docs/docs.test.mjs` runs every snippet in `docs/` (set `ATLIBS_DOCS_NETWORK=1` to include the ones that read the live network). `javascript/src/plugin-context/test.html` covers the browser engine: serve the repo root with `python3 -m http.server` and open it. ## Open - [ ] SSRF: route module calls through the user's PDS, public reads through a relay or AppView, one hardened DID resolver; drop or allowlist direct `service` routes ([security](docs/reference/security.md#known-gap-ssrf)) - [ ] Rust host: XRPC, DID resolution and service auth from atproto-crates, once they take a pluggable fetch (they bring their own reqwest client, which would bypass atlibs' `Fetch`) - [ ] Node CLI: `login` / `logout` with OAuth on 127.0.0.1, like `atlibs login` (today: `--app-password` only) - [ ] Budget kills skip cleanup: a run stopped by its budget (e.g. a requester `contract` past `wallMs` after the accept) gets no chance to release what it holds; give modules a final `closing` event with a small grace budget, both hosts - [ ] Requester (atlibs-socialweb-computer-requester): surface a bidder's rejection reason (e.g. an RFP signed by an unbound badge.blue key) instead of waiting out the budget with "no acceptable bid" - [ ] Republish the split repos' modules from their own repos so `atlibs verify` reproduces them there - [ ] Review / address-review loop until clean