Examples

Jev in n8n and design systems

Something gets made, by an agent or a person, and a small call decides what happens next: which n8n branch, which component, whether a button breaks a rule. Jev makes those calls in about 200 ms and says how sure it is, so a person or a bigger model only steps in when it isn't.

Data: n8n's public template library, plus a real desktop app's UI kit (components/ui), its design rules (DESIGN.md) and its git history · 309 Jev calls, $0.011 · the code and results are in design/

Where it fits

Jev doesn't write code. It answers small multiple-choice questions about things that already exist, so it handles the decisions around the model that does:

WhenThe questionType
Before generatingWhich existing component should this frame become?choice over the kit
While generatingWhich variant, token or icon fits this spot?choice
After generatingDoes this break a rule in DESIGN.md?noul per rule
In n8nWhich branch does this item take?choice, feeding a Switch
01 · n8n

Swapping the LLM classifier for one HTTP node

The most common AI pattern in n8n's templates is trigger, LLM classifier, parse JSON, Switch. In "Classify and route DevOps chat requests with Mattermost and Claude", the classifier is a Sonnet agent with a 5,280-character prompt, then an 85-line Code node to dig the JSON out and validate it.

Jev uses the template's 7 categories as its options. On 28 new DevOps messages:

RightMedian timeCost for all 28
The template's Sonnet classifier28 / 282.1 s$0.151
One Jev choice28 / 28180 ms$0.0014

Same answers, about 106× cheaper and 12× faster, with no parser. Jev's three least confident answers were the three truly borderline messages, which is where an "Ask a human" branch belongs:

  • “how do I get read access to the prod replica?”: question at 0.54
  • “Let's move our secrets from env files to Vault properly, we've never had it”: new_system at 0.66
  • “the release workflow can't push the image, 403 from the registry”: ci_cd_error at 0.89

A workflow you can import

design/n8n/jev-router.json imports straight into n8n: Webhook, an HTTP Request to Jev, then an If on confidence ≥ 0.6 before the Switch, with low-confidence items going to "Ask a human". The Jev node takes about 247 ms; for a deploy stuck waiting on a runner it returns ci_cd_error at 0.95.

// all the "AI" in the workflow is this one HTTP Request node
POST https://openrouter.ai/api/v1/systemone
{ "model": "~typesafe/jev-latest",
  "state": { "message": "{{ $json.message }}" },
  "questions": { "category": { "type": "choice", "criteria": { …the template's categories… } } } }
// Switch on {{ $json.answers.category.choice }}; If on .confidence

n8n's built-in Text Classifier does the same with any chat model, but without a confidence, so unclear items can only be dropped or sent to "Other".

02 · Design system · linting

Linting the rules a regex can't check

The app's DESIGN.md says "Do not tip menu triggers" and "Do not tip close / dismiss X buttons". A regex can't tell what a button does, but two yes/no questions per <Tip> can. Across all 53 Tips:

TooltipRule it breaksJevWhere
Clearclose / dismiss0.92keybind-settings.tsx
Voice chat engineopens a menu0.92start-voice-button.tsx
New…opens a menu0.94roster-pane-toolbar.tsx
Clear searchclose / dismiss0.95search-field.tsx

All 4 are real violations. "Clear search" lives in SearchField, so every search box inherits it. A fuzzier question, "does hovering teach something new?", gave muddy scores because it depends on surrounding context. Keep the linter to precise questions.

In a workflow it runs after the coding agent, one call per changed Tip, and anything at 0.8+ becomes a review comment quoting the rule.

03 · Design system · icons

Does the icon say what the label says?

DESIGN.md asks you to "reuse the existing icon for an action." One noul per icon-only button asks whether the icon says what its label says. 12 of 33 pairs score 0.8 or above. The lowest:

IconLabelFitsJev would pickWhere
discardRestore checkpoint0.06refreshuser-message.tsx
kebab-verticalNew branch0.09addcoding-row.tsx
watchManage0.22watchcron-jobs-section.tsx
discardReset to default0.28refreshkeybind-settings.tsx
discardReset HUD size and position0.28screen-normalcontrols.tsx
addStage all0.30check-allindex.tsx

These are review candidates, not bugs. The clearest is "New branch" on a kebab icon, which says "more". The discard rows are a naming question: the app uses discard for revert and reset, where Jev expects refresh. One line in DESIGN.md would settle it.

04 · Design to code · while generating

Which Button variant goes here?

A design-to-code agent picks <Button variant="…"> constantly. Here are 166 Buttons from the app with variant removed, put to one choice over the 8 variants, described in button.tsx's own words.

ConfidenceButtonsMatched the code
0.9 or higher3795%
0.6 to 0.93330%
below 0.69621%

Only 39% match overall, since ghost versus text depends on context the snippet lacks. But confident picks are almost always right (37 at 95%), so take those and let the agent check neighbours otherwise.

05 · Design to code · before generating

Building on the component that already exists

Design systems drift when someone hand-builds a copy of an existing component. For 26 commits that cleaned this up, the removed markup is the state and the 45 components/ui primitives are the options.

Jev's first pick matches the commit 7 of 26 times, its top three 10 of 26, and at 0.9+ it's right 7 of 11:

  • scope pane fallback menus to the clicked content: actions-menu at 0.92
  • every settings row renders through one ListRow/ToggleRow/Slider/SearchField: search-field at 0.97
  • one identity chip behind every avatar: avatar-chip at 0.93
  • let ConfirmDialog carry a secondary action: confirm-dialog at 1.00
  • route cron delete and review revert through ConfirmDialog: confirm-dialog at 1.00

So it's a hint, not a gate. It reliably catches rebuilt ConfirmDialogs, AvatarChips and SearchFields, the most common kind, and misses when the answer depends on purpose rather than markup. Figma frames share that limit, so send the frame name and notes too.

Figma: the Dev Mode MCP's layer tree would go in state, with the kit as options. Untested: it needs the desktop app with a file open.

Putting it together

A design-to-code workflow with Jev at each decision:

Trigger: Figma frame / PR opened
  └─ Gate · Jev choice   which kit components? (≥0.9: pass them as hints)
      └─ Agent           writes the code, using those components
          └─ Gate · Jev noul × DESIGN.md rules   tip on a dismiss button? hand-built dialog?
              ├─ all clear: Agent opens the PR
              ├─ confident violation: Agent fixes it and loops back
              └─ unsure: Human, a designer reviews the flagged spots

What to build first:

  1. The n8n swap (01). Same answers, far cheaper, and it imports as-is.
  2. The DESIGN.md linter (02). One noul per rule, on every agent's diff. Found 4 violations.
  3. Component hints (05). Feed the top three picks into the coding agent's prompt.