Derive this project's actual conventions from its code and write them into a project-local rules file, so autodev enforces what this codebase already decided instead of a generic default.
Scanned 9/3/2026
Install to Claude Code
npx -y skills add djnsty23/claude-auto-dev --skill autodev-init --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Autodev Init?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/djnsty23-autodev-init)More formats (shields.io, HTML) on the badges page.
---
name: autodev-init
description: Derive this project's actual conventions from its code and write them into a project-local rules file, so autodev enforces what this codebase already decided instead of a generic default.
when_to_use: "Invoked when the user says \"autodev init\", \"init autodev\", \"learn my conventions\", \"generate project rules\", or when review/audit findings keep contradicting how this codebase is actually written."
allowed-tools: Bash, Read, Write, Edit, Grep, Glob
model: opus
user-invocable: true
argument-hint: "[refresh]"
---
# autodev-init
Every other skill in this plugin ships someone else's conventions. This one reads
yours out of the code and writes them down, so `review`, `audit`, and `auto`
enforce what your project actually does.
Output goes to **`.claude/project-rules.md`** in the project — not into the
plugin. It is project-local, git-committed, and human-editable. The generic
`standards` and `rule-*` skills stay as the fallback for anything you have not
decided.
## Rule one: observe, never assume
Every line you write must be backed by a count from this codebase. If you cannot
produce evidence, the convention does not go in the file — write it in the
"Undecided" section instead. A generated rules file that guesses is worse than
none, because `review` will enforce the guess.
If `.claude/project-rules.md` already exists, this is a **refresh**: re-measure,
show a diff of what changed, and preserve every hand-edited line. Never silently
overwrite a human's edit.
## Step 1: Establish the stack
```bash
cat package.json 2>/dev/null | head -60
ls -d src app pages components lib server 2>/dev/null
cat tsconfig.json 2>/dev/null | head -30
```
Record: framework and major version, router style, package manager (from the
lockfile), TypeScript strictness, test runner, linter/formatter.
## Step 2: Measure the conventions
Run these and **keep the counts** — they are the evidence.
```bash
# Component style: function declarations vs arrow consts
grep -rEc "^export (default )?function [A-Z]" --include='*.tsx' src app 2>/dev/null | awk -F: '{n+=$2} END {print "fn components:", n+0}'
grep -rEc "^export const [A-Z][A-Za-z]* = \(" --include='*.tsx' src app 2>/dev/null | awk -F: '{n+=$2} END {print "arrow components:", n+0}'
# Data fetching
grep -rl "useQuery\|useSuspenseQuery" --include='*.tsx' --include='*.ts' src app 2>/dev/null | wc -l
grep -rl "useSWR" --include='*.tsx' --include='*.ts' src app 2>/dev/null | wc -l
grep -rl "await fetch(" --include='*.tsx' --include='*.ts' src app 2>/dev/null | wc -l
# Validation at boundaries
grep -rl "from ['\"]zod['\"]" --include='*.ts' --include='*.tsx' src app 2>/dev/null | wc -l
# Styling: tokens vs raw colors
grep -rEo "\b(bg|text|border)-(background|foreground|primary|secondary|muted|accent|destructive)\b" --include='*.tsx' src app 2>/dev/null | wc -l
grep -rEo "\b(bg|text|border)-(gray|slate|zinc|white|black|red|blue|green)-?[0-9]*\b" --include='*.tsx' src app 2>/dev/null | wc -l
# Error and state handling
grep -rc "catch" --include='*.ts' --include='*.tsx' src app 2>/dev/null | awk -F: '{n+=$2} END {print "catch blocks:", n+0}'
grep -rl "isLoading\|isPending" --include='*.tsx' src app 2>/dev/null | wc -l
# Test layout
ls **/*.test.* **/*.spec.* __tests__ 2>/dev/null | head -5
```
Read 3–5 of the most recently changed non-trivial components in full. Counts
tell you what is common; reading tells you what is *intended*.
```bash
git log --format= --name-only -50 -- '*.tsx' | grep -v '^$' | sort | uniq -c | sort -rn | head -10
```
## Step 3: Find the boundaries
These matter more than style, because getting them wrong is a security bug:
- Where does auth get enforced? Middleware, per-route, or per-component?
- Where does external data enter, and is it validated there?
- Which directories are server-only? What stops a secret reaching the client?
- If there is a database: where do RLS policies live, and is deny-by-default the pattern?
## Step 4: Resolve contradictions with the user
Where the codebase is split — say 60/40 between two patterns — do **not** pick the
majority silently. Ask, using AskUserQuestion, with the counts in the options:
> Components are 34 arrow-const and 22 function-declaration. Which is the
> convention going forward?
Ask about at most the four most consequential splits. Everything else goes to
"Undecided".
## Step 5: Write `.claude/project-rules.md`
```markdown
# Project Rules
Generated by autodev-init on <date> from <N> files. Hand edits are preserved on
refresh — edit freely.
## Stack
<framework, router, package manager, TS strictness, test runner>
## Conventions
- <rule> — observed in <N>/<M> files
- <rule> — decided by <user>, <date>
## Boundaries
- Auth enforced at: <where>
- External data validated at: <where> using <what>
- Server-only: <paths>
## Anti-patterns for this codebase
- <specific pattern>, because <project-specific reason>
## Undecided
- <split convention with counts> — no rule; do not flag either form in review.
```
Then tell the user, in one line each: what you measured, what you asked, and
what remains undecided.
## Step 6: Wire it in
`.claude/` is ephemeral tooling state and should be ignored — but this one file
is worth committing. A bare `!.claude/project-rules.md` negation only works if
`.claude/` is ignored as a directory, so add both, and check the result rather
than assuming:
```bash
grep -q "^\.claude/$" .gitignore || printf '\n# autodev tooling state\n.claude/\n' >> .gitignore
grep -q "project-rules" .gitignore || printf '# ...except the project rules, which are committed\n!.claude/project-rules.md\n' >> .gitignore
git check-ignore -v .claude/project-rules.md && echo "STILL IGNORED — fix the negation before continuing"
```
If the repo already ignores only specific paths inside `.claude/` rather than
the whole directory, leave that alone and just confirm `project-rules.md` is
committable. Do not restructure someone's `.gitignore`.
Tell the user that `review`, `audit`, and `auto` should read
`.claude/project-rules.md` and that **it outranks the plugin's generic
`standards` skill wherever the two disagree** — the project's own observed
convention wins over a shipped default.
## What not to do
- Do not write a rule you did not measure.
- Do not restate general best practice. "Handle errors" is not a project rule;
"errors surface through `<ErrorState>`, never a toast" is.
- Do not reformat or refactor anything. This skill only reads and writes one file.
- Do not run on a repo with fewer than ~10 source files — there is no convention
to observe yet. Say so and stop.
## Proving the run
**Observable:** every rule written to `.claude/project-rules.md` cites the file
it was measured from, and re-reading that file still supports the rule.
The failure mode of this skill is a confident convention nobody follows — a rule
inferred from two files and applied to two hundred. A citation makes that
checkable by someone who was not here. Before finishing, re-read three cited
files at random and confirm each still says what the rule claims. State how many
files the conventions were measured across; a rule derived from one file is a
guess and should say so.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!