The CLI
Every command and flag, the exit codes, and the JSON that —json prints.
yuanme runs in the project’s folder, the one with yuanme.toml, or in the folder -C DIR names. Every command that reads the project first writes these docs to .yuanme/docs/ when they are for another version of yuanme.
Starting a Site
yuanme init DIR creates a Site in DIR, or in the current folder without one, from a Starter. It asks nothing, so it runs the same for a person and for a coding agent. --starter picks one:
blog, the default: a personal site. Its Collections areposts, paginated at/blog/, andprojects, with atagsTaxonomy, an about Page in the built-inpagesCollection, a home Page, a 404 Page and an RSS feed. Its two Posts, one in Markdown and one in Org, show an equation with a Label, a Theorem block, a reference to each and a highlighted code block, and its project is an Entry folder with an image beside it. Its one stylesheet,styles/site.css, is plain CSS with its colours and fonts as custom properties, light and dark. Its one Script, the Sidecartemplates/components/code-copy.ts, puts a copy button on each code block, and its types are checked ([typescript] check = true, with atsconfig.json). Moving between its Pages is a View Transition with no JS ([router] mode = "native").minimal:yuanme.toml, a Layout, a home Page, a 404 Page and a stylesheet, to build your own design from.
Each builds with no Diagnostic under yuanme build --strict-budgets, and passes axe-core’s accessibility checks in light and dark. Its files are yours under MIT-0: change or delete any of them. yuanme.toml starts with two lines that init writes:
#:schema ./.yuanme/schemas/yuanme.toml.json, which editors with a TOML language server, such as Taplo or Tombi, read to complete and check keys.yuanme = "X.Y", the yuanme release the project needs, whichcheckholds every later release to.
With --host ADAPTER, it also sets [host] adapter and writes that host’s GitHub Actions deploy workflow and files, which yuanme docs deploying describes.
It also writes the files a coding agent reads:
AGENTS.md, with a block between<!-- BEGIN:yuanme -->and<!-- END:yuanme -->that teaches the commands to run, the mistakes to avoid and where the docs are. AnAGENTS.mdof yours keeps its text and gains the block at its end.CLAUDE.md, which holds@AGENTS.mdso Claude Code reads it, unless you have one.- Two skills,
yuanme-verify, the check, build and look loop, andyuanme-migrate, for bringing a site in from Astro, Hugo, Jekyll or Zola. They are in.agents/skills/and, for Claude Code,.claude/skills/. .gitignore, with.yuanme/and the output directory, or those two lines added to yours..yuanme/: these docs, the JSON Schemas and the types for Scripts, which every command rewrites.
yuanme dev, build and check keep the block and the skills in step with the yuanme that runs them, and say what they rewrote:
- When another version wrote the block, they rewrite it, and nothing else in
AGENTS.md.[agents] manage_agents_md = falsein Site config turns that off. - They rewrite a skill another version wrote, unless you edited it, which they tell from the hash in its
metadata. An edited skill is yours from then on. - They never make a file you removed, and never touch
CLAUDE.md.
init never overwrites a file. If any file it would create is already there, it lists them all, exits 2 and changes nothing. A folder that holds other files, such as a Git repository’s, is fine.
Output
What yuanme prints depends on where it goes, never on guessing who runs it:
- On a terminal: Diagnostics with the lines they are about, in colour, and a summary.
- Into a pipe or a file: one line per Diagnostic, as
path:line:column: error[code]: message, and no colour. - With
--json: one JSON object per line on stdout, and nothing else there. Use it from a script or an agent.
Human text always goes to stderr, so stdout holds only what a command prints as its result, such as yuanme routes’s table or a schema.
Exit codes
0: success. Warnings are allowed.1: the Site has errors.2: the command can’t be carried out as written: a bad flag, noyuanme.toml, a name that matches nothing, or a fileinitornewwould overwrite.101: yuanme failed, such as when it can’t write a file, or crashed.
--json
Each line is one event with a type:
diagnostic: one Diagnostic, shaped like rustc’s:level,code,message,spanswith byte offsets and 1-based lines and columns,childrenwith help and suggested edits,docsandrendered. Apply a suggestion whoseapplicabilityismachine-applicableas it is.build-startedandbuild-finished: aroundbuild,checkand each build ofdev;build-finishedhasok,duration_ms,pages,changed_urlsand the counts of errors and warnings.server-ready:yuanme devis serving, aturl, from the processpid.reload:yuanme devtold browsers to reload the Pages aturls.browser-console: a browser onyuanme devlogged something or threw an uncaught error.dev-status: fromyuanme dev status, whether a dev server runs for the project, and if one does, where, and its last build as/__yuanme/statusreturns it.yuanme dev stopprints one once it has stopped.route: one line ofyuanme routes.site-created: whatyuanme initwrote: the Site’sdir, itsstarter, thehostof--host, the files itcreated, and the files of yours itupdated.entry-created: whatyuanme newwrote.schema: whatyuanme schemaprints.docs: a page of these docs.
yuanme schema events prints the JSON Schema of every event. A later release may add fields, but renames and removes none before 2.0.
The dev server
yuanme dev builds the Site with its Drafts, serves it on http://127.0.0.1:4590/, or the next free port, and builds it again on every save. Read the URL from server-ready or .yuanme/dev.json rather than assuming the port.
- Everything is in memory. Nothing is written to the output directory, which never holds Drafts.
- Every save rebuilds the whole Site, in milliseconds, and what changed is shown in the browser without a reload where it can be: a stylesheet is swapped where it is, and with the Router on, a Page is swapped in place, keeping its scroll and what the Site keeps between Pages, and its Sidecar scripts are mounted again, their new code included. Any other change, such as to a Site Script, is a full load. What it serves is what
yuanme build --draftsmakes, but for two things that would slow a save: an image is encoded when a browser first asks for it, and math uses the whole math font rather than a subset. A small dev-only script is added to each HTML file as it is served. - An error keeps the last good build served, with an overlay on the Page that shows its Diagnostics until a save fixes it. They are printed too, as
buildprints them. With[typescript] check = true, types are checked after each build that succeeds, and the overlay shows the type errors. - What a browser logs reaches the terminal: console output and uncaught errors, as
browser-consoleevents with--json. --write DIRalso writes each build that succeeds toDIR, from the project root, for a tool that wants the files. It holds Drafts, so it can’t be the output directory. Images are encoded only when a browser asks for them, so it has none of their variants, and its Pages have no dev script.--polllooks at every file every 100 ms, for file systems that never say a file changed, such as some network and container mounts.
One dev server runs for a project. While it runs, .yuanme/dev.json says where: its pid, port, url, Engine version, when it started, and its log. Another yuanme dev prints its URL, as server-ready, and exits 0 rather than starting a second.
yuanme dev --backgroundstarts it in a process of its own and returns once the first build has finished, with that build’s Diagnostics andserver-ready. It exits 1 if that build failed, but the server runs on, and serves the Site once a save fixes it.yuanme dev statussays whether one runs, where, and how its last build went. With--json, that is onedev-statusevent.yuanme dev logsprints what the server started with--backgroundprinted, which is in.yuanme/dev.log, in the form it was started with.--followgoes on printing until it stops.yuanme dev stopstops it, and returns once it has saved its cache. Stopping when none runs is no error.GET /__yuanme/statuson the server returns its last build:build-finished’s fields, and itsdiagnosticsas--jsonprints them.
Working with an agent
The loop is: edit, run yuanme check --json, and fix each Diagnostic by its code, applying its suggested edits where they are machine-applicable. To look at the Site, start yuanme dev --background --json once; yuanme dev status --json then gives its last build. yuanme docs CODE explains a code; yuanme routes --json finds which file makes a URL; yuanme schema gives the shape of Site config, of each Collection’s front matter and of what each Template sees.
Reference
Global options
--json: Print NDJSON events on stdout, one per line. Human text, if any, goes to stderr.-C DIR: Run as if yuanme was started in DIR.--color COLOR: Colour human output.autocolours it when stdout is a terminal. One ofauto,always,never. Defaults toauto.-q, --quiet: Print only errors.-h, --help: Print help.-V, --version: Print version.
yuanme init
Create a Site from a Starter, with the files coding agents read. It overwrites no file.
yuanme init [OPTIONS] [DIR]
DIR: The Site’s folder, which may hold other files already. Defaults to the current one.--starter STARTER: The Starter to begin from. One ofblog,minimal. Defaults toblog.--host HOST: Deploy to this host: set[host] adapter, and write its GitHub Actions deploy workflow and files. One ofcloudflare,netlify,vercel,github-pages,cloudflare-pages,static.
yuanme build
Build the Site into the output directory.
yuanme build [OPTIONS]
--drafts: Include Drafts.--strict: Make every warning an error.--strict-budgets: Make every warning about a Site budget an error, asbudgets.strictdoes.--clean: Empty the output directory first, files yuanme didn’t write included.--out DIR: The output directory, from the project root. By defaultdist, or.vercel/outputwith the vercel adapter.
yuanme check
Report every Diagnostic build would, rendering every Page in memory and writing none.
yuanme check [OPTIONS]
--drafts: Include Drafts.--strict: Make every warning an error.
yuanme dev
Serve the Site with its Drafts from memory, and rebuild it on every change.
yuanme dev [OPTIONS]
yuanme dev <COMMAND>
--port PORT: The port on 127.0.0.1. By default 4590, or the next free one.--poll: Look for changes every 100 ms instead of being told of them, for file systems that tell nothing, such as some network and container mounts.--background: Run in the background, and return once the first build has finished.yuanme dev status,logsandstopmanage it.--write DIR: Also write each build that succeeds to DIR, from the project root, for a look at its files. Never the output directory: dev includes Drafts.
yuanme dev status
Say whether a dev server runs for the project, where, and how its last build went.
yuanme dev status [OPTIONS]
yuanme dev stop
Stop the dev server running for the project.
yuanme dev stop [OPTIONS]
yuanme dev logs
Print what the dev server started with --background printed.
yuanme dev logs [OPTIONS]
--follow: Go on printing what it prints until it stops.
yuanme new
Create an Entry whose required fields are filled in, and print its path and Route.
yuanme new [OPTIONS] <COLLECTION> <TITLE>
COLLECTION: The Collection, by its name in yuanme.toml.TITLE: The Entry’s title, from which its Slug and file name come.--format FORMAT: The Source format. One ofmd,org. Defaults tomd.
yuanme routes
List every Route and what produces it.
yuanme routes [OPTIONS]
--drafts: Include Drafts.
yuanme schema
Print a JSON Schema.
yuanme schema [OPTIONS] <COMMAND>
yuanme schema config
Site config, yuanme.toml.
yuanme schema config [OPTIONS]
yuanme schema entry
The front matter of a Collection’s Entries.
yuanme schema entry [OPTIONS] <COLLECTION>
yuanme schema data
A Data file that [data.NAME] declares.
yuanme schema data [OPTIONS] <NAME>
yuanme schema context
What a kind of Route’s Template sees: entry, list, term, index, template or feed.
yuanme schema context [OPTIONS] <KIND>
yuanme schema events
The events --json prints.
yuanme schema events [OPTIONS]
yuanme docs
Print a docs page by topic or Diagnostic code; with none, the index.
yuanme docs [OPTIONS] [TOPIC]
TOPIC: A topic, such astemplates, or a code, such asentry/unknown-key.