| name | generate-agents | ||
|---|---|---|---|
| description | Analyzes any project and scaffolds a complete .agents/ folder with AGENTS.md, sync script, and starter skills tailored to the detected tech stack. Use when bootstrapping AI agent configuration for a new or existing repository. | ||
| metadata |
|
You are a meta-scaffolding expert. Analyze the project's codebase and produce a complete .agents/ folder that gives AI coding agents project-specific context, conventions, and reusable skills.
Gather the following signals in parallel.
Read these files (skip missing ones):
| Signal | Files to Check |
|---|---|
| Package manager | package.json, pnpm-workspace.yaml, pnpm-lock.yaml, yarn.lock, package-lock.json |
| Build tool | webpack.config.*, vite.config.*, rspack.config.*, tsconfig.json, next.config.* |
| Framework | package.json deps (react, vue, angular, svelte, express, nest, fastify) |
| Linting | eslint.config.*, .eslintrc.*, .prettierrc*, biome.json |
| Testing | jest.config.*, vitest.config.*, playwright.config.*, cypress.config.*, .storybook/ |
| State | package.json deps (mobx, redux, zustand, pinia, vuex, ngrx) |
| Styling | postcss.config.*, tailwind.config.*, CSS Modules usage, styled-components |
| CI/CD | .github/workflows/, .gitlab-ci.yml, Jenkinsfile, Dockerfile |
| Monorepo | pnpm-workspace.yaml, lerna.json, nx.json, turbo.json, rush.json |
| .NET | *.sln, *.csproj, Directory.Build.props, global.json |
| Python | pyproject.toml, setup.py, requirements.txt, Pipfile, poetry.lock |
| Go | go.mod, go.sum |
| Rust | Cargo.toml, Cargo.lock |
| Existing agent files | AGENTS.md, CLAUDE.md, .cursor/rules, .github/copilot-instructions.md, .clinerules |
Scan src/ (or equivalent) to detect:
- Pattern: FSD, Clean Architecture, MVC, modular, flat
- Naming: PascalCase / camelCase / kebab-case for files and folders
- Exports: barrel files (
index.ts) vs direct imports
Sample 3–5 source files to detect:
- Indentation (tabs vs spaces, width)
- Semicolons (yes/no), quotes (single/double)
- Type definitions (
typevsinterface) - Component style (function declarations, arrow functions,
export default)
If AGENTS.md, CLAUDE.md, or similar files already exist, preserve their content as the baseline — extend, don't replace.
.agents/
├── AGENTS.md
├── scripts/
│ └── sync.ts
└── skills/
└── <skill-name>/
└── SKILL.md
# Project: {name from package.json or directory}
## Identity
You are working on {project name} — {description from package.json or README}.
{Monorepo note if applicable.}
## Tech Stack
- **Runtime**: {Node.js / .NET / Python / Go / Rust}
- **Language**: {TypeScript X.x / C# / Python 3.x} ({strict if applicable})
- **Framework**: {React / Vue / Express / Django / ...}
- **Build**: {Vite / Webpack / MSBuild / ...}
- **Package Manager**: {pnpm / npm / yarn / pip / ...}
- **Testing**: {Jest / Vitest / pytest / xUnit / ...}
- **Linting**: {ESLint+Prettier / Biome / ...}
- **State**: {MobX / Redux / Zustand} (if applicable)
- **Styling**: {CSS Modules / Tailwind / styled-components} (if applicable)
- **CI/CD**: {GitHub Actions / GitLab CI} (if detected)
## Architecture
{Describe the detected pattern.}
### Directory Structure
{Actual top-level src layout as an indented tree.}
{If FSD or layered: describe the dependency rule.}
## Code Style Rules
### Naming
| Element | Convention | Example |
| --- | --- | --- |
### {Language}-Specific
{Detected conventions: semicolons, quotes, type vs interface, etc.}
## Common Commands
| Task | Command |
| --- | --- |
| Install | `{detected}` |
| Dev server | `{detected}` |
| Build | `{detected}` |
| Test | `{detected}` |
| Lint | `{detected}` |
| Format | `{detected}` |import fs from 'node:fs';
import path from 'node:path';
const AGENTS_SOURCE = '.agents/AGENTS.md';
const AGENTS_TARGETS = [/* determined by detected tooling */];
const SKILLS_SOURCE = '.agents/skills';
const SKILLS_TARGETS = [/* determined by detected tooling */];
const isDryRun = process.argv.includes('--dry-run');
function copyFile(src: string, destination: string): void {
if (isDryRun) { console.log(` [dry] ${src} → ${destination}`); return; }
fs.mkdirSync(path.dirname(destination), { recursive: true });
fs.copyFileSync(src, destination);
console.log(` ${src} → ${destination}`);
}
function syncAgents(): number {
if (!fs.existsSync(AGENTS_SOURCE)) { console.error(`Source not found: ${AGENTS_SOURCE}`); process.exit(1); }
let count = 0;
for (const target of AGENTS_TARGETS) { copyFile(AGENTS_SOURCE, target); count++; }
return count;
}
function syncSkills(): number {
if (!fs.existsSync(SKILLS_SOURCE)) return 0;
const dirs = fs.readdirSync(SKILLS_SOURCE, { withFileTypes: true })
.filter(e => e.isDirectory()).sort((a, b) => a.name.localeCompare(b.name));
let count = 0;
for (const targetDir of SKILLS_TARGETS) {
for (const dir of dirs) {
const src = path.join(SKILLS_SOURCE, dir.name, 'SKILL.md');
if (!fs.existsSync(src)) continue;
copyFile(src, path.join(targetDir, dir.name, 'SKILL.md'));
count++;
}
}
return count;
}
function sync(): void {
const start = performance.now();
if (isDryRun) console.log('Dry run — no files will be written\n');
const total = syncAgents() + syncSkills();
console.log(`\nSync complete: ${total} files in ${(performance.now() - start).toFixed(0)}ms`);
}
sync();Sync targets — populate AGENTS_TARGETS and SKILLS_TARGETS based on detection:
| If detected | AGENTS_TARGETS |
SKILLS_TARGETS |
|---|---|---|
| GitHub Copilot | AGENTS.md |
.github/skills/ |
| Claude / Anthropic | CLAUDE.md |
.claude/skills/ |
| Cursor | — | .cursor/skills/ |
| None specifically | AGENTS.md, CLAUDE.md |
.github/skills/, .claude/skills/, .cursor/skills/ |
| Skill | Purpose |
|---|---|
code-review |
Code review checklist adapted to the project's conventions |
summary |
Git change summary for QA / release notes |
| Condition | Skill | Purpose |
|---|---|---|
| TypeScript | typescript-conventions |
Type vs interface, naming, patterns |
| React | react-best-practices |
Component patterns, hooks, memoization |
| Vue | vue-best-practices |
Composition API, reactivity, SFC patterns |
| CSS Modules / Tailwind | css-styling |
Styling approach and naming conventions |
| Jest / Vitest / pytest / xUnit | unit-test |
Test patterns, mocking, file structure |
| Storybook | storybook-story |
Story conventions, tags, visual testing |
| MobX | mobx-patterns |
Observable patterns, reactions, stores |
| Redux / Zustand | state-management |
Store patterns, selectors, middleware |
| FSD architecture | create-slice |
Scaffolding slices with correct structure |
| REST API / OpenAPI | api-patterns |
API client patterns, error handling |
| .NET / C# | csharp-conventions |
C# naming, async patterns, test structure |
| Python | python-conventions |
PEP 8, typing, project tooling |
| Monorepo | monorepo-guide |
Cross-package imports, workspace commands |
| Playwright / Cypress | e2e-testing |
E2E test patterns, selectors, fixtures |
| Docker | docker-guide |
Container patterns, compose conventions |
If a create-skill skill is available in the project, use it to generate each skill file — it already encodes the correct structure and conventions. Otherwise, author each SKILL.md manually following the project's established skill format.
After generating all files, output:
- File tree of everything created
- Summary of detected stack and generated skills
- Next steps:
- Review and customize
AGENTS.mdfor accuracy - Run
npx tsx .agents/scripts/sync.ts --dry-runto preview sync targets - Run
npx tsx .agents/scripts/sync.tsto distribute files - Add
.agents/to version control - Optionally add sync targets to
.gitignoreif they should not be committed separately
- Review and customize
- Be conservative — only include what was actually detected; don't guess
- Preserve existing — if
AGENTS.mdorCLAUDE.mdalready exist, merge their content - Adapt, don't copy — each skill should use the project's actual patterns and file names
- Keep skills focused — one concern per skill, 50–150 lines each
- Match project style — use the detected indentation, quote style, and naming throughout
- Don't over-generate — fewer accurate skills beat many generic ones