Skip to content
weftGitHub

LearnGet started

Working with AI agents

weft is built for code that AI agents write, as much as for code you write yourself. An agent's usual problem with a framework is that it guesses: it writes what the framework it knows best would want, and nothing tells it otherwise until a person reads the result. weft closes that gap from both sides. It tells the agent what this app is and how to write it, and when the agent gets something wrong, the diagnostics say exactly what and how to fix it, in a form a program can act on.

Nothing on this page needs an agent. Every command here is one you can run yourself, and you'll see the same things the agent sees.

AGENTS.md

A new app has an AGENTS.md at its root. Most coding agents read a file by that name when they start work in a project. weft's opens like this:

md
# AGENTS.md<!-- Generated by `weft agents-md` from weft@0.1.0. Do not edit: change weft.config.ts and regenerate. -->This is a **weft** app. It is not React: components run once, state is a box, andReact hooks don't exist. Run `weft check --json` after every change; each diagnostic gives code, location, why and fix.

The rest is written from the weft you have installed, not from a template, so it can't describe a version you don't have:

  • The rules: the short list of how weft code is written (boxes, derived, live JSX and props, bodies that run once). It's the same text as weft docs rules.
  • The API in this version: what @weft-js/core and its entries export, and anything it doesn't have yet, with "Don't import them".
  • Diagnostics: how to look one up, and which test checks this weft reports.
  • How to verify a change, which is the loop later on this page.
  • Full stack, for an app with src/routes: routes, server functions, the database and auth, in brief.
  • Styling, when the app has style groups: reuse a group before writing a new one.
  • Commands: this project's commands and tasks, each with what it does and what it touches.
  • Plugins: a short section from each plugin in weft.config.ts.
  • More: the weft docs topics to read for depth.

weft keeps its own part under 8 KB, because an agent pays for every word of it on every task. Each plugin's section has its own limit of 1 KB (P112). Anything longer belongs in weft docs, which an agent reads only when it needs to.

Keeping it current

AGENTS.md is generated, so don't edit it by hand. It's written after the install by the generator, and again by weft add when you add a plugin. Regenerate it yourself after you upgrade weft or change tasks or plugins:

bash
npx weft agents-md

To check it's current without writing, as in CI:

bash
npx weft agents-md --check

That exits 1 when the file is stale, or when weft's part is over the limit. --stdout prints it instead of writing.

If your agent reads a different file, such as CLAUDE.md, have that file point to AGENTS.md rather than copying it, so there's one file to keep current.

Docs an agent can read: weft docs

The site is for people. An agent working in a terminal reads the same reference from the command line:

bash
npx weft docs            # the list of topicsnpx weft docs props      # one topicnpx weft docs W014       # one diagnostic code

The topics are the reference pages: rules, state, props, lists, async, start, rust, plugins, testing, browser, ui-state, surface, verify, icons, fonts, meta, config, design and style. A few are generated from your app instead of written:

TopicWhat it prints
diagnosticsEvery code, and whether the weft you have installed reports it
commandsThis project's commands and tasks, with what each one changes
agentsWhat AGENTS.md would say now

A code page says whether your install reports that code at all. A plugin can add topics and codes of its own, and they show up in weft docs like the built-in ones.

Each topic is written to be short, because an agent reads it in its context. The Reference on the site shows the same text.

.weft/map.md: what this app has

AGENTS.md says how to write weft. The map says what's in this app: its routes, its server functions and data, its style groups and its plugins, and what to call for each.

bash
npx weft map

That writes .weft/map.md (and .weft/map.json); weft check keeps it current once .weft/ exists. AGENTS.md tells the agent to start there, so it reuses the listTodos query you already have instead of writing another.

Tasks: commands an agent can trust

An agent shouldn't have to read a shell script to learn whether it deletes a database. weft's project commands are declared in weft.config.ts, each with what it does and what it touches:

ts
tasks: {  seed: { run: 'node scripts/seed.mjs', description: 'Load demo products into the dev db', sideEffects: ['db'], env: ['dev'] },},

weft tasks lists them beside weft's own commands, and weft run seed runs one. A task with no description or sideEffects is P004, and a package.json script that isn't a weft command is P002, for the same reason.

scope in the config draws the lines an agent works inside: write and read globs, and forbid, which weft never compiles or writes (.env*, say). The config reference has the details.

The verify loop

"Done" for an agent means more than "it compiles". AGENTS.md gives it four steps for every change, and each one answers to a command.

1. Check: weft check --json

After every change, the agent runs:

bash
npx weft check --json

Each diagnostic comes back with its code, its place, why it's wrong, and the fix, often as an exact edit. The agent applies the safe edits (weft fix does it in one go), decides the rest, and runs the check again until there are no errors. Because the reason is written about the code in front of it, the agent doesn't have to guess what a stack trace meant.

2. See it work: weft browser

A clean check means the code is well formed, not that the feature works. So the agent looks at the running app. With weft dev running and the app open in a browser, weft browser drives that tab through the dev server:

