Skip to content

AI Coding Agents

Velocity isn’t an agent, and it doesn’t decide what your site looks like. It gives the agent you already use, such as Claude Code, the rules, skills and checks it needs to follow Velocity’s conventions without you explaining them:

  • Rules: AGENTS.md and .agents/velocity.md describe the stack, the commands and which files upgrades replace.
  • Skills: seven step-by-step guides, from setting up the whole site to adding a page or connecting the forms.
  • Component reference: .agents/components.md lists all 46 components, so agents reuse them instead of writing new ones.
  • A check: npm run check:agent finds the mistakes agents make that the build lets through, and tells the agent how to fix each one.
FilePurposeOn upgrade
AGENTS.mdYour project’s rules, plus a pointer to Velocity’sLeft alone
CLAUDE.mdImports AGENTS.md for Claude CodeLeft alone
.agents/velocity.mdVelocity’s stack, commands, rules and file ownershipReplaced
.agents/components.mdReference for every component Velocity shipsReplaced
.agents/site.mdYour site brief, written by the CLI and your agentLeft alone
.agents/skills/velocity-*Skills for common tasksReplaced
.claude/skills/velocity-*The same skills, in the folder Claude Code usesReplaced
scripts/check-agent.mjsThe agent-ready checkReplaced
.velocity/baseline.jsonVelocity-owned files as they were at scaffold or last upgradeRewritten by the CLI

Add your own rules to the Project notes section of AGENTS.md.

Create an own-site project, open it in your agent and ask:

Set up this site for my business.

The velocity-start-site skill then:

  1. Asks up to seven questions it can’t answer from your request: the business, the audience, the main action, the pages, languages, the look you want, and any existing site to take facts from.
  2. Writes a brief to .agents/site.md and shows you the sitemap before building.
  3. Prepares the project: removes the demo if there is one, sets your site’s name and contact details, and applies your colours, fonts and logo with velocity-rebrand.
  4. Builds your pages with the other skills, using Velocity’s components where they fit and writing new ones where they don’t.
  5. Writes real copy in every enabled language. Anything it doesn’t know, such as prices or opening hours, becomes a [[placeholder: …]] instead of a guess.
  6. Checks its work with npm run validate and hands off with a list of placeholders and assumptions to confirm.

You don’t have to use it. Velocity is a starter kit: build by hand, use your own components, or ask your agent for anything else.

.agents/site.md is the project’s memory: the business, audience, voice, brand, sitemap, facts, placeholders, assumptions and a dated decisions log. Later sessions read it first, so your agent builds on earlier decisions instead of starting over. The CLI seeds it with your site name, description, languages and starter pages, and leaves every other heading for the agent to fill with you. Upgrades never touch it. Edit it like any other file.

Velocity is tested with Claude Code, which reads CLAUDE.md and loads skills from .claude/skills/. Codex, Cursor and other tools that read AGENTS.md get the same rules, and AGENTS.md tells them where the skills are. How well a given tool follows them depends on the tool.

Skills are step-by-step instructions for a specific task. You don’t need to name them. Describe what you want, and a tool that supports skills can load the right one. If your tool doesn’t load skills automatically, AGENTS.md tells your agent to read the matching SKILL.md first.

SkillUse it by asking to…
velocity-start-siteSet up or rebuild the whole site for a business, from a brief to built pages, replacing the demo or starter content
velocity-add-pageAdd a page or route, with its view, locale wrappers, nav entry and translated copy
velocity-add-componentAdd, restore or customize a component, following its CVA variants, design tokens, i18n and upgrade rules
velocity-add-contentPublish a blog post with valid frontmatter, or add a content collection with its own pages, URLs, search indexing and share images
velocity-add-localeAdd a language, with a complete translation file, translated URL slugs, content and hreflang checks
velocity-connect-formsConnect the contact and newsletter forms to a real provider (Resend by default, or Postmark, a webhook or a newsletter service), with secrets in astro:env
velocity-rebrandChange the brand color, theme, fonts, logo, favicon, site name and share-image color

Each skill is in both .agents/skills/ and .claude/skills/, and the two copies are identical.

.agents/components.md is generated from Velocity’s component registry. For each of the 46 components it gives the import path, what it’s for, its props and variants, an example, and what to use instead when another component fits better. .agents/velocity.md tells agents to read it before building a component.

A project scaffolded with only some components still has the full reference. The reference tells the agent to check that the import path exists, and the velocity-add-component skill restores a missing component with its dependencies.

Terminal window
npm run build
npm run check:agent

check:agent scans your source and your build for mistakes that astro check and the build let through. Every finding names the file, the rule in .agents/velocity.md it breaks, and the fix, so an agent can act on it without asking you.

It runs at the end of npm run validate, and as its own step in the deploy workflow in .github/workflows/deploy.yml. It needs a build to scan: without one, it reports an error and asks you to build first.

Errors fail the check:

