@leafphp/kata
v0.1.0
Published
Taste as a build step. Kata checks your copy for generated-text tells the way a linter checks your code.
Maintainers
Readme
@leafphp/kata
Taste as a build step. Kata checks the copy in your project for generated-text tells the way a linter checks your code: it extracts human-readable text from your components and content, runs it against a rule registry, and fails the build with a file and line number when a tell slips in.
npx @leafphp/kata init
npx @leafphp/kata check
npx @leafphp/kata fixfix applies the fixes that are mechanical (dash punctuation, including HTML
entities; numeric ranges become hyphens) and returns everything else as a
rewrite worklist with guidance per finding. Tells that live in sentence
structure cannot be patched by a tool without butchering the copy; they have to
be rewritten, by you or by the agent that ran the command.
How it works
Kata never lints raw source. Extractors pull copy out of each surface (JSX text nodes, string literals that read as prose, markdown outside code fences), so class lists, imports, and identifiers cannot produce false positives.
Rules come in three tiers:
- deny: deterministic patterns that block the build (em dashes, negation reframes, suspense reveals, anthropomorphic flourish).
- density: constructions that are fine occasionally and a tell at saturation, counted against document length (triads, fragment-pair closers).
- judge: checks that need a model to evaluate (mirrored antithesis, facts auditing against your declared sources). These run on Kata Cloud; the local report always names the judge rules it did not check, so a green check never overstates its coverage.
Configuration
Kata reads a kata: key in alchemy.yml when present, otherwise kata.yml:
surfaces:
- "app/**/*.{ts,tsx}"
- "content/**/*.{md,mdx}"
rules:
preset: leaf-writing
disable: [fragment-pair-closer]
options:
triad-saturation: { max: 3, per: 1000 }
custom:
- id: no-internal-codenames
tier: deny
summary: Internal codenames never ship in copy.
pattern: "\\b(?:craftly)\\b"Predefined rules are enabled by preset or id, so most configs stay a few lines.
Run npx @leafphp/kata rules to list the registry.
For agents
If you are an AI agent writing copy in this project: run
npx @leafphp/kata check before handing off. Fix every finding by rewriting
the sentence, not by paraphrasing around the pattern.
