Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Bug Report
description: Report a bug with @vllnt/eslint-config
labels: ["bug"]
body:
- type: textarea
id: description
attributes:
label: Description
description: What happened? What did you expect?
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Reproduction
description: Minimal eslint.config.js and steps to reproduce
render: js
validations:
required: true
- type: input
id: version
attributes:
label: "@vllnt/eslint-config version"
placeholder: "1.0.1"
validations:
required: true
- type: input
id: eslint-version
attributes:
label: ESLint version
placeholder: "9.39.4"
validations:
required: true
- type: input
id: node-version
attributes:
label: Node.js version
placeholder: "22.x"
validations:
required: true
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Discord
url: https://bntvllnt.com/discord
about: Questions and discussion
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Feature Request
description: Suggest a new rule, preset, or improvement
labels: ["enhancement"]
body:
- type: textarea
id: problem
attributes:
label: Problem
description: What problem does this solve?
validations:
required: true
- type: textarea
id: solution
attributes:
label: Proposed Solution
description: How should it work?
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives Considered
description: Other approaches you've thought about
validations:
required: false
8 changes: 8 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Summary

<!-- What does this PR do? -->

## Test plan

- [ ] `pnpm test` passes
- [ ] Tested with a real project (if adding/changing rules)
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,28 @@ jobs:
- run: pnpm install --frozen-lockfile

- run: pnpm test

changelog:
name: Changelog
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: CHANGELOG.md updated
run: |
if ! git diff --name-only origin/main...HEAD | grep -q '^CHANGELOG.md$'; then
echo "::error::CHANGELOG.md must be updated in every PR"
exit 1
fi

- name: Version matches CHANGELOG
run: |
PKG_VERSION=$(node -p "require('./package.json').version")
CL_VERSION=$(grep -oP '(?<=## \[)[0-9]+\.[0-9]+\.[0-9]+' CHANGELOG.md | head -1)
if [ "$PKG_VERSION" != "$CL_VERSION" ]; then
echo "::error::package.json version ($PKG_VERSION) does not match latest CHANGELOG.md entry ($CL_VERSION)"
exit 1
fi
echo "Versions match: $PKG_VERSION"
78 changes: 28 additions & 50 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ on:
- "pnpm-lock.yaml"
- ".github/workflows/publish.yml"
workflow_dispatch:
inputs:
bump:
description: "Version bump type"
required: true
type: choice
options:
- patch
- minor
- major

concurrency:
group: publish-${{ github.event_name }}
Expand Down Expand Up @@ -105,58 +96,44 @@ jobs:

- run: pnpm install --frozen-lockfile

- name: Bump version
- name: Read version
id: version
run: |
npm version ${{ inputs.bump }} --no-git-tag-version
VERSION=$(node -p "require('./package.json').version")
echo "version=$VERSION" >> "$GITHUB_OUTPUT"

- name: Generate changelog
- name: Extract release notes from CHANGELOG.md
id: changelog
run: |
LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
if [ -z "$LAST_TAG" ]; then
RANGE="HEAD"
else
RANGE="${LAST_TAG}..HEAD"
VERSION="${{ steps.version.outputs.version }}"
NOTES=$(awk -v ver="$VERSION" '
BEGIN { found=0 }
/^## \[/ {
if (found) exit
if (index($0, "[" ver "]")) { found=1; next }
}
found && /^[[:space:]]*$/ && !printed { next }
found { printed=1; print }
' CHANGELOG.md)

if [ -z "$NOTES" ]; then
echo "::warning::No release notes found in CHANGELOG.md for v$VERSION"
NOTES="Release v$VERSION"
fi

{
echo "body<<CHANGELOG_EOF"

FEATS=$(git log "$RANGE" --pretty=format:"%s" --grep="^feat" 2>/dev/null || true)
if [ -n "$FEATS" ]; then
echo "### Features"
echo "$FEATS" | sed 's/^/- /'
echo ""
fi

FIXES=$(git log "$RANGE" --pretty=format:"%s" --grep="^fix" 2>/dev/null || true)
if [ -n "$FIXES" ]; then
echo "### Bug Fixes"
echo "$FIXES" | sed 's/^/- /'
echo ""
fi

OTHERS=$(git log "$RANGE" --pretty=format:"%s" --invert-grep --grep="^feat" --grep="^fix" 2>/dev/null || true)
if [ -n "$OTHERS" ]; then
echo "### Other Changes"
echo "$OTHERS" | sed 's/^/- /'
echo ""
fi

echo "CHANGELOG_EOF"
echo "notes<<CHANGELOG_DELIM"
echo "$NOTES"
echo "CHANGELOG_DELIM"
} >> "$GITHUB_OUTPUT"

- name: Commit and tag
- name: Create git tag
run: |
VERSION="${{ steps.version.outputs.version }}"
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add package.json
git commit -m "chore(release): v${{ steps.version.outputs.version }}"
git tag "v${{ steps.version.outputs.version }}"
git push origin main --follow-tags
git tag -a "v$VERSION" -m "Release v$VERSION"
git push origin "v$VERSION"

