The config file now tells your editor what belongs in it — and tells Poops, which no longer lets a key misspelt inside a block pass in silence. It also stops calling a companion package's block a mistake. Separately, `llms` was the one index feature that could not turn itself on, and the corpus it writes carried the machinery of the pages it was made from.
A JSON Schema for poops.json, so the editor catches a typo you would
otherwise find in the output. A top-level "stlyes" was warned about and
ignored, and a mistyped script option reaches esbuild, which rejects it — but
"minfiy" in a style's options is read by nothing and warned about by nobody.
The build stays green and the .min.css is never written.
Poops now ships schema/poops.schema.json, covering every key, with the
documentation for each one inline. Point $schema at it and the editor
completes and validates as you type:
{
"$schema": "./node_modules/poops/schema/poops.schema.json"
}
The same file is published at
https://stamat.info/poops/poops.schema.json
for a project that has not installed Poops yet, and can be attached by
filename from VS Code's json.schemas setting instead of by editing the
config. The $schema key is inert to Poops — it is recognised and otherwise
ignored, and nothing was added to what Poops installs into your project.
The schema is hand-written, so Poops' own test suite holds it to the code: it
is validated against the draft-07 meta-schema, and poops.json plus every
complete config example in the README and on the documentation site is
validated against it, so an example that stops being valid config now fails
the build.
A key misspelt inside a block is now named too. The unknown-key warning
stopped at the top level: "stlyes" was caught, "inn" in a styles entry was
not. That entry compiled nothing, poops -b exited 0, and the file that never
appeared was the only sign. Poops now checks every block it owns against the
schema it ships, at startup:
[info][warn] Unknown key "inn" in styles[0] — ignored. Valid: in, out, options
Key names only, and only where Poops owns them: images belongs to
poops-images, site is yours to name, and a companion's top-level block is
left alone — an unrecognised key in any of those passes without comment.
Types are not checked, so "minify": "yes" still reaches the compiler and
fails there. exec keeps its own warning, which says the more useful thing —
that the stage never runs. The schema read is the copy inside
node_modules/poops, so where $schema points changes nothing.
The walk is unknown-keys, a new dependency and the only one this release adds — zero dependencies of its own, written for this and published separately because poops-images and septic read the same file and want the same warning.
A top-level key naming a package you depend on is no longer called
unknown. poops.json is shared — septic
reads a septic block out of the same file — but every build printed
Unknown config key "septic" — ignored, a warning about something working
exactly as designed. The name is now checked against your dependencies,
devDependencies, peerDependencies and optionalDependencies first, and a
match passes in silence. Declaring the package is enough; Poops still never
loads it or reads its block. Nothing by that name declared, and the warning
is unchanged — which is what still catches "stlyes".
Your editor cannot see node_modules, so the schema cannot make that call: it
allows an object under any name it does not know and rejects everything else,
meaning "stlyes": [ … ] is flagged there but "srve": { … } is not. The CLI
catches what the editor lets through.
llms alone now generates its files. Page entries were collected only
when searchIndex, sitemap, nav or feed was configured, so a markup
config whose only index feature was llms compiled the site and wrote
nothing — no warning, no output. Pairing it with a sitemap was the
workaround; there is nothing to pair it with now.
llms-full.txt no longer carries a page's machinery. The corpus is built
from the Markdown source, which is read before the template engine runs, so it
held whatever the source held: template comments, tags and output expressions,
and every inline <style> and <script> on the page. A page that wraps its
body in a {% set body %}…{% endset %} capture and styles itself in a
<style> block could hand an LLM more plumbing than prose. All of it is
stripped now, and the prose a capture wrapped stays. Fenced blocks, inline
code spans and bodies are left alone — a sample documenting
template syntax is content. A feed's article HTML is built from the same
stripped source.