CLI & commands¶
Everything you do runs through one binary: webtasks. It can serve the
HTTP API, run a single recipe from the terminal, or package a folder of recipes
into a deployable bundle.
webtasks # start the HTTP server (bundle from WEBTASKS_BUNDLE)
webtasks serve # same as above, explicit
webtasks run <file> [opts] # run one recipe once and print JSON
webtasks bundle <dir> [out.zip] # package a directory into a runnable bundle
webtasks version # print version
webtasks run — run one file¶
The fastest way to try a recipe: point webtasks run at a .webtask (or a
.yaml task) and it executes once, prints the result as JSON to stdout, and
exits. Progress events stream to stderr, so you can pipe the JSON cleanly.
# run a recipe (Chrome launches headless by default)
webtasks run recipes/title.webtask
# pass inputs
webtasks run recipes/search.webtask --input q=golang
webtasks run recipes/pdf.webtask --json '{"url":"https://news.ycombinator.com","path":"/tmp/hn.pdf"}'
# watch it happen in a real browser window
WEBTASKS_HEADLESS=false webtasks run recipes/title.webtask
| Option | Meaning |
|---|---|
--input k=v |
Set one input. Repeatable. |
--json '{...}' |
Set inputs from a JSON object. |
.webtask sources are transpiled with the grammar baked into the binary; this
needs the capy CLI on your PATH. A
.yaml task runs with no extra tools. JS modules referenced by a recipe are
loaded from a scripts/ folder next to the file.
webtasks bundle — package a directory¶
A bundle is what the server loads: a directory (or zip) of recipes, JS
modules, and config. webtasks bundle zips a source folder, transpiling every
.webtask to YAML on the way in and copying everything else verbatim.
webtasks bundle ./my-recipes # -> my-recipes.zip
webtasks bundle ./my-recipes dist/bundle.zip # custom output path
Then run the server against it:
→ Deployment for the full bundle layout and config files.
webtasks serve — run the HTTP API¶
The default. Reads a bundle from WEBTASKS_BUNDLE and serves every recipe as an
HTTP endpoint. Call tasks with any HTTP client:
WEBTASKS_BUNDLE=./my-bundle webtasks &
curl -s localhost:8765/health | python3 -m json.tool # pool status + task count
curl -s localhost:8765/tasks | python3 -m json.tool # every task + its schema
curl -s -X POST localhost:8765/tasks/basics/title -d '{}'
curl -s -X POST localhost:8765/tasks/search/duckduckgo -d '{"q":"golang"}'
# stream live progress as Server-Sent Events
curl -N -X POST localhost:8765/tasks/streaming/progress \
-H 'Accept: text/event-stream' -d '{}'
→ HTTP API for the full contract.
Environment¶
| Variable | Used by | Meaning |
|---|---|---|
WEBTASKS_BUNDLE |
serve | Bundle directory or .zip. |
WEBTASKS_HOST / WEBTASKS_PORT |
serve | Bind address (default 127.0.0.1:8765). |
WEBTASKS_HEADLESS |
serve, run | true/false. run defaults to headless; the server defaults to visible. |
WEBTASKS_DOWNLOADS_DIR |
serve, run | Where downloaded files land. |
WEBTASKS_PROFILE_DIR |
serve, run | Where persistent Chrome profiles live. |
Contributing to webtasks itself?
The repo also ships a commands.yaml of developer shortcuts (build, lint,
release packaging) run via the capy-based command runner. Those are for
hacking on the engine and are documented in
commands.yaml.
You never need them to use webtasks.