The Observatory · 11 min mission

Starter Kits: Make Any Repo Agent-Ready

Drop one set of copy-paste files into a fresh repo and every coding agent boots informed.

starter-kitAGENTS.mdCLAUDE.mdhookspermissionsskillsFact-checked 2026-06-15
On this page

An agent-ready starter kit is a fixed set of files you commit to a repo so any coding agent that opens it starts with your build commands, conventions, and constraints already loaded. This guide gives you the exact files to drop in, the shim each tool needs, and the enforcement layer that briefings alone cannot provide.

The architecture is one canonical briefing plus thin per-tool shims: the real instructions live in AGENTS.md; CLAUDE.md, GEMINI.md, a Cursor .mdc, and .github/copilot-instructions.md only point at it or add tool-specific notes. Every briefing file is advice the model tries to follow; only deny rules, hooks, sandboxes, and CI are enforcement it cannot bypass.

ToolReads `AGENTS.md` nativelyShim the kit ships
CursorYes (root + nested, closest wins)Optional .cursor/rules/*.mdc for scoped rules
GitHub CopilotYes (nearest-in-tree wins).github/copilot-instructions.md (used *together* with AGENTS.md)
Windsurf / DevinYes (root always-on; subdir glob-scoped)None; .devin/rules/ for scoped rules
Cline / Roo CodeYesNone needed
Claude CodeNo — reads CLAUDE.md onlyCLAUDE.md with @AGENTS.md import (or symlink)
Gemini CLINo by defaultGEMINI.md import, or add to context.fileName
CodexYes (primary instruction file)None needed
Which tools read AGENTS.md natively, and the shim the kit ships for the ones that do not. Verified against each tool’s official docs as of 2026-06-15.

The starter-kit forge — generate your repo’s agent files

Starter-kit forge

Pick the agents your team uses and answer a couple of project questions. The kit assembles itself around one canonical AGENTS.md — the source of truth the standard ~24 tools read — plus only the thin shim each tool needs and Claude Code's enforcement layer. Untick a tool and its file leaves the tree.

Agents your team uses

AGENTS.md is always generated — it's the spine. Each tool you add brings only the shim it needs.

  • Claude Code Needs a CLAUDE.md that imports @AGENTS.md — it never reads AGENTS.md directly. Brings the enforcement layer: settings.json, a Stop-gate hook, and a skill.
  • Cursor Reads AGENTS.md natively. Adds a scoped .cursor/rules/*.mdc (globs/modes) — not the broad briefing, which lives in AGENTS.md.
  • GitHub Copilot Reads AGENTS.md natively and uses it together with .github/copilot-instructions.md (both files concatenate). Keep the Copilot file short.

Package manager

Threaded through every command in the briefing so agents never reach for the wrong one.

Test command

The exact command for the Definition of done, the Claude allow-list, and the Stop-hook gate.

Forbidden directory

A path agents must never edit — written into AGENTS.md's Conventions section.

Files generated (8)

Click a file to open it. AGENTS.md leads; shims and the enforcement layer follow your selection.

.claude/
hooks/
skills/
summarize-changes/
.cursor/
rules/
.github/
AGENTS.md
# AGENTS.md > Operating instructions for coding agents working in this repo. Plain Markdown, no schema.> The closest AGENTS.md to the file being edited wins; an explicit chat instruction wins over all. ## Project overview- <One sentence: what this project is and its stack, e.g. "Next.js 14 App Router + TypeScript, static export.">- Entry points: `app/` (routes), `lib/` (shared logic), `components/` (UI). ## Setup- Install: `pnpm install`  (this repo uses pnpm — do not use npm or yarn)- Integration tests need a local Postgres: `docker compose up -d db` first. ## Build, test, lint- Build: `pnpm build`- Test (all): `pnpm test`   ·   single file: `pnpm test <path>`- Lint (must be zero warnings): `pnpm lint`- Typecheck: `pnpm typecheck` ## Code style- TypeScript strict; no `any` that breaks the build.- 2-space indent; named exports; colocate tests as `*.test.ts`. ## Conventions & constraints- Never edit `legacy/` or generated output in `dist/`.- Keep the public API in `lib/api/` backward compatible.- Use the `@/*` path alias (maps to repo root); never deep relative imports across packages. ## Definition of doneBefore claiming a task is finished: `pnpm lint` clean, `pnpm test` green, `pnpm typecheck`passes, no new TODOs left in changed files. ## PR / commit- Conventional Commits (`feat:`, `fix:`, `chore:`). One logical change per PR.- Do not commit unless explicitly asked. ## Review guidelines- Don't log PII. Verify auth middleware wraps every route.- Flag typos/grammar in user-facing strings as P0.

Replace the <…> placeholders per project. Specs current as of 2026-06-15; coding agents ship fast, so check each tool's docs before relying on a detail.

Toggle the tools your team uses (Claude Code, Codex, Cursor, Copilot, Gemini CLI, Windsurf) and answer a few project questions — package manager, test command, forbidden directories. The forge emits the exact file tree on one side and the rendered, copyable contents on the other, always centered on AGENTS.md and wired with only the shims your selected tools actually need.

Assemble the kit

  1. Write `AGENTS.md` at the repo root

    Plain Markdown, no schema. Put the real briefing here: build/test/lint commands, code style, hard constraints, and an explicit definition of "done". Cursor, Copilot, Windsurf, Cline, Roo Code, and Codex read it natively.

  2. Add `CLAUDE.md` with `@AGENTS.md` on line 1

    Claude Code reads CLAUDE.md, not AGENTS.md. The @AGENTS.md import pulls in the canonical briefing; add only Claude-specific lines below it. Target under 200 lines.

  3. Add `GEMINI.md` with `@./AGENTS.md`, or set `context.fileName`

    Gemini CLI reads GEMINI.md only by default. Either import AGENTS.md from a tiny GEMINI.md, or list AGENTS.md in context.fileName in .gemini/settings.json. Ship one, not both.

  4. Add scoped shims for Cursor and Copilot

    Both read AGENTS.md natively, so do not copy the briefing. Add .cursor/rules/*.mdc only for path-scoped rules, and keep .github/copilot-instructions.md a short pointer plus Copilot-only notes.

  5. Add the enforcement layer under `.claude/`

    Commit .claude/settings.json (permissions + a format-on-edit hook), .claude/hooks/test-gate.sh (a Stop test gate), and a .claude/skills/<name>/SKILL.md skill.

  6. Gitignore the personal-override siblings

    Add CLAUDE.local.md, .claude/settings.local.json, and AGENTS.local.md (Roo Code) to .gitignore so local preferences never reach the shared repo.

AGENTS.md — the canonical briefing

AGENTS.md is plain Markdown with no schema and no required fields, stewarded by the Agentic AI Foundation under the Linux Foundation; agents.md reports it is used by over 60,000 open-source projects. The spec recommends optional sections — project overview, build/test/lint commands, code style, dev-environment tips, testing instructions, PR/commit conventions, security considerations — but imposes none. Precedence: the closest AGENTS.md to the edited file wins; an explicit chat instruction wins over all.

AGENTS.md — the canonical briefing (repo root)
markdown
# AGENTS.md
 
> Operating instructions for coding agents working in this repo. Plain Markdown, no schema.
> The closest AGENTS.md to the file being edited wins; an explicit chat instruction wins over all.
 
## Project overview
- Next.js 14 App Router + TypeScript, static export.
- Entry points: `app/` (routes), `lib/` (shared logic), `components/` (UI).
 
## Setup
- Install: `pnpm install`  (this repo uses pnpm — do not use npm or yarn)
- Integration tests need a local Postgres: `docker compose up -d db` first.
 
## Build, test, lint
- Build: `pnpm build`
- Test (all): `pnpm test`   ·   single file: `pnpm test <path>`
- Lint (must be zero warnings): `pnpm lint`
- Typecheck: `pnpm typecheck`
 
## Code style
- TypeScript strict; no `any` that breaks the build.
- 2-space indent; named exports; colocate tests as `*.test.ts`.
 
## Conventions & constraints
- Never edit `legacy/` or generated output in `dist/`.
- Keep the public API in `lib/api/` backward compatible.
- Use the `@/*` path alias (maps to repo root); never deep relative imports across packages.
 
## Definition of done
Before claiming a task is finished: `pnpm lint` clean, `pnpm test` green, `pnpm typecheck`
passes, no new TODOs left in changed files.
 
## PR / commit
- Conventional Commits (`feat:`, `fix:`, `chore:`). One logical change per PR.
- Do not commit unless explicitly asked.
 
## Review guidelines
- Don't log PII. Verify auth middleware wraps every route.
- Flag typos/grammar in user-facing strings as P0.

CLAUDE.md and GEMINI.md shims

Claude Code reads CLAUDE.md only; Gemini CLI reads GEMINI.md only (or whatever you list in context.fileName). Neither reads AGENTS.md by default — the single biggest trap when assembling a kit. Both support @-path imports, so each shim imports the canonical briefing and adds only its own notes. Claude Code's documented single-source pattern is exactly this @AGENTS.md import; it targets keeping CLAUDE.md under 200 lines and delivers the content as a user message after the system prompt. HTML comments are stripped before injection, so they are free annotations.

CLAUDE.md — the Claude Code shim (repo root)
markdown
@AGENTS.md
 
# CLAUDE.md
 
<!-- The shared briefing above is imported from AGENTS.md so Claude Code and every
     AGENTS.md-native tool read one source of truth. Add ONLY Claude-specific lines below. -->
 
## Claude Code specifics
- Use plan mode before multi-file changes under `lib/api/`.
- Run a single test with `pnpm test <path>`, not the whole suite, while iterating.
- Money-handling rules live in `lib/payments/CLAUDE.md` and load on demand when you work there.
GEMINI.md — the Gemini CLI shim (repo root)
markdown
@./AGENTS.md
 
# GEMINI.md
 
<!-- Imports the shared AGENTS.md briefing. Gemini-only notes go below. -->
 
## Gemini CLI specifics
- Prefer `gemini -m gemini-2.5-flash` for quick edits; reserve the pro model for design work.
.gemini/settings.json — alternative to the GEMINI.md file
json
{
  "context": {
    "fileName": ["AGENTS.md", "GEMINI.md"]
  }
}

Cursor and Copilot scoped shims

Cursor rules live in .cursor/rules/ as .mdc files (Markdown + YAML frontmatter) — a plain .md there is silently ignored. Three frontmatter fields (description, globs, alwaysApply) select one of four activation modes. Keep rules under 500 lines and use the .mdc for path-scoped conventions only; AGENTS.md covers the rest.

For Copilot, when both AGENTS.md and .github/copilot-instructions.md exist at the root, Copilot uses the instructions in both files together — concatenated, not one overriding the other. Duplicating the briefing here creates redundancy, not precedence. Path-scoped rules go in .github/instructions/*.instructions.md with an applyTo: glob.

.cursor/rules/project-conventions.mdc — a scoped Cursor rule
markdown
---
description: TypeScript/React component conventions for this repo
globs: src/components/**/*.tsx
alwaysApply: false
---
 
