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.mdand.agents/velocity.mddescribe 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.mdlists all 46 components, so agents reuse them instead of writing new ones. - A check:
npm run check:agentfinds the mistakes agents make that the build lets through, and tells the agent how to fix each one.
What’s in your project
Section titled “What’s in your project”| File | Purpose | On upgrade |
|---|---|---|
AGENTS.md | Your project’s rules, plus a pointer to Velocity’s | Left alone |
CLAUDE.md | Imports AGENTS.md for Claude Code | Left alone |
.agents/velocity.md | Velocity’s stack, commands, rules and file ownership | Replaced |
.agents/components.md | Reference for every component Velocity ships | Replaced |
.agents/site.md | Your site brief, written by the CLI and your agent | Left alone |
.agents/skills/velocity-* | Skills for common tasks | Replaced |
.claude/skills/velocity-* | The same skills, in the folder Claude Code uses | Replaced |
scripts/check-agent.mjs | The agent-ready check | Replaced |
.velocity/baseline.json | Velocity-owned files as they were at scaffold or last upgrade | Rewritten by the CLI |
Add your own rules to the Project notes section of AGENTS.md.
Set up your site
Section titled “Set up your site”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:
- 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.
- Writes a brief to
.agents/site.mdand shows you the sitemap before building. - 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. - Builds your pages with the other skills, using Velocity’s components where they fit and writing new ones where they don’t.
- 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. - Checks its work with
npm run validateand 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.
The site brief
Section titled “The site brief”.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.
Which agents
Section titled “Which agents”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
Section titled “Skills”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.
| Skill | Use it by asking to… |
|---|---|
velocity-start-site | Set up or rebuild the whole site for a business, from a brief to built pages, replacing the demo or starter content |
velocity-add-page | Add a page or route, with its view, locale wrappers, nav entry and translated copy |
velocity-add-component | Add, restore or customize a component, following its CVA variants, design tokens, i18n and upgrade rules |
velocity-add-content | Publish a blog post with valid frontmatter, or add a content collection with its own pages, URLs, search indexing and share images |
velocity-add-locale | Add a language, with a complete translation file, translated URL slugs, content and hreflang checks |
velocity-connect-forms | Connect 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-rebrand | Change 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.
Component reference
Section titled “Component reference”.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.
The agent-ready check
Section titled “The agent-ready check”npm run buildnpm run check:agentcheck: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.
What it checks
Section titled “What it checks”Errors fail the check:
| Rule | Finds |
|---|---|
i18n/missing-key | t('a.b') with no English string, so the raw key renders |
i18n/raw-key | A translation key rendered as text in the build |
csp/inline-handler | onclick= and other inline event handlers |
csp/unhashed-script | An inline <script> whose hash isn’t in the page’s CSP |
csp/javascript-url | href="javascript:…" |
links/broken | An internal link, asset or #anchor that doesn’t exist |
Warnings are printed but pass:
| Rule | Finds |
|---|---|
i18n/untranslated | Keys an enabled language doesn’t translate, so it falls back to English |
i18n/single-locale-page | A page with no other-language versions on a multilingual site |
forms/stub | A form Action that tells visitors their message was sent but delivers nothing |
ownership/edited | A Velocity-owned file changed since scaffold or the last upgrade |
strings/hardcoded | User-facing text written into a page, view or component |
content/placeholder | A [[placeholder: …]] marker or an empty MediaSlot image still on a page |
config/default-identity | The 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-h1 | A 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.
Example
Section titled “Example”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)Options
Section titled “Options”| Command | Does |
|---|---|
npm run check:agent -- --json | Prints the findings as JSON, for scripts and agents |
npm run check:agent -- --strict | Makes warnings fail too |
npm run check:agent -- --write-baseline | Records Velocity-owned files as they are now in .velocity/baseline.json |
With pnpm, drop the --: pnpm check:agent --json.
The ownership baseline
Section titled “The ownership baseline”.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.
Opting out
Section titled “Opting out”Some warnings are deliberate. Add a comment to the file to opt out:
velocity-allow-hardcodedin a file that is deliberately single-language turns offstrings/hardcodedfor it.velocity-single-languagein a page insrc/pages/turns offi18n/single-locale-pagefor it. Blog posts are already exempt.
---// velocity-allow-hardcoded: this landing page is English-only---File ownership
Section titled “File ownership”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.
Add your own skills
Section titled “Add your own skills”Create a folder with a SKILL.md file:
---name: add-case-studydescription: 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 agent benchmark
Section titled “The agent benchmark”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.
Get this in an existing project
Section titled “Get this in an existing project”Upgrade to get the latest rules, skills and check:
npm create velocity-astro@latest upgrade- From 2.0: the upgrade replaces your old
AGENTS.mdonce, 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 leaveAGENTS.mdalone. - From 2.1 or later: the upgrade adds
check:agentto the end of yourvalidatescript. If you customizedvalidate, append&& node scripts/check-agent.mjsyourself.
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.