- name: Upgrade npm for OIDC support
run: npm install -g npm@latest
Expand All @@ -169,8 +146,9 @@ jobs:

- name: Create GitHub Release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.RELEASE_PAT }}
run: |
gh release create "v${{ steps.version.outputs.version }}" \
--title "@vllnt/eslint-config v${{ steps.version.outputs.version }}" \
--notes "${{ steps.changelog.outputs.body }}"
VERSION="${{ steps.version.outputs.version }}"
gh release create "v$VERSION" \
--title "@vllnt/eslint-config v$VERSION" \
--notes "${{ steps.changelog.outputs.notes }}"
51 changes: 51 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# @vllnt/eslint-config

Strict ESLint flat config for TypeScript projects. Scoped to `@vllnt` npm org.

## Project Structure

```
flat/ ← shipped code (included in npm tarball)
index.js ← barrel: re-exports all presets
base.js ← base config (TS strict + prettier)
nextjs.js ← Next.js preset
nodejs.js ← Node.js preset
react.js ← React preset
convex.js ← Convex preset
turbo.js ← Turborepo preset
boundaries.js ← Architecture boundaries preset
convex-plugin.js ← convex-rules ESLint plugin
convex-rules/ ← 7 custom Convex lint rules
core/ ← shared config fragments
tests/
smoke.test.js ← export/shape/hygiene tests (node:test)
```

## Commands

| Command | What |
|---------|------|
| `pnpm test` | Smoke tests (43 assertions) |
| `pnpm pack --dry-run` | Preview tarball contents |

## Architecture

- Each preset is a flat config array exported from `flat/{preset}.js`
- Config fragments live in `flat/core/{name}.js` and are composed into presets
- `flat/index.js` is the barrel that re-exports all presets
- Custom Convex rules live in `flat/convex-rules/` and are bundled via `flat/convex-plugin.js`
- Tests use `node:test` (no external test runner)

## Conventions

- All rules enforce `error` — never `warn` or `off`
- Presets are arrays — consumers spread them into their flat config
- No TypeScript source — all shipped code is plain JS
- `peerDependencies` for eslint, prettier, typescript
- `dependencies` for all plugins (consumers don't install them separately)

## Publishing

Push to main triggers canary publish. For releases: bump version in package.json,
add CHANGELOG.md entry, merge PR, then trigger `workflow_dispatch`. CI creates
git tag, publishes to npm, and creates GitHub Release with notes from CHANGELOG.md.
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).

## [1.0.1] - 2026-03-29

### Fixed

- Resolve 23 transitive dependency vulnerabilities (1 critical, 14 high, 7 moderate, 1 low) (#12)
- Bump `@convex-dev/eslint-plugin` ^1.1.1 to ^1.2.1
- Bump `eslint` (dev) ^9.39.2 to ^9.39.4
- Add `pnpm.overrides` for `handlebars` (pinned by upstream `@boundaries/elements`)
- Refresh lockfile to resolve minimatch, picomatch, flatted, brace-expansion to patched versions

## [1.0.0] - 2026-03-14

### Added

- Initial release
- 7 presets: Base, React, Next.js, Node.js, Convex, Turbo, Boundaries
- TypeScript-first with `strictTypeChecked` + `stylisticTypeChecked`
- Prettier built-in as lint errors
- 7 custom Convex lint rules bundled as `eslint-plugin-convex-rules`
- Smoke tests with 43 assertions
- CI/CD with GitHub Actions (test + canary publish + release)

[1.0.1]: https://github.com/vllnt/eslint-config/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/vllnt/eslint-config/releases/tag/v1.0.0
14 changes: 5 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,11 @@ git push && git push --tags

## Publishing (CI)

Push a version tag — CI handles the rest:

```sh
pnpm version patch
git push && git push --tags
# release.yml: test → npm publish --provenance → GitHub Release
```

Requires `NPM_TOKEN` secret in GitHub repo settings.
1. Bump version in `package.json`
2. Add entry to `CHANGELOG.md` (CI enforces this)
3. Merge PR (CI verifies version matches CHANGELOG)
4. Trigger **Publish** workflow manually (`workflow_dispatch`)
5. CI creates git tag, publishes to npm, creates GitHub Release with notes from CHANGELOG.md

## Project structure

Expand Down
43 changes: 43 additions & 0 deletions CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to a positive environment:

- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members

Examples of unacceptable behavior:

- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported via:

- **Discord**: [bntvllnt.com/discord](https://bntvllnt.com/discord)
- **X / Twitter DM**: [bntvllnt.com/x](https://bntvllnt.com/x)

All complaints will be reviewed and investigated promptly and fairly. Community leaders are obligated to respect the privacy and security of the reporter.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1.
Loading
Loading