# Component conventions
 
- Function components only; no class components.
- Props typed with an exported `interface`, never inline object types.
- Co-locate a `*.test.tsx` beside every component.
- Use the design tokens in `styles/tokens.css`; never hardcode hex colors.
- Reference `@/lib/api` for data fetching — do not call `fetch` directly in components.
ModeFrontmatterFires when
Always ApplyalwaysApply: trueEvery request, always in context
Apply Intelligentlydescription, no globsCursor judges the description relevant
Apply to Specific Filesglobs setAn edited file matches the glob
Apply Manuallynone of the threeOnly on an explicit @rule-name
Cursor’s four activation modes, by frontmatter combination — exact dropdown names from the official docs. A vague description on an "Apply Intelligently" rule is the #1 reason a rule never fires.
.github/copilot-instructions.md — Copilot repository instructions
markdown
# Copilot instructions
 
The canonical project briefing lives in `AGENTS.md` at the repo root and Copilot reads it
automatically; this file adds Copilot-specific guidance only.
 
- This repo uses **pnpm**. Never suggest `npm install` or `yarn`.
- Prefer small, reviewable diffs; explain non-obvious changes in the PR body.
- TypeScript strict mode is on — never introduce `any`.
- For test files, follow the existing `*.test.ts` patterns in the same directory.

