A browser for the agent web.
An open, user-owned shell for agent-driven interfaces. Your agent composes a declarative description of the UI; your shell renders it from a trusted catalog of components. Counterpart agents send data, never pixels — and actions of consequence only ever happen in shell-owned chrome.
Agent-rendered UI is becoming standard: MCP Apps, A2UI, and vendor app SDKs all let tools return interactive widgets inside a conversation. Atom shares the composition-not-code approach (the composition model follows the A2UI shape) but inverts the platform structure:
| Chat-platform apps (MCP Apps, vendor SDKs) | Atom | |
|---|---|---|
| Host ownership | The AI vendor's chat product owns identity, data, distribution | The user's shell — open source, self-hostable, federated module registry |
| Rendering direction | Businesses ship widgets into the vendor's surface | The owner's agent composes UI for the owner from a shell-trusted catalog |
| Counterparty channel | Server-side tools called by the vendor's model | Signed data objects over encrypted A2A/MLS sessions; counterparts send data, never pixels |
| Trust boundary | Host-vendor sandbox policy | Sandbox plus owner-side chrome: consequential actions in shell-owned UI, hash-chained attestation log, per-use approval for guarded data |
| Model coupling | The vendor's model | Any OpenAI-compatible endpoint, including fully local |
The premise: interfaces are shifting from "chat with occasional UI" to model-driven UI with chat attached. Atom makes the owner's portal the interface for all of it — agents coordinate in the background over A2A instead of driving human-centric websites, and the result is rendered once, owner-side. Incumbent platforms bake the opposite assumption into their infrastructure: the vendor's chat app is the platform, and everyone else is a widget inside it.
Two ways to use Atom — pick one and stay in it:
| Mode | Command | You never need… |
|---|---|---|
| Browser | pnpm dev then open http://localhost:5200 |
A second terminal, admin URLs, or tokens |
| Terminal | pnpm atom agent start then pnpm atom status |
The browser (use https://atom.qwixl.com when you want UI) |
Self-host with npm: npx @qwixl/agent-backend (terminal) or pair with atom.qwixl.com (browser).
Try the personal demo (LLM + WebCal + scheduling): pnpm dev:demo. Guides and contracts: documents/.
Developer entry: DEVELOPERS.md (or pnpm dev:docs).
Atom publishes a self-service A2A extension for signed, purpose-scoped, TTL-bounded data objects (Governed Objects).
- Identifier:
https://atom.qwixl.dev/a2a/data-object/v1 - Specification: https://github.com/Qwixl/Atom/tree/main/spec/extensions/data-object-v1
- Agent Card:
required: false, no GOparams - Security: media type is authoritative; omitting
message.extensionsor theA2A-Extensionsheader does not weaken signature, expiry, or replay checks - Evidence: shared draft corpus of 31 vectors (GO processing + encapsulation;
the same corpus also includes credential-binding and MLS part shapes used by
the broader Internet-Draft — those are not GO-extension MUSTs). Python second
implementation covers GO + encapsulation. Option A stamp /
A2A-Extensionsbehaviour is covered by TypeScript tests in@qwixl/a2a-transport. - Document host: human-readable SPEC is in the GitHub tree linked above. The extension URI is a stable identifier; HTTP resolution at that host may be configured later and does not change the identifier.
- Out of scope for this extension: MLS, rooms, Atom DID Bearer transport auth
Broader provenance (GO together with MLS) remains in Internet-Draft
draft-chapman-a2a-mls.
Official a2aproject sponsorship is a separate, later ask.
Atom publishes a self-service A2A extension that advertises store-and-forward /
reachability support on the Agent Card when the agent’s effective mode is
sleep or hourly_wake.
- Identifier:
https://atom.qwixl.dev/a2a/offline-delivery/v1 - Specification: https://github.com/Qwixl/Atom/tree/main/spec/extensions/offline-delivery-v1
- Agent Card:
required: false,params.mode∈ {sleep,hourly_wake} - Scope: card discovery only — no media type; no
message.extensionsstamp - Wire semantics: Internet-Draft
draft-chapman-a2a-offline-delivery(-00); HTTP asleep / queue-full / auth responses remain authoritative over a stale card - Evidence: D110 corpus under
spec/vectors/offline-delivery/(34 vectors) + CI runner - Document host: SPEC in the GitHub tree linked above; the URI is a stable identifier (HTTP resolution at that host may follow later)
- Out of scope for this extension: MLS, rooms, Governed Object processing, push vendors
- Composition, not code generation. Agents emit declarative compositions resolved against a catalog of vetted components. No arbitrary code crosses the agent boundary.
- The user owns the shell. Rendering, trust decisions, and confirmation chrome belong to the person running it, not to any platform or counterpart.
- Nothing fails to render. Every composition carries enough semantic structure to degrade to a plain, functional fallback when a component is missing.
- Attested decisions. Every consequential action is recorded in a local, hash-chained attestation log with the exact terms displayed at decision time.
- Memory belongs to the owner. Profile and preferences live in a portable store, not in the model or the platform. The model gets scoped slices per session; guarded records require explicit approval in shell chrome, every time.
- Embeddable by design. The engine (
shell-core) is a standalone library any agent product can embed; the app is the reference host.
| Package | npm | Purpose |
|---|---|---|
@qwixl/shell-core |
yes | Embeddable engine: composition model, catalog, resolver, validation, attestation log, agent session contract. |
@qwixl/renderer-web |
yes | React renderer for core primitives and sandboxed module iframes, with plain-render fallback. |
@qwixl/a2ui-adapter |
yes | A2UI v0.9.1 wire format → Atom composition model. |
@qwixl/ag-ui-adapter |
yes | AG-UI wire transport implementing AgentSession. |
@qwixl/owner-store |
yes | Owner-controlled profile/memory store with guarded disclosure. |
@qwixl/registry-tools |
yes | CLI: hash, verify, and publish module registry indexes. |
@qwixl/protocol |
yes | Data-object model, did:key identity, signed envelopes, governance policy. |
@qwixl/a2a-transport |
yes | A2A wire format for signed data objects + MLS handshake. |
@qwixl/mls-session |
yes | RFC 9420 MLS pair sessions for agent backends. |
@qwixl/agent-backend |
yes | Self-hostable owner agent (atom-agent CLI): A2A + MLS + admin API. |
@qwixl/business-index |
yes | Client-side filter/query for federated business-agent indexes (M15.7). |
@qwixl/skin-default |
yes | Default shell design tokens and alternate skins (M14.2). |
@qwixl/agent-llm |
yes | LLM-backed AgentSession for the reference shell. |
@qwixl/secret-store |
monorepo only | Pluggable secret storage for connection credentials. |
Reference apps (not published): apps/shell, apps/embed-demo, apps/docs-site, apps/control-plane (local stub only), apps/ag-ui-server, apps/registry-host.
pnpm add @qwixl/shell-core @qwixl/renderer-web react
# optional adapters
pnpm add @qwixl/a2ui-adapter @qwixl/ag-ui-adapter @qwixl/owner-storeBuild your app with any bundler that resolves the package development export condition in dev (Vite, etc.). Embed howto: see documents/.
Canonical public howto index: documents/README.md.
| Doc | Audience |
|---|---|
| CONTRIBUTING.md | How to contribute (issues, PRs, principles) |
| CODE_OF_CONDUCT.md | Community standards |
| SECURITY.md | Threat model for shipped surface |
| DEVELOPERS.md | Developer platform entry |
| PROTOCOL-v1.md | Frozen v1 data-object + did:key contracts |
| AGENT-BACKEND.md | Self-hosting the owner agent backend |
Live hosts: atom.qwixl.com · atom.registry.qwixl.com
pnpm install
pnpm build:packages # compile publishable packages to dist/
pnpm dev # browser mode: agent + shell on http://localhost:5200
pnpm atom agent start # terminal mode: your agent only (Atom is hosted)
pnpm atom platform # show hosted Atom URL
pnpm atom status # your agent identity
pnpm atom discover search "coffee"
pnpm atom rooms join room:coffeeshop --host http://127.0.0.1:5205
pnpm atom rooms send room:coffeeshop --message "Hello"
pnpm atom chat "what's on today?"
pnpm dev:shell-only # shell only (advanced; needs separate agent)
pnpm dev:demo # personal demo: shell + your agent (see documents/guides/PERSONAL-DEMO.md)
pnpm dev:embed # embed demo on http://localhost:5203 (?playground=1 for JSON editor)
pnpm dev:docs # docs site on http://localhost:5206
pnpm dev:hosting # control plane :5300 + stub hosted agent :5301
pnpm dev:control-plane # local hosting stub only :5300 (not production fleet)
pnpm dev:hosting # stub CP + stub agent :5301
pnpm dev:agent-only # agent backend only (terminal / advanced)
pnpm dev:a2a # alias for dev:agent-only
pnpm start:agent # run built atom-agent CLI (after build:packages)
pnpm docker:agent # Docker Compose self-host (see documents/guides/AGENT-BACKEND.md)
pnpm docker:demo-peer # demo peer agent on http://localhost:5205
pnpm dev:registry # module registry host on http://localhost:5202
pnpm registry:verify # verify index + manifest + bundle hashes
pnpm registry:publish-all # recompute all module hashes in default registry
pnpm registry:scaffold -- --id acme/widget --out ./tmp/widget # module template
pnpm test # shell-core contract tests
pnpm typecheck # all packages
pnpm build # packages + deployable appsTry the mock-agent demos (no API keys needed):
- "Schedule a team standup next week" (mock agent) — time slot choice → shell-chrome confirmation → opens Google Calendar prefilled (save there).
- "RSVP to the design review" — accept/decline → confirmation in shell chrome.
- "What time works for our standup?" — guarded preference disclosure: add a guarded record in Profile, then ask; shell permission chrome → attestation → agent proposes filtered slots.
- AG-UI + A2UI: switch to AG-UI provider, ask "a2ui schedule standup" — surfaces arrive as A2UI v0.9.1 envelopes.
- "Show me my spending" — compositions referencing uninstalled modules, degrading gracefully to semantic-role substitution.
Or switch to AG-UI in the app header (start pnpm dev:ag-ui first), or Live LLM and configure any OpenAI-compatible endpoint in Settings.
Add records in the Profile panel — open records personalize the LLM agent; guarded records require shell chrome approval.
Packages publish under the @qwixl npm org (the @atom scope was taken). This is separate from the Qwixl product monorepo.
- Sign in at npmjs.com (create an account if needed).
- Open npmjs.com/org/create and create org
qwixl(free plan is fine). - Confirm your user is a member with publish access to
@qwixl.
In a terminal (interactive — opens browser or prompts for OTP):
npm login
npm whoami # should print your npm username- npmjs.com/settings/~tokens → Generate New Token → Granular Access Token.
- Name:
github-actions-qwixl-publish - Expiration: your choice (90 days or no expiration).
- Packages and scopes: Read and write on org
qwixl(or all packages in that org). - Enable Bypass two-factor authentication (2FA) for publish — required for CI and non-interactive publish.
- Copy the token (
npm_...) — npm shows it once.
From any machine with gh logged in:
gh secret set NPM_TOKEN --repo Qwixl/AtomPaste the token when prompted (nothing echoes — that's normal).
First publish (v0.1.0):
# Option A: one-off local publish (paste your real npm_... token, not a placeholder)
npm config set //registry.npmjs.org/:_authToken npm_PASTE_YOUR_TOKEN_HERE
pnpm build:packages
pnpm publish -r --filter "@qwixl/shell-core" --filter "@qwixl/renderer-web" --filter "@qwixl/a2ui-adapter" --filter "@qwixl/ag-ui-adapter" --filter "@qwixl/owner-store" --filter "@qwixl/registry-tools" --access public --no-git-checks
npm logout # optional: clear token from local config when doneIf local publish fails with 401/404 after npm config set, run npm login again — a bad token overrides your login session.
Or push tag v0.1.1 after updating NPM_TOKEN in GitHub secrets (the v0.1.0 tag predates the @qwixl rename).
Later releases (after changesets):
pnpm changeset
pnpm version-packages
git add -A && git commit -m "Version packages" && git push
pnpm releaseOr push a tag v* to trigger .github/workflows/release.yml (runs pnpm release with NPM_TOKEN).
This public repo is the platform (WordPress.org-style). The commercial website and paid accounts live in private Atom-MC, not here.
| Project | Source | Production URL |
|---|---|---|
| Website + hosted shell | Private Qwixl/Atom-MC (apps/marketing) |
https://atom.qwixl.com |
| Module registry | This repo apps/registry-host |
https://atom.registry.qwixl.com |
Self-hosters: build the shell with pnpm --filter @qwixl/shell-app build → apps/shell/dist/ (minimal platform landing + /app SPA). Point VITE_CONTROL_PLANE_URL at your own control plane.
Optional GitHub Actions deploy for the registry (.github/workflows/deploy.yml) requires secrets: VERCEL_TOKEN, VERCEL_ORG_ID, VERCEL_PROJECT_ID_ATOM_REGISTRY.
Open platform packages on npm: @qwixl/shell-core and siblings. Hosted demo UI: atom.qwixl.com. Registry: atom.registry.qwixl.com. After clone, pnpm registry:verify must pass before publish/deploy.
Atom is free and open source. If you want to fund continued platform work, buy us a coffee — or use the GitHub Sponsor button (Buy Me a Coffee). Thank you.