airier 0.0.10 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +227 -231
- package/README.md +1 -1
- package/modules/eslint_config.js +14 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -1,168 +1,185 @@
|
|
|
1
1
|
# AI Coding Assistant Instructions
|
|
2
2
|
|
|
3
|
-
Write code that breathes. Think Ruby-like elegance meets modern
|
|
3
|
+
Write code that breathes. Think Ruby-like elegance meets modern js.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Important boundaries:
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- You do not touch files specified in `.gitignore`
|
|
8
|
+
- You do not touch `.env` or `.env.*` files
|
|
9
|
+
- You do not touch dotfiles, pattern `.*`
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
==============================
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
```javascript
|
|
15
|
-
// ✅ CORRECT
|
|
16
|
-
const x = 5
|
|
17
|
-
return x + y
|
|
13
|
+
## 1. Code Philosophy
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
const x = 5;
|
|
21
|
-
return x + y;
|
|
22
|
-
```
|
|
15
|
+
**Code is written for human eyes**: Code is a description of the intent of a programmer, it must communicate the intent. For machines, the syntax and style is not relevant. Therefore, code style must be optimised for human eyes and mental models.
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
```javascript
|
|
26
|
-
// ✅ CORRECT - Airy and readable
|
|
27
|
-
const arr = [ 1, 2, 3 ]
|
|
28
|
-
const obj = { foo: 'bar' }
|
|
29
|
-
const result = my_func( arg1, arg2 )
|
|
30
|
-
if( condition ) {
|
|
31
|
-
console.log( `Value: ${ variable }` )
|
|
32
|
-
}
|
|
33
|
-
const arrow = ( a, b ) => a + b
|
|
34
|
-
|
|
35
|
-
// ❌ WRONG - Cramped
|
|
36
|
-
const arr = [1, 2, 3]
|
|
37
|
-
const obj = {foo: 'bar'}
|
|
38
|
-
const result = myFunc(arg1, arg2)
|
|
39
|
-
if(condition) {
|
|
40
|
-
console.log(`Value: ${variable}`)
|
|
41
|
-
}
|
|
42
|
-
```
|
|
17
|
+
**More comments is better than less comments**: Reading code can clarify function but not intention. Comments are a reminder to self, or an explanation to coworkers.
|
|
43
18
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const timeout_ms = 5000
|
|
48
|
-
const user_name = 'John'
|
|
49
|
-
const add_numbers = ( a, b ) => a + b
|
|
50
|
-
const fetch_user_data = async ( user_id ) => { }
|
|
19
|
+
**Readability Through Spacing**: Code needs room to breathe. Spacing makes structure visible at a glance.
|
|
20
|
+
|
|
21
|
+
**Remember**: Code is read far more than it's written. Make it beautiful, make it breathe, make it obvious.
|
|
51
22
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
23
|
+
==============================
|
|
24
|
+
|
|
25
|
+
## 2. Syntax preferences
|
|
26
|
+
|
|
27
|
+
Code should be elegant, not use superfluous characters, and have space to breathe. For example: do not use semicolons, add space in brackets. The linter will show you syntax preferences, to that end with every change learn the styling by:
|
|
28
|
+
|
|
29
|
+
1. save your changes and look at the syntax
|
|
30
|
+
2. run `npm run lint` and ignore the command output
|
|
31
|
+
3. look at how the linter changed the style, and mimic it in future responses.
|
|
32
|
+
|
|
33
|
+
==============================
|
|
34
|
+
|
|
35
|
+
## 3. Tooling preferences
|
|
36
|
+
|
|
37
|
+
### LLM agent context
|
|
38
|
+
|
|
39
|
+
Any LLM including you should always:
|
|
40
|
+
|
|
41
|
+
- Read the `AGENTS.md` file for instructions
|
|
42
|
+
- Check if `SPECIFICATION.md` exists, if so read it
|
|
43
|
+
- Check if `SPECIFICATION.*.md` patterned files exist, if so read them for context
|
|
44
|
+
- Check for all `*.md` files in the project root
|
|
45
|
+
|
|
46
|
+
### Node.js usage
|
|
47
|
+
|
|
48
|
+
- Use `nvm` for version management, with the latest LTS (24) in the `.nvmrc`
|
|
49
|
+
- Do not modify files in `node_modules/`
|
|
50
|
+
- Environment variables are stored in `.env` which is supported by node without dependencies
|
|
51
|
+
- Frontend code should use Vite for bundling
|
|
52
|
+
- Backend code should use Node.js
|
|
53
|
+
- Prefer javascript over typescript, including when setting up vite projects
|
|
54
|
+
|
|
55
|
+
### React usage
|
|
56
|
+
|
|
57
|
+
- Frontends should be built in react
|
|
58
|
+
- React should be used in frontend mode (no server components)
|
|
59
|
+
- Routing is done with `react-router` BrowserRouter
|
|
60
|
+
- State is put in the URL where possible using the `use-query-params` npm package
|
|
61
|
+
- State that is used in multiple places at once uses `zustand`
|
|
62
|
+
- Components follow a structure inspired by Atomic Design where they are split into:
|
|
63
|
+
- Atoms: stateless components
|
|
64
|
+
- Molecules: stateful components (may use Atoms)
|
|
65
|
+
- Pages: components rendered by the router
|
|
66
|
+
|
|
67
|
+
File structure in a react project:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
.
|
|
71
|
+
├── assets
|
|
72
|
+
├── package-lock.json
|
|
73
|
+
├── package.json
|
|
74
|
+
├── public
|
|
75
|
+
│ ├── assets
|
|
76
|
+
│ ├── favicon.ico
|
|
77
|
+
│ ├── logo192.png
|
|
78
|
+
│ ├── logo512.png
|
|
79
|
+
│ └── robots.txt
|
|
80
|
+
├── src
|
|
81
|
+
│ ├── App.jsx
|
|
82
|
+
│ ├── components
|
|
83
|
+
│ │ ├── atoms
|
|
84
|
+
│ │ ├── molecules
|
|
85
|
+
│ │ └── pages
|
|
86
|
+
│ ├── hooks
|
|
87
|
+
│ ├── index.css
|
|
88
|
+
│ ├── index.jsx
|
|
89
|
+
│ ├── modules
|
|
90
|
+
│ ├── routes
|
|
91
|
+
│ │ └── Routes.jsx
|
|
92
|
+
│ └── stores
|
|
93
|
+
└── vite.config.js
|
|
57
94
|
```
|
|
58
95
|
|
|
59
|
-
###
|
|
60
|
-
```javascript
|
|
61
|
-
// ✅ CORRECT
|
|
62
|
-
if( x > 5 ) { }
|
|
63
|
-
for( let i = 0; i < 10; i++ ) { }
|
|
64
|
-
while( condition ) { }
|
|
96
|
+
### Using Mentie Helpers
|
|
65
97
|
|
|
66
|
-
|
|
67
|
-
if (x > 5) { }
|
|
68
|
-
for (let i = 0; i < 10; i++) { }
|
|
69
|
-
```
|
|
98
|
+
If `mentie` is installed, **always use its utilities**. Check `node_modules/mentie/index.js` for available exports.
|
|
70
99
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// ✅ CORRECT
|
|
74
|
-
const process_data = ( data ) => {
|
|
75
|
-
const filtered = data.filter( item => item.active )
|
|
76
|
-
return filtered
|
|
77
|
-
}
|
|
100
|
+
```js
|
|
101
|
+
import { log, multiline_trim, shuffle_array } from 'mentie'
|
|
78
102
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
103
|
+
log.info( `User logged in:`, user_id )
|
|
104
|
+
|
|
105
|
+
const query = multiline_trim( `
|
|
106
|
+
SELECT * FROM users
|
|
107
|
+
WHERE active = true
|
|
108
|
+
` )
|
|
109
|
+
|
|
110
|
+
const randomized = shuffle_array( items )
|
|
84
111
|
```
|
|
85
112
|
|
|
86
|
-
|
|
113
|
+
==============================
|
|
87
114
|
|
|
88
|
-
|
|
89
|
-
|---------|---------|---------|
|
|
90
|
-
| Arrays | `[ items ]` | `[ 1, 2, 3 ]` |
|
|
91
|
-
| Objects | `{ key: value }` | `{ foo: 'bar' }` |
|
|
92
|
-
| Function calls | `func( args )` | `my_func( a, b )` |
|
|
93
|
-
| Arrow functions | `( args ) => { }` | `const fn = ( x ) => x * 2` |
|
|
94
|
-
| Template literals | `${ expr }` | `` `Hello ${ name }` `` |
|
|
95
|
-
| Blocks | `keyword( cond ) {` | `if( x > 5 ) {` |
|
|
115
|
+
## 3. Code style preferences
|
|
96
116
|
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
//
|
|
100
|
-
|
|
101
|
-
<div className="foo">{ children }</div>
|
|
117
|
+
### Always use template literals instead of strings
|
|
118
|
+
```js
|
|
119
|
+
// Use literals for regular strings
|
|
120
|
+
const name = `Ada Localace`
|
|
102
121
|
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
<div className="foo">{children}</div>
|
|
122
|
+
// Use templates for string manipulation too
|
|
123
|
+
const annotated_name = `${ name } ${ Math.random() }`
|
|
106
124
|
```
|
|
107
125
|
|
|
108
|
-
- No `import React from 'react'` needed (modern React)
|
|
109
|
-
- Prefer functional components with hooks
|
|
110
|
-
- PropTypes optional (use TypeScript if you need types)
|
|
111
126
|
|
|
112
|
-
|
|
127
|
+
### snake_case for Everything
|
|
128
|
+
```js
|
|
129
|
+
const timeout_ms = 5_000
|
|
130
|
+
const user_name = 'John'
|
|
131
|
+
const fetch_user_data = async ( user_id ) => { }
|
|
132
|
+
```
|
|
113
133
|
|
|
114
|
-
###
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
const create_greeting = ( config ) => {
|
|
118
|
-
const { name, formal = false } = config
|
|
119
|
-
return formal ? `Hello, ${ name }` : `Hey ${ name }`
|
|
120
|
-
}
|
|
134
|
+
### Use comments to describe intent
|
|
135
|
+
```js
|
|
136
|
+
import { abort_controller } from 'mentie'
|
|
121
137
|
|
|
122
|
-
//
|
|
123
|
-
const
|
|
138
|
+
// Load the users with a timeout to prevent hanging
|
|
139
|
+
const fetch_options = abort_controller( { timeout_ms: 10_000 } )
|
|
140
|
+
const { uids } = await fetch( 'https://...', fetch_options ).then( res => res.json() )
|
|
141
|
+
|
|
142
|
+
// Parallel fetch resulting data to optimise speed
|
|
143
|
+
const downstream_data = await Promise.all( uids.map( async uid => fetch( `https://...?uid=${ uid }` ) ) )
|
|
124
144
|
```
|
|
125
145
|
|
|
126
|
-
### ❌ Don't Add Unrequested Features
|
|
127
|
-
```javascript
|
|
128
|
-
// ❌ WRONG - validation, logging, backup not requested
|
|
129
|
-
const save_user = ( user, options = {} ) => {
|
|
130
|
-
if( options.validate ) validate( user )
|
|
131
|
-
if( options.log ) console.log( user )
|
|
132
|
-
return db.save( user )
|
|
133
|
-
}
|
|
134
146
|
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
### Prioritise semantic clarity over optimisation
|
|
148
|
+
Don't reassign variables. Create new bindings for each transformation step.
|
|
149
|
+
```js
|
|
150
|
+
// Parse a dataset - each step is clear and traceable
|
|
151
|
+
const data = []
|
|
152
|
+
const filtered_data = data.filter( ( { relevant_number } ) => relevant_number > 1.5 )
|
|
153
|
+
const restructured_data = filtered_data.map( ( { base_value, second_value } ) => ( { composite_value: base_value * second_value } ) )
|
|
154
|
+
return restructured_data
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
### Lean towards onelining single statements
|
|
159
|
+
Single statements can be on one line. Multiple statements need blocks.
|
|
160
|
+
```js
|
|
161
|
+
// ✅ Single statement - oneline it
|
|
162
|
+
if( condition ) log.info( `Message` )
|
|
163
|
+
const filtered_data = data.filter( ( { relevant_property } ) => relevant_property )
|
|
137
164
|
```
|
|
138
165
|
|
|
139
|
-
## Functional Programming Over Loops
|
|
140
166
|
|
|
141
|
-
|
|
167
|
+
### Functional Programming Over Loops
|
|
168
|
+
|
|
169
|
+
Prefer `.map()`, `.filter()`, `.reduce()`, `.find()`, `.some()`, `.every()` over `for`/`while` loops.
|
|
142
170
|
|
|
143
|
-
```
|
|
144
|
-
// ✅ CORRECT - Functional approach
|
|
171
|
+
```js
|
|
145
172
|
const active_users = users.filter( u => u.active )
|
|
146
|
-
const user_names =
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
// ❌ WRONG - Primitive loops
|
|
150
|
-
const active_users = []
|
|
151
|
-
for( let i = 0; i < users.length; i++ ) {
|
|
152
|
-
if( users[i].active ) {
|
|
153
|
-
active_users.push( users[i] )
|
|
154
|
-
}
|
|
155
|
-
}
|
|
173
|
+
const user_names = active_users.map( u => u.name )
|
|
174
|
+
const total_age = user_names.reduce( ( sum, age ) => sum + age, 0 )
|
|
156
175
|
```
|
|
157
176
|
|
|
158
|
-
**Prefer in order**: `.map()`, `.filter()`, `.reduce()`, `.find()`, `.some()`, `.every()` over `for`/`while` loops.
|
|
159
177
|
|
|
160
|
-
|
|
178
|
+
### JSDoc for Exported Functions
|
|
161
179
|
|
|
162
|
-
**CRITICAL**: Every exported function MUST have JSDoc
|
|
180
|
+
**CRITICAL**: Every exported function MUST have JSDoc. Verify before finishing!
|
|
163
181
|
|
|
164
|
-
```
|
|
165
|
-
// ✅ CORRECT
|
|
182
|
+
```js
|
|
166
183
|
/**
|
|
167
184
|
* Fetches user data from the API
|
|
168
185
|
* @param {string} user_id - The ID of the user to fetch
|
|
@@ -172,148 +189,127 @@ export const fetch_user = async ( user_id ) => {
|
|
|
172
189
|
const response = await api.get( `/users/${ user_id }` )
|
|
173
190
|
return response.data
|
|
174
191
|
}
|
|
175
|
-
|
|
176
|
-
// ❌ WRONG - No JSDoc
|
|
177
|
-
export const fetch_user = async ( user_id ) => {
|
|
178
|
-
const response = await api.get( `/users/${ user_id }` )
|
|
179
|
-
return response.data
|
|
180
|
-
}
|
|
181
192
|
```
|
|
182
193
|
|
|
183
|
-
|
|
194
|
+
### Error Handling
|
|
184
195
|
|
|
185
|
-
|
|
196
|
+
Only at boundaries (user input, external APIs). Trust internal code. Remember `finally` for cleanup!
|
|
186
197
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
**IMPORTANT**: Remember the `finally` block! It's perfect for cleanup operations and runs regardless of success/failure.
|
|
190
|
-
|
|
191
|
-
```javascript
|
|
192
|
-
// ✅ CORRECT - Using finally for cleanup
|
|
198
|
+
```js
|
|
193
199
|
const fetch_user = async ( id ) => {
|
|
194
|
-
const loading_indicator = start_loading()
|
|
195
200
|
|
|
196
201
|
try {
|
|
202
|
+
start_loading()
|
|
197
203
|
const response = await api.get( `/users/${ id }` )
|
|
198
204
|
return response.data
|
|
199
205
|
} catch( error ) {
|
|
200
206
|
throw new Error( `Failed to fetch user: ${ error.message }` )
|
|
201
207
|
} finally {
|
|
202
|
-
|
|
203
|
-
stop_loading( loading_indicator )
|
|
208
|
+
stop_loading()
|
|
204
209
|
}
|
|
205
210
|
}
|
|
211
|
+
```
|
|
206
212
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
213
|
+
### Complete example of well styled code
|
|
214
|
+
|
|
215
|
+
```js
|
|
216
|
+
/**
|
|
217
|
+
* Fetches and processes active users from the API
|
|
218
|
+
* @param {Object} options
|
|
219
|
+
* @param {Array} options.user_ids - User ids to fetch
|
|
220
|
+
* @param {Number} options.limit - Limit the amount of users to fetch
|
|
221
|
+
* @returns {Promise<Array>} Processed user objects
|
|
222
|
+
*/
|
|
223
|
+
export async function fetch_and_process_users( { user_ids, limit=5 } = {} ) {
|
|
224
|
+
|
|
225
|
+
// Get users to ensure up to date data
|
|
226
|
+
const users = await api.get( `/users`, { user_ids, limit } )
|
|
216
227
|
|
|
217
|
-
//
|
|
218
|
-
const
|
|
228
|
+
// Keep only active users to prevent wasting time on inactive ones
|
|
229
|
+
const filtered_users = users.filter( ( { active } ) => active )
|
|
219
230
|
|
|
220
|
-
//
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
231
|
+
// Annotate users with value based on local conversion so we can show the user the computed values
|
|
232
|
+
const annotated_users = filtered_users.map( ( { score, user } ) => ( { score: score * local_conversion_value, ...user } ) )
|
|
233
|
+
|
|
234
|
+
// Return users with annotated data
|
|
235
|
+
return annotated_users
|
|
224
236
|
}
|
|
225
|
-
```
|
|
226
237
|
|
|
227
|
-
|
|
238
|
+
```
|
|
228
239
|
|
|
229
|
-
If the `mentie` package is installed in the project, **always use its utilities** instead of reinventing them.
|
|
230
240
|
|
|
231
|
-
|
|
241
|
+
### React Specific styling
|
|
232
242
|
|
|
233
|
-
|
|
234
|
-
```javascript
|
|
235
|
-
import { log } from 'mentie'
|
|
243
|
+
**Exception to snake_case**: React component names MUST be PascalCase (required by React/JSX).
|
|
236
244
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
245
|
+
```js
|
|
246
|
+
// ✅ Components are PascalCase
|
|
247
|
+
const UserProfile = ( { user_id } ) => { }
|
|
248
|
+
const DataTable = () => { }
|
|
241
249
|
|
|
242
|
-
//
|
|
243
|
-
|
|
250
|
+
// ✅ Everything else is snake_case
|
|
251
|
+
const user_name = `John`
|
|
252
|
+
const fetch_user_data = async ( user_id ) => { }
|
|
244
253
|
```
|
|
245
254
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
255
|
+
**File naming**: Component files use PascalCase to match component name.
|
|
256
|
+
- `UserProfile.jsx` - Component files
|
|
257
|
+
- `fetch_user_data.js` - Utility files
|
|
249
258
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
SELECT *
|
|
253
|
-
FROM users
|
|
254
|
-
WHERE active = true
|
|
255
|
-
` )
|
|
259
|
+
**Event handlers**:
|
|
260
|
+
- Do not name things after the event (e.g. `on_click`) but name them actions (e.g. `save_user`)
|
|
256
261
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
262
|
+
**JSX spacing and structure**:
|
|
263
|
+
```js
|
|
264
|
+
// Styled and stateless sections use arrow functions or variables
|
|
265
|
+
const Header = styled.aside`
|
|
266
|
+
color: red;
|
|
267
|
+
`
|
|
260
268
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
import { shuffle_array } from 'mentie'
|
|
269
|
+
// Use JSX comments to separate sections
|
|
270
|
+
export function UserProfile( { user_id, on_update } ) {
|
|
264
271
|
|
|
265
|
-
//
|
|
266
|
-
const
|
|
272
|
+
// Hooks at the top
|
|
273
|
+
const [ user_data, set_user_data ] = useState( null )
|
|
274
|
+
const [ is_loading, set_is_loading ] = useState( false )
|
|
267
275
|
|
|
268
|
-
//
|
|
269
|
-
|
|
270
|
-
|
|
276
|
+
// Effects after hooks
|
|
277
|
+
useEffect( () => {
|
|
278
|
+
fetch_user_data( user_id ).then( set_user_data )
|
|
279
|
+
}, [ user_id ] )
|
|
271
280
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
2. If present, read `node_modules/mentie/index.js` to see all available exports
|
|
275
|
-
3. Use mentie's utilities instead of reimplementing them
|
|
281
|
+
// Event handlers
|
|
282
|
+
const update_user = () => on_update( user_data )
|
|
276
283
|
|
|
277
|
-
|
|
284
|
+
// Conditional rendering
|
|
285
|
+
if( is_loading ) return <LoadingSpinner />
|
|
278
286
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
} ) )
|
|
295
|
-
|
|
296
|
-
return processed
|
|
287
|
+
// Do not add () around returned jsx.
|
|
288
|
+
return <>
|
|
289
|
+
|
|
290
|
+
{ /* Profile header section */ }
|
|
291
|
+
<Header title={ user_data.name } />
|
|
292
|
+
|
|
293
|
+
{ /* Profile details */ }
|
|
294
|
+
<div className="profile">
|
|
295
|
+
{ user_data.details }
|
|
296
|
+
</div>
|
|
297
|
+
|
|
298
|
+
{ /* Actions */ }
|
|
299
|
+
<Button on_click={ update_user }>Save</Button>
|
|
300
|
+
|
|
301
|
+
</>
|
|
297
302
|
}
|
|
298
303
|
|
|
299
|
-
|
|
304
|
+
// Lists need keys
|
|
305
|
+
const user_list = users.map( ( user ) => <UserCard key={ user.id } user={ user } /> )
|
|
306
|
+
|
|
307
|
+
// Props always have spacing
|
|
308
|
+
<Component prop={ value } />
|
|
309
|
+
<div className="foo">{ children }</div>
|
|
300
310
|
```
|
|
301
311
|
|
|
302
|
-
## Checklist
|
|
303
312
|
|
|
304
|
-
- [ ] No semicolons
|
|
305
|
-
- [ ] Spacing in all brackets: `[ ]`, `{ }`, `( )`, `${ }`
|
|
306
|
-
- [ ] snake_case for all variables and functions
|
|
307
|
-
- [ ] 4-space indentation
|
|
308
|
-
- [ ] `const`/`let` only (never `var`)
|
|
309
|
-
- [ ] Arrow functions preferred
|
|
310
|
-
- [ ] Higher-level functions (.map, .filter, .reduce) over loops
|
|
311
|
-
- [ ] JSDoc on ALL exported functions (verify before finishing!)
|
|
312
|
-
- [ ] Consider `finally` block for cleanup in try/catch
|
|
313
|
-
- [ ] Check if `mentie` is installed and use its helpers (log, multiline_trim, etc.)
|
|
314
|
-
- [ ] No unnecessary features or abstractions
|
|
315
|
-
- [ ] Dead code completely removed
|
|
316
313
|
|
|
317
|
-
---
|
|
318
314
|
|
|
319
|
-
|
|
315
|
+
|
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ npm pkg set scripts.lint="eslint --fix src"
|
|
|
18
18
|
npx husky init
|
|
19
19
|
|
|
20
20
|
# Download files (using new ESLint 9 flat config format)
|
|
21
|
-
curl https://raw.githubusercontent.com/actuallymentor/airier/main/eslint.config.js --output eslint.config.js
|
|
21
|
+
curl https://raw.githubusercontent.com/actuallymentor/airier/main/eslint.config.example.js --output eslint.config.js
|
|
22
22
|
curl https://raw.githubusercontent.com/actuallymentor/airier/main/.vscode/settings.json --output .vscode/settings.json
|
|
23
23
|
curl https://raw.githubusercontent.com/actuallymentor/airier/main/.husky/pre-commit --output .husky/pre-commit
|
|
24
24
|
curl https://raw.githubusercontent.com/actuallymentor/airier/main/.babelrc --output .babelrc
|
package/modules/eslint_config.js
CHANGED
|
@@ -10,6 +10,16 @@ import styleguide from './styleguide.js'
|
|
|
10
10
|
|
|
11
11
|
// Export the flat config as an array
|
|
12
12
|
export default [
|
|
13
|
+
// Global ignores for build output and dependencies
|
|
14
|
+
{
|
|
15
|
+
ignores: [
|
|
16
|
+
'**/dist/**',
|
|
17
|
+
'**/build/**',
|
|
18
|
+
'**/node_modules/**',
|
|
19
|
+
'**/.next/**',
|
|
20
|
+
'**/coverage/**'
|
|
21
|
+
]
|
|
22
|
+
},
|
|
13
23
|
// Apply to all JavaScript and JSX files
|
|
14
24
|
{
|
|
15
25
|
files: [ '**/*.js', '**/*.jsx', '**/*.cjs', '**/*.mjs' ],
|
|
@@ -19,6 +29,9 @@ export default [
|
|
|
19
29
|
parserOptions: {
|
|
20
30
|
ecmaVersion: 2020,
|
|
21
31
|
requireConfigFile: false,
|
|
32
|
+
babelOptions: {
|
|
33
|
+
presets: [ '@babel/preset-react' ]
|
|
34
|
+
},
|
|
22
35
|
ecmaFeatures: {
|
|
23
36
|
jsx: true
|
|
24
37
|
}
|
|
@@ -38,7 +51,7 @@ export default [
|
|
|
38
51
|
|
|
39
52
|
settings: {
|
|
40
53
|
react: {
|
|
41
|
-
version: '
|
|
54
|
+
version: '19'
|
|
42
55
|
}
|
|
43
56
|
},
|
|
44
57
|
|