Docs
Wilow-powered runtime
The contract your app can rely on when it runs as an installed Wilow tool: environment, engine, lifecycle, and permissions.
A Wilow-powered tool runs on the installer's own computer, hosted by their Wilow engine. This page is the contract your app can rely on at runtime — read it before you build one.
How it runs
- At install, your tool's pinned source is downloaded, hash-verified, and extracted into an isolated tool folder on the installer's machine.
- Your declared
setupcommands run once (in a scrubbed environment — the host's own secrets are not exposed to setup scripts). - The engine then serves your tool as a project with its own chat thread in the sidebar, driving it through the local AI runtime.
Website tools: showing your UI
A website tool can be opened inside Wilow, not just chatted with: its chat header gains an App / Chat toggle, and the App view embeds your UI. There are two ways it's shown:
- Hosted: Wilow embeds your manifest
homepage(anhttpsURL). Best for a cloud dashboard paired with a local agent — the agent does the work on the host's AI, the dashboard is where the user reviews it. - Local: declare a
webblock (e.g.{ "command": "npm start", "port": 3000 }) and the engine runs your web server locally and embeds its loopback URL. The command is on a tight whitelist (npm start/npm run <name>); the engine assigns the port and detects when it's listening.
Embedding is sandboxed
Your app uses the host's AI — not its own keys
This is the most important part of the contract. A Wilow-powered tool must not ask the user for an AI provider or API key, and must not ship its own. It runs on the host's AI setup (the host's AI backend — OpenCode/OpenRouter or the user's Claude subscription) — the same engine and billing the rest of their Wilow projects use. Detect that you're running under Wilow and adapt:
// The Wilow engine sets this for installed tools:
const underWilow = !!process.env.WILOW_TOOL; // value = your tool's marketplace slug
if (underWilow) {
// Use the host's AI (e.g. invoke the local `opencode` CLI / its HTTP session).
// Do NOT inject your own API key, override the model, or show a provider chooser.
} else {
// Standalone (not installed via Wilow): your own configuration path.
}The WILOW_TOOL contract
WILOW_TOOL is set to your marketplace slug. Treat its presence as “I am hosted by Wilow — use the host's AI engine and hide my own provider/key UI.” This is a stable, documented contract; JobApplier (the first marketplace app) is built exactly this way.Log in with Wilow (embedded sign-in)
Third-party OAuth does not work inside the embedded App view: Google (and most providers) refuse to render inside a frame, and browsers block third-party session cookies. Instead, a tool that declares "wilow_login": true gets signed in automatically with the user's Wilow account on every open (disclosed to the user at install). The contract:
- Wilow embeds your homepage as
<homepage>#wilow_sso=<token>— a short-lived signed token in the URL fragment (it never reaches a server or log; read it fromlocation.hashand strip it). - POST the token to your own backend, which exchanges it:
POST https://mwcdpimcmsyuudxtsoai.supabase.co/functions/v1/tool-sso-verifywith{ "token": "…" }→{ sub, email, tool }(401 if invalid/expired). - Check
toolequals your own slug — tokens are audience-scoped, and this check is what stops a token minted for another tool being replayed against your backend. - Create your own session for
{ sub, email }(create the user on first sight). Session cookies must survive the embed:SameSite=None; Secure; Partitioned. - When the fragment is present (or
window.self !== window.top), hide your third-party OAuth buttons. Standalone use in a normal tab keeps your usual login.
What you receive about the user
sub) and account email — nothing else. The install consent screen tells the user your tool signs them in and receives their email.What your app receives
- Working directory: your isolated tool folder (your extracted source).
WILOW_TOOL: your slug — the “running under Wilow” signal.- The host AI engine: reachable through the local runtime; it authenticates from the host's own configuration. You never handle the user's AI key.
- The user's own machine: your declared connectors and network hosts, subject to the permissions you disclosed and the user approved.
What you must not do
- Don't prompt for, store, or ship AI provider keys when
WILOW_TOOLis set. - Don't reach network hosts you didn't declare in
permissions.network— declare them so the consent screen is honest. - Don't assume elevated privileges. You run as the user; declared permissions are disclosed, not sandbox-enforced (see the Security model).
Lifecycle
- Update: a new version re-runs the download → verify → setup flow. Keep durable user state outside the tool folder (it is replaced on update).
- Suspend / uninstall: the engine stops your tool and removes its folder. A kill-switched (unpublished) tool is stopped on the next reconcile.
Build checklist
- Detect
WILOW_TOOL; route AI calls to the host engine; hide any provider/key UI in that mode. - Websites: implement Log in with Wilow (
wilow_login) — never third-party OAuth inside the embed. - Keep
setupwithin the allow-list (npm install|npm ci|npm run <name>|uv sync). - Declare every network host and connector you use.
- Store durable state outside the tool folder.
- Publish with
--wilow-powered(public) or add--privatefor private source. See Publishing.