# Claude Code Instructions

## Architecture

This is a single-package repo with three logical components:

- **NPM package** (`src/`, `bin/`) — TypeScript linter with CLI and programmatic API
- **Claude plugin** (`.claude-plugin/`, `skills/`) — thin wrapper providing skills that call the npm package
- **Website** (`website/`) — VitePress documentation site at claudelint.com

See `src/CLAUDE.md` and `website/CLAUDE.md` for component-specific guidance.

## Commands

```bash
npm run build            # Compile TypeScript to dist/
npm run dev              # Watch mode
npm test                 # Jest test suite
npm run lint             # All linters in parallel (TS, Vue, CSS, MD, pkg)
npm run lint:fix         # Auto-fix all linters
npm run format:check     # Prettier check
npm run validate         # lint + format + build + test
npm run check:self       # Dogfood: build then run claudelint on itself
npm run docs:dev         # VitePress dev server (generates rule docs first)
npm run docs:build       # Production website build
```

## Auto-Generated Files

**Do NOT hand-edit these files — they are overwritten by scripts:**

- `src/rules/index.ts` — rule registry (`npm run generate:types`)
- `src/rules/rule-ids.ts` — rule ID union type (`npm run generate:types`)
- `website/rules/**/*.md` — rule documentation pages (`npm run docs:generate`)
- `website/rules/_sidebar.json` — rules sidebar nav (`npm run docs:generate`)
- `website/data/rule-stats.json` — rule count data (`npm run docs:generate`)
- `CHANGELOG.md` — auto-generated by release-it from Conventional Commits

Skill-level CHANGELOGs (`.claude/skills/*/CHANGELOG.md`) are manually maintained.

## Commit Message Format

All commits must follow Conventional Commits (enforced by commitlint):

```text
<type>: <description>
```

Standard types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`.

## Release Process

```bash
npm run release:dry      # Preview
npm run release          # Interactive release
npm run release:patch    # Patch bump
npm run release:minor    # Minor bump
npm run release:beta     # Pre-release
```

**What happens locally** (release-it): lint, test, build, generate CHANGELOG, bump version, `npm run sync:versions` (syncs version to plugin.json, marketplace.json, check-dependency.js), commit, tag, push. No `GITHUB_TOKEN` needed locally.

**What happens in CI** (`.github/workflows/publish.yml`, triggered by tag push): publishes to npm (OIDC trusted publishing with provenance), then creates a GitHub Release by extracting release notes from `CHANGELOG.md`. Do NOT create GitHub releases locally or with `gh release create --generate-notes` — CI extracts the conventional-changelog formatted notes from CHANGELOG.md so releases are consistent.

**Version sync**: `npm run sync:versions` propagates `package.json` version to `.claude-plugin/plugin.json`, `.claude-plugin/marketplace.json`, and the `PLUGIN_VERSION` constant in `.claude-plugin/scripts/check-dependency.js`. This runs automatically in the `after:bump` release-it hook. Run `npm run sync:versions:check` to verify all versions match.

**If the publish workflow fails, read [`docs/releasing.md`](docs/releasing.md) before touching `publish.yml`.** Four independent things must be right at the same time (npm trusted publisher config, no `npm install -g npm@latest`, no `registry-url` on setup-node, Node 24+ for npm 11.5+ OIDC). Toggling them in isolation can mask which one is actually broken — that runbook captures every failure mode and its symptom so the next debug session starts from known ground.

## File Naming Conventions

- Use kebab-case for all files: `my-file.ts`
- Test files: `my-file.test.ts`
- Rule files: `rule-name.ts` in `src/rules/<category>/`
- Rule docs: auto-generated in `website/rules/<category>/`

## Documentation

All documentation lives at [claudelint.com](https://claudelint.com) (source in `website/`). The `docs/projects/` directory contains internal project tracking only.