Enforcement: permissions + a format-on-edit hook

.claude/settings.json carries permissions with allow / ask / deny arrays. Evaluation order is deny → ask → allow; deny always wins and rules merge across scopes, so a deny rule cannot be overridden by a prompt. Allow-listing the safe commands removes the prompt fatigue that pushes people toward bypassPermissions (isolated containers only — never a kit default). Commit .claude/settings.json for the team; keep personal overrides in gitignored .claude/settings.local.json. The same file holds a hooks object; below, a PostToolUse hook formats every edited file.

.claude/settings.json — permissions + a format-on-edit hook
json
{
  "permissions": {
    "allow": [
      "Bash(pnpm test *)",
      "Bash(pnpm lint *)",
      "Bash(pnpm build *)",
      "Bash(pnpm typecheck *)",
      "Bash(git status *)",
      "Bash(git diff *)"
    ],
    "ask": [
      "Bash(git push *)"
    ],
    "deny": [
      "Read(./.env)",
      "Read(./.env.*)",
      "Bash(rm -rf *)",
      "Bash(curl *)"
    ]
  },
  "defaultMode": "default",
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs -r npx prettier --write"
          }
        ]
      }
    ]
  }
}

Enforcement: a Stop-hook test gate

A Stop hook fires when Claude tries to end a turn. The most valuable kit hook runs the suite there and exits 2 to block the stop and feed the failure to stderr so Claude keeps working. Mandatory footgun: read stop_hook_active from the JSON on stdin and exit 0 early if it is true — Claude Code overrides a Stop hook after 8 consecutive blocks anyway, but you want to bow out cleanly first. The hook runs with full user privileges and no per-run prompt, so never ship one the team has not read.