bash
npx weft browser snapshot --interactivenpx weft browser act button "Add to cart" clicknpx weft browser assert status - text "Total: $4.50"

snapshot lists what's on the page by role and name, with a ref for each, the way a screen reader or a test sees it, plus the reactive graph with real names: Cart.total = 4.5 ← Cart.lines. act clicks, types and selects as a user would, and returns what changed. assert checks what the user sees, and waits briefly for something that loads.

There's more for harder cases: time pause and time advance 3000 control the page's clock, net offline and net drop test what happens when the connection goes, set Cart.coupon '"SAVE10"' jumps to a state, and logs returns the page's errors with the component they came from. weft browser help lists them all. With no browser open, weft browser launch starts a headless Chrome.

An agent with its own browser tool can skip the CLI: every page in dev has __weft__.agent, and await __weft__.agent.run('snapshot') is the same command. That needs @testing-library/dom and @testing-library/user-event in the app, which the testing setup adds.

3. Keep it: weft browser record

What the agent just did by hand can become a test. record start, then the acts and asserts, then:

bash
npx weft browser record code --component Cart --from ./Cart --out src/Cart.test.tsx

writes them as a @weft-js/core/test test.

4. Prove the test: weft test --gate

A test that passes isn't proof of anything if it would also have passed before the change. The gate checks the tests on the diff:

bash
npx weft test --gate
  • T010: each new or changed test must fail on the code from before the change.
  • T011: each new test must catch at least one deliberate mistake ("mutant") in the lines that changed. A mutant it misses comes back with what to assert.
  • T020: no existing test may be deleted, skipped or loosened without a // weft-allow T020: <reason>.

The gate works in scratch copies, so your working tree is never touched. --base main compares against a branch instead of the uncommitted change. The verify reference has every option.

weft mcp: weft's tools over MCP

Agents that speak the Model Context Protocol can use weft as a set of tools instead of shell commands. weft mcp is an MCP server on stdio. Most clients take a block like this in their MCP settings:

json
{  "mcpServers": {    "weft": { "command": "npx", "args": ["weft", "mcp"] }  }}

If the client starts it from another folder, add "--root", "path/to/my-app" to args.

The tools are the commands on this page:

ToolSame as
docsweft docs <topic or code>
checkweft check, optionally on some files
mapweft map
tasksweft tasks
routes_metaweft routes --meta: every route's title, description, image and H-diagnostics
style_find, style_explainweft style find and weft style explain
surfacesThe app's canvas and WebGL surfaces
test_gateweft test --gate
browser_tabs, browser_launch, browser_open, browser_snapshot, browser_act, browser_assert, browser_state, browser_time, browser_net, browser_record, browser_logs, browser_screenshotweft browser …

Each tool returns the same JSON as the command's --json, so what you learn from one works in the other.

--json everywhere

Every weft command takes --json and --root <dir>. They follow one convention, so a script or an agent can rely on it:

  • JSON goes to stdout, and text for people goes to stderr. With --json, stdout holds nothing else.
  • The exit code is 0 when all is well, 1 when there are errors (or, for agents-md --check, a stale file), and 2 for a usage error or a failure in weft itself. A failure still prints { "ok": false, "error": { "code", "message" } }.
  • Diagnostics have one shape in every command: code, severity, file, span, why, fix and docs.
bash
npx weft check --json > check.jsonnpx weft routes --meta --jsonnpx weft tasks --json
Deep diveWhy weft's diagnostics are written for agents

An agent fixes what it's told about. A compiler error written for an expert ("invalid hook call") sends it searching; one that names the variable, says what happens at run time, and gives the line to write gets fixed in one step. So each weft diagnostic is written about the code in front of it ("total is a box; JSX needs its value"), has a stable code the agent can look up with weft docs, and carries the edit when there is one, marked safe or not. The safe ones, weft fix applies; the others an agent has to decide on, and the why gives it what it needs to decide.

The same thinking runs through the rest. AGENTS.md is generated, so it never describes a weft you don't have. Codes that the installed compiler doesn't report yet say so, so an agent doesn't trust a check that isn't there. The test gate exists because an agent can write a test that passes without testing anything, and T010 and T011 catch exactly that.

None of this is only for agents. A message that's specific enough for a program is clear for a person too.

Recap

  • AGENTS.md is generated from your installed weft and your config. Regenerate it with weft agents-md, check it in CI with --check, and never edit it by hand.
  • weft docs is the reference in the terminal, weft docs <CODE> explains any diagnostic, and .weft/map.md says what this app has.
  • The verify loop: weft check --json and fix, see it work with weft browser, record a test, and pass weft test --gate.
  • weft mcp offers the same commands as MCP tools, returning the same JSON.
  • Every command takes --json: JSON on stdout, text on stderr, and exit codes 0, 1 and 2.

That's the end of Get started. Next, Describing the UI begins the tour of weft itself.