Skip to content
Velocity Velocity
View Docs
astro release ai agents skills

Velocity 2.4: Built for Agents, Checked Before You Ship

A new check:agent command catches the mistakes AI coding agents make, plus a component reference, four new skills and an open agent benchmark. Here's what's new and how to get it.

S

Southwell Media

7 min read

An AI coding agent can add a Pricing page to an Astro site in a couple of minutes. Building fast isn’t the hard part anymore. The hard part is whether the result holds up: whether the page is accessible, whether its scripts survive the Content Security Policy, whether every language gets its copy, and whether the next upgrade quietly undoes the work.

Most of those failures are invisible. The build passes, the page looks right in English, and the agent reports that it’s done. A week later you find a raw translation key on the Spanish page, or a button that does nothing because CSP blocked its handler.

Velocity 2.1 gave agents the rules. Velocity 2.4 checks that they followed them.

check:agent: an agent-ready check

Every project now has one command that reads the source and the build, and reports what agents typically get wrong:

npm run check:agent

To test it, we planted typical agent mistakes in a fresh project: a Pricing page with a missing translation key, an onclick handler, a link to a page that doesn’t exist, an edited Velocity file and some hardcoded copy. All of them were caught. Here’s part of the output:

✖ i18n/missing-key (1)  .agents/velocity.md → Rules → No hardcoded user-facing strings
  src/views/PricingView.astro:8  t('pricingPage.title') has no English string, so the page shows "pricingPage.title".
  fix: Add pricingPage.title to src/i18n/translations/en.ts (under `pricingPage`), then to each other locale's file.
✖ csp/inline-handler (1)  .agents/velocity.md → Rules → CSP is on
  dist/client/pricing/index.html:22  <button onclick="…"> is an inline event handler; CSP blocks it.
  fix: Remove onclick and add the listener in the component's <script> with addEventListener, guarded for astro:after-swap.
✖ links/broken (1)  .agents/velocity.md → Rules → Internal links
  dist/client/pricing/index.html:22  <a href="/checkout"> points at a page or file the build doesn't contain.
✖ check:agent: 4 error(s), 6 warning(s)

Every finding names the file and line, the rule in .agents/velocity.md that it breaks, and the fix. That’s written for the agent as much as for you. It can read the output, fix the problem and run the check again, without guessing what “broken” means.

Rule What it catches Severity
i18n/missing-key, i18n/raw-key A t() key with no English string, or a raw key rendered in the built page error
csp/inline-handler, csp/unhashed-script, csp/javascript-url Inline handlers, javascript: URLs, and inline scripts that don’t match the page’s CSP hashes error
links/broken Internal links to pages, files or #anchors the build doesn’t contain error
forms/stub Contact and newsletter Actions that still report success without sending anything warning
ownership/edited Edits to files Velocity replaces on upgrade warning
strings/hardcoded User-facing text written straight into views, components and layouts warning
i18n/untranslated Keys an enabled language falls back to English for warning

Errors fail the check. Warnings are worth fixing or explaining: every new project starts with stubbed forms, for example, so that one can’t be an error. Add --strict to treat warnings as errors, or --json for machine-readable output.

check:agent runs at the end of npm run validate and in the deploy workflow every project ships with, so a mistake fails CI instead of reaching production. .agents/velocity.md also gains a “Before you say you’re done” section that tells agents to run it.

It found a real bug in Velocity, too: PasswordInput had a hardcoded English aria-label on its show/hide button. In 2.4 it’s translated into English, Spanish and French.

A component reference agents read first

Agents write a new component when they don’t know one already exists. .agents/components.md is a generated reference for all 46 entries in Velocity’s component registry. For each one, it lists:

  • What it’s for, and what to use instead when it’s the wrong fit
  • Its props with defaults, its variants and its slots
  • The import path and a working example

It’s generated from the registry, the variant files and the prop types, so it can’t drift. A stale file fails Velocity’s tests, and every example is compiled in a unit test. The velocity-add-page and velocity-add-component skills read it before they read the source.

Four new skills

2.1 shipped two skills. 2.4 adds four more, for the tasks people ask agents to do most once the pages exist:

Skill What it does
velocity-rebrand Brand color, theme, fonts, logo, favicon, site name and share-image color, through design tokens instead of raw colors
velocity-connect-forms Connects the contact and newsletter forms to a real provider (Resend by default), with secrets in astro:env
velocity-add-locale Adds a language with a complete translation file, translated URL slugs and hreflang checks
velocity-add-content Writes a blog post with valid frontmatter, or adds a content collection with its own pages, search indexing and share images

Two details are worth calling out. velocity-connect-forms never reports a form as working without a real send: with no API key, it stops and asks you for one. And velocity-add-locale closes a real gap. Velocity’s built-in UI strings are only translated into English, Spanish and French, and that file is replaced on upgrade, so for any other language the skill has your agent translate them in your own translations file.

That makes six skills, in both .agents/skills/ and .claude/skills/.

An open agent benchmark

We think these files make agents better at building Velocity sites. That’s a claim, so we built a way to test it, and we’re publishing the harness before the results.

The benchmark in Velocity’s benchmark/ folder gives the same six plain-language requests to an agent in three kinds of project:

  • Velocity
  • Velocity without its agent files: the same code with AGENTS.md, .agents/ and .claude/ removed. Comparing it with the first arm isolates what the agent files add.
  • Plain Astro, from npm create astro

The six tasks are a pricing page, an FAQ page, a rebrand, a Spanish version, a working contact form and a blog post. They’re written the way a non-expert would ask, and they never mention Velocity or Astro. Every arm uses the same agent and the same pinned model, with five repeats by default.

An independent scorer grades the built site in a real browser. It doesn’t use check:agent, and it never looks at file paths or Velocity conventions. It reports neutral metrics (task checks, build, axe accessibility on desktop and mobile, broken links and cost) separately from the ones that favor Velocity by construction, such as CSP. A self-test checks the scorer without calling a model. It includes a plain Astro site that solves all six tasks, to show they can be done without Velocity.

We don’t have results yet. When we do, we’ll publish every complete run, including any where Velocity looks worse. Until then, you can run it yourself:

git clone https://github.com/southwellmedia/velocity
cd velocity
pnpm install
pnpm bench:selftest           # checks the scorer, no model calls
pnpm bench --model <model-id> # 6 tasks × 3 arms × 5 repeats

The benchmark README covers the requirements, the options and how to read the results. If you think a task or a check favors Velocity, open an issue. Tasks from people outside the project are welcome.

Get it

Start a new project:

npm create velocity-astro@latest

Or upgrade an existing one:

npm create velocity-astro@latest upgrade

The upgrade adds check:agent, the component reference and the new skills, and puts the check at the end of your validate script. If you customized validate, append && node scripts/check-agent.mjs to it yourself.

The upgrade also records .velocity/baseline.json, a fingerprint of the files Velocity owns, so the check can warn when an agent edits one; commit it. That takes create-velocity-astro 2.1, which @latest gives you. With an older CLI, record it yourself once:

npm run check:agent -- --write-baseline

Your contact and newsletter Actions belong to you, so the upgrade leaves them alone. Since 2.3 they forward to CONTACT_FORM_ENDPOINT and NEWSLETTER_ENDPOINT when those are set, and check:agent warns until they are, or until you wire a provider with the velocity-connect-forms skill.

Then ask your agent to build something, and run npm run check:agent before you take its word that it’s done. The AI agents guide covers the rest.

Back to Blog
Share:

Related Posts