RuleFinds
i18n/missing-keyt('a.b') with no English string, so the raw key renders
i18n/raw-keyA translation key rendered as text in the build
csp/inline-handleronclick= and other inline event handlers
csp/unhashed-scriptAn inline <script> whose hash isn’t in the page’s CSP
csp/javascript-urlhref="javascript:…"
links/brokenAn internal link, asset or #anchor that doesn’t exist

Warnings are printed but pass:

RuleFinds
i18n/untranslatedKeys an enabled language doesn’t translate, so it falls back to English
i18n/single-locale-pageA page with no other-language versions on a multilingual site
forms/stubA form Action that tells visitors their message was sent but delivers nothing
ownership/editedA Velocity-owned file changed since scaffold or the last upgrade
strings/hardcodedUser-facing text written into a page, view or component
content/placeholderA [[placeholder: …]] marker or an empty MediaSlot image still on a page
config/default-identityThe scaffold’s name, author or email in site.config.ts, or a build that uses example.com because SITE_URL isn’t set
a11y/multiple-h1A page with more than one <h1>

The hardcoded-text check covers every .astro and .tsx file under src/, outside content, i18n, assets and styles. Velocity’s own files are skipped while they’re untouched. With a baseline, a Velocity-owned file you’ve changed, or a file you’ve added inside a Velocity folder, is scanned too.

Links to server-rendered routes, API endpoints, redirects in astro.config.mjs and sites with a base path aren’t reported as broken.

An agent asked for a pricing page wrote a view with a missing translation key, an inline onclick handler and a link to a page that doesn’t exist. npm run check:agent reported (output shortened):

✖ 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:24 <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:24 <a href="/checkout"> points at a page or file the build doesn't contain.
fix: Build internal links with localizeRoute()/localizePath() from @/i18n and check the route exists in src/config/nav.config.ts; for assets, use a file that exists in public/ or import it.
⚠ strings/hardcoded (3) .agents/velocity.md → Rules → No hardcoded user-facing strings
src/views/PricingView.astro:10 "Buy now" is written into the markup, so it won't translate.
...
✖ check:agent: 4 error(s), 5 warning(s)
CommandDoes
npm run check:agent -- --jsonPrints the findings as JSON, for scripts and agents
npm run check:agent -- --strictMakes warnings fail too
npm run check:agent -- --write-baselineRecords Velocity-owned files as they are now in .velocity/baseline.json

With pnpm, drop the --: pnpm check:agent --json.

.velocity/baseline.json records a hash of each Velocity-owned file. ownership/edited compares against it to warn when a change would be lost on the next upgrade. Commit the file.

create-velocity-astro 2.1 and later write it when you scaffold or upgrade a project. With an older CLI, run npm run check:agent -- --write-baseline once on a clean checkout. Without a baseline, the check skips this rule and says so.

Some warnings are deliberate. Add a comment to the file to opt out:

  • velocity-allow-hardcoded in a file that is deliberately single-language turns off strings/hardcoded for it.
  • velocity-single-language in a page in src/pages/ turns off i18n/single-locale-page for it. Blog posts are already exempt.
---
// velocity-allow-hardcoded: this landing page is English-only
---

Upgrades replace some files and never touch others. .agents/velocity.md lists both, so your agent knows where a change is safe. The list comes from files in velocity-manifest.json.

For example, new strings go in src/i18n/translations/<locale>.ts, because upgrades replace src/i18n/ui.ts. If a task requires editing a file Velocity owns, your agent is told to warn you, and check:agent reports the edit. The upgrade saves your version to .velocity-backup/, but you’ll need to reapply the change by hand.

Create a folder with a SKILL.md file:

---
name: add-case-study
description: Add a case study to the site. Use when asked to publish a new case study.
---
# Add a case study
1. Create the entry in `src/content/case-studies/`.
2. ...

Save it in .claude/skills/add-case-study/ for Claude Code, and in .agents/skills/add-case-study/ for other tools.

The Velocity repository includes a benchmark harness in benchmark/. It gives the same six plain-language tasks to an agent in a Velocity project, in the same project without its agent files, and in plain Astro, then scores the built sites in a browser. No results have been published yet. See benchmark/README.md in the Velocity repository to run it yourself. The harness isn’t copied into your project.

Upgrade to get the latest rules, skills and check:

Terminal window
npm create velocity-astro@latest upgrade
  • From 2.0: the upgrade replaces your old AGENTS.md once, because it contains outdated instructions. Your copy is saved to .velocity-backup/. If you added your own rules, copy them into the Project notes section of the new file. After that, upgrades leave AGENTS.md alone.
  • From 2.1 or later: the upgrade adds check:agent to the end of your validate script. If you customized validate, append && node scripts/check-agent.mjs yourself.

See Upgrading to 2.5 and Upgrading to 2.4 for the other steps.

Skills are committed with your project, so everyone working on it gets the same instructions. Only local Claude Code state in .claude/ is ignored.