Skip to content

Commit 9705cf1

Browse files
committed
init linters
1 parent 5668c37 commit 9705cf1

104 files changed

Lines changed: 23009 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Build output
5+
dist/
6+
build/
7+
8+
# Coverage
9+
coverage/
10+
11+
# IDE
12+
.idea/
13+
.vscode/
14+
*.swp
15+
*.swo
16+
17+
# OS
18+
.DS_Store
19+
Thumbs.db
20+
21+
# Logs
22+
*.log
23+
npm-debug.log*
24+
25+
# Environment
26+
.env
27+
.env.local
28+
29+
# Package manager locks (optional - remove if you want to commit them)
30+
# package-lock.json
31+
# yarn.lock

README.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# @factory/eslint-plugin
2+
3+
An open-source ESLint plugin showcasing how agent-native organizations use custom lint rules to drive AI coding agents toward better results.
4+
5+
## About This Project
6+
7+
This codebase is forked from what is used internally at [Factory](https://factory.ai) and has been altered to be more generic. We are sharing this as requested by the developer community and to showcase an example of what an agent-native organization does with custom lint rules to improve agent output quality.
8+
9+
**All code in this repository is fully AI-generated.**
10+
11+
To learn more about our approach:
12+
- [Using Linters to Direct Agents](https://factory.ai/news/using-linters-to-direct-agents)
13+
- [Agent Readiness](https://factory.ai/news/agent-readiness)
14+
15+
## Important: How to Use This Repository
16+
17+
**Our recommendation is NOT to simply import this package.** Instead, take the ideas from these rules and build your own set of custom lint rules tailored to your codebase, tech stack, and conventions.
18+
19+
We have included comprehensive markdown documentation for each rule (in `rules/<rule-name>/README.md`) that makes it easy for any AI agent to parse and adapt to your custom tech stack or framework.
20+
21+
> **Note:** This repository is not planned to be actively maintained or updated. It is designed for sharing and inspiration only.
22+
23+
## Installation
24+
25+
```bash
26+
npm install @factory/eslint-plugin eslint --save-dev
27+
```
28+
29+
## Quick Start
30+
31+
Create an `.eslintrc.js` file in your project root:
32+
33+
### For TypeScript packages/libraries
34+
35+
```js
36+
module.exports = {
37+
root: true,
38+
plugins: ['@factory'],
39+
extends: ['plugin:@factory/recommended'],
40+
};
41+
```
42+
43+
### For frontend applications (React/Vite)
44+
45+
```js
46+
module.exports = {
47+
root: true,
48+
plugins: ['@factory'],
49+
extends: ['plugin:@factory/frontend'],
50+
};
51+
```
52+
53+
### For backend applications
54+
55+
```js
56+
module.exports = {
57+
root: true,
58+
plugins: ['@factory'],
59+
extends: ['plugin:@factory/backend'],
60+
};
61+
```
62+
63+
## Available Configurations
64+
65+
| Config | Use Case | Description |
66+
|--------|----------|-------------|
67+
| `plugin:@factory/base` | Base | Core TypeScript/JavaScript rules |
68+
| `plugin:@factory/recommended` | Packages/Libraries | Base + Factory plugin rules |
69+
| `plugin:@factory/frontend` | React/Vite apps | Recommended + React/JSX rules |
70+
| `plugin:@factory/backend` | Backend apps | Recommended + backend constraints |
71+
72+
### Configuration Hierarchy
73+
74+
```mermaid
75+
graph TD
76+
A[base] --> B[recommended]
77+
B --> C[frontend]
78+
B --> D[backend]
79+
```
80+
81+
## Factory Plugin Rules
82+
83+
This plugin includes custom rules that enforce code organization and best practices:
84+
85+
### File Organization
86+
- `@factory/enum-file-organization` - Enums must live in `enums.ts` files
87+
- `@factory/types-file-organization` - Type definitions must live in `types.ts` files
88+
- `@factory/constants-file-organization` - Constants must live in `constants.ts` files
89+
- `@factory/errors-file-organization` - Error classes must live in `errors.ts` files
90+
- `@factory/test-utils-organization` - Test utilities must live under `test-utils/`
91+
- `@factory/test-file-location` - Test files must be colocated with source files
92+
93+
### Naming & Exports
94+
- `@factory/filename-match-export` - Filenames must match exported components/functions
95+
- `@factory/no-exported-function-expressions` - Prefer function declarations for exports
96+
- `@factory/no-exported-string-union-types` - Prefer enums over string union types
97+
98+
### Testing
99+
- `@factory/require-test-files` - TypeScript files must have corresponding test files
100+
- `@factory/require-tsx-test-stories-files` - TSX files need test and story files
101+
- `@factory/jest-mock-absolute-paths` - Jest mocks must use absolute paths
102+
- `@factory/jest-mock-require-actual` - Jest mocks must include `jest.requireActual()`
103+
- `@factory/no-unstable-mock-module` - Disallow `unstable_mockModule`
104+
105+
### Logging
106+
- `@factory/structured-logging` - Enforce structured logging patterns
107+
- `@factory/no-log-exception-with-throw` - No logging exceptions before throwing
108+
109+
### API Routes (Next.js/Express)
110+
- `@factory/require-route-middleware` - Route files must use middleware
111+
- `@factory/require-v0-route-handle-middleware` - v0 routes need specific middleware
112+
- `@factory/require-v0-strict-schemas` - v0 routes need strict schema validation
113+
114+
### React
115+
- `@factory/no-dynamic-styled-components` - No dynamic styled-components
116+
- `@factory/no-plain-html-text-elements` - No plain text in HTML elements
117+
- `@factory/no-use-effect-in-hooks` - Restrict useEffect in custom hooks
118+
- `@factory/restrict-tsx-components` - Enforce component patterns
119+
120+
## Peer Dependencies
121+
122+
- `eslint` >= 8.0.0
123+
- `typescript` >= 5.0.0
124+
125+
## License
126+
127+
MIT

configs/backend.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict';
2+
3+
// Config for apps/* that are not Next.js
4+
const factoryConfig = require('./recommended.js');
5+
6+
module.exports = {
7+
...factoryConfig,
8+
plugins: [...(factoryConfig.plugins || []), 'no-relative-import-paths'],
9+
rules: {
10+
...factoryConfig.rules,
11+
'@factory/jest-mock-absolute-paths': 'error',
12+
'no-relative-import-paths/no-relative-import-paths': [
13+
'error',
14+
{ allowSameFolder: false, rootDir: 'src', prefix: '@' },
15+
],
16+
},
17+
};

configs/base.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
module.exports = {
2+
parser: '@typescript-eslint/parser',
3+
globals: {
4+
NodeJS: true,
5+
FileSystemFileHandle: true,
6+
FileSystemHandle: true,
7+
FileSystemDirectoryHandle: true,
8+
FileSystemPermissionMode: true,
9+
FileSystemHandlePermissionDescriptor: true,
10+
FileSystemWritableFileStream: true,
11+
globalThis: 'readonly',
12+
},
13+
extends: [
14+
'eslint-config-airbnb-base',
15+
'plugin:jest/recommended',
16+
'prettier',
17+
],
18+
parserOptions: {
19+
ecmaVersion: 'latest',
20+
sourceType: 'module',
21+
},
22+
settings: {
23+
'import/resolver': {
24+
typescript: {
25+
project: true,
26+
},
27+
node: {
28+
project: true,
29+
extensions: ['.js', '.jsx', '.ts', '.tsx'],
30+
},
31+
},
32+
},
33+
ignorePatterns: ['build/**/*', 'dist/**/*', 'coverage/**/*'],
34+
plugins: [
35+
'@typescript-eslint',
36+
'eslint-comments',
37+
'unused-imports',
38+
'no-barrel-files',
39+
],
40+
rules: {
41+
// TypeScript rules
42+
'@typescript-eslint/no-empty-object-type': 'error',
43+
'@typescript-eslint/no-explicit-any': 'error',
44+
'@typescript-eslint/no-require-imports': 'error',
45+
// Handled by "unused-imports/no-unused-vars" instead.
46+
'@typescript-eslint/no-unused-vars': 'off',
47+
'@typescript-eslint/no-floating-promises': 'error',
48+
'no-barrel-files/no-barrel-files': 'error',
49+
// Import rules
50+
'import/extensions': [
51+
'error',
52+
'never',
53+
{
54+
json: 'always',
55+
},
56+
],
57+
'import/named': 'error',
58+
'import/no-cycle': 'error',
59+
'import/no-extraneous-dependencies': [
60+
'error',
61+
{
62+
devDependencies: true,
63+
packageDir: ['.', '../..'], // Include the workspace root package.json
64+
},
65+
],
66+
'import/no-default-export': 'error',
67+
'import/no-unresolved': [
68+
'error',
69+
{
70+
ignore: ['^@factory/'],
71+
},
72+
],
73+
'import/order': [
74+
'error',
75+
{
76+
groups: [
77+
'builtin',
78+
'external',
79+
'internal',
80+
['parent', 'sibling'],
81+
'index',
82+
'type',
83+
],
84+
pathGroups: [
85+
{
86+
pattern: '@/**',
87+
group: 'parent',
88+
},
89+
],
90+
distinctGroup: false,
91+
'newlines-between': 'always',
92+
alphabetize: {
93+
order: 'asc',
94+
caseInsensitive: true,
95+
},
96+
},
97+
],
98+
'eslint-comments/no-unused-disable': 'error',
99+
'no-void': [
100+
'error',
101+
{
102+
allowAsStatement: true,
103+
},
104+
],
105+
'unused-imports/no-unused-imports': 'error',
106+
'unused-imports/no-unused-vars': [
107+
'error',
108+
{
109+
vars: 'all',
110+
varsIgnorePattern: '^_',
111+
args: 'after-used',
112+
argsIgnorePattern: '^_',
113+
ignoreRestSiblings: false,
114+
caughtErrorsIgnorePattern: '^_',
115+
},
116+
],
117+
'prefer-arrow-callback': ['error', { allowNamedFunctions: true }],
118+
// General rules
119+
'class-methods-use-this': 'error',
120+
'default-case': 'error',
121+
'no-console': 'error',
122+
'no-constant-condition': [
123+
'error',
124+
{
125+
checkLoops: false,
126+
},
127+
],
128+
'no-param-reassign': [
129+
'error',
130+
{
131+
props: false,
132+
},
133+
],
134+
'no-restricted-globals': 'error',
135+
'no-promise-executor-return': 'error',
136+
'prefer-promise-reject-errors': 'error',
137+
'jest/expect-expect': 'error',
138+
// Covered by unused-imports
139+
'no-unused-vars': 'off',
140+
},
141+
};

0 commit comments

Comments
 (0)