.claude/hooks/test-gate.sh — block the stop until tests pass
bash
#!/usr/bin/env bash
# Stop-hook gate: block the turn from ending until the test suite passes.
set -euo pipefail
 
input="$(cat)"   # Claude Code feeds hook JSON on stdin
 
# Don't re-fire on a turn we already blocked (prevents the 8-block override loop).
if [ "$(printf '%s' "$input" | jq -r '.stop_hook_active')" = "true" ]; then
  exit 0
fi
 
if pnpm test >/tmp/test-gate.log 2>&1; then
  exit 0   # tests green: allow the stop
else
  echo "Tests are failing — keep working until they pass:" >&2
  tail -n 20 /tmp/test-gate.log >&2
  exit 2   # block the stop; stderr is fed back to Claude
fi
.claude/settings.json — wire the Stop hook (merge into the file above)
json
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": ".claude/hooks/test-gate.sh"
          }
        ]
      }
    ]
  }
}

Enforcement: a minimal skill

A skill is a directory with one required file, SKILL.md (YAML frontmatter + Markdown body). The directory name becomes the command (.claude/skills/summarize-changes//summarize-changes), and project skills under .claude/skills/ ship to the team via git. description is the matching surface Claude uses to auto-invoke, so describe when to use the skill. A ! followed by a backticked command does dynamic context injection — Claude Code runs it and splices the output into the prompt before Claude reads. allowed-tools is permissive, not restrictive: it pre-approves the listed tools but does not sandbox the skill. Keep SKILL.md under 500 lines; for side-effecting skills add disable-model-invocation: true so only the user can fire them.

.claude/skills/summarize-changes/SKILL.md — a minimal skill
markdown
---
name: summarize-changes
description: Summarizes uncommitted changes and flags anything risky. Use when the user asks
  what changed, wants a commit message, or asks to review their diff.
allowed-tools: Bash(git diff *) Bash(git status *)
---
 
## Current changes
 
!`git diff HEAD`
 
## Instructions
 
Summarize the changes above in two or three bullet points, then list any risks you notice —
missing error handling, hardcoded values, or tests that need updating. If the diff is empty,
say there are no uncommitted changes.
drop the kit, verify both spines load
… scroll to run this session
AGENTS.md is the one briefing; CLAUDE.md and GEMINI.md are one-line imports of it. The tree shows the full kit, the imports confirm there is no duplicated briefing to drift, and the listed deny rules are enforcement a prompt cannot override.

Knowledge check

You want a single briefing that Claude Code, Codex, Cursor, Copilot, and Gemini CLI all follow, with no second copy to keep in sync. What is the cleanest kit architecture?

Reach the end and this star joins your charted sky.