nollm 0.1.0 → 0.2.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/README.md +22 -22
- package/package.json +1 -1
- package/src/cli.js +1 -1
- package/src/config.js +14 -2
- package/src/index.d.ts +4 -0
- package/src/rules.js +211 -6
package/README.md
CHANGED
|
@@ -80,28 +80,28 @@ Files of other types, binary files, lockfiles, minified files, and files over 2
|
|
|
80
80
|
|
|
81
81
|
## Rules
|
|
82
82
|
|
|
83
|
-
| Rule
|
|
84
|
-
|
|
|
85
|
-
| `banned-word`
|
|
86
|
-
| `em-dash`
|
|
87
|
-
| `bold-list-item`
|
|
88
|
-
| `filler-word`
|
|
89
|
-
| `llm-vocabulary`
|
|
90
|
-
| `chat-opener`
|
|
91
|
-
| `chat-closer`
|
|
92
|
-
| `ai-disclosure`
|
|
93
|
-
| `contrast-cliche`
|
|
94
|
-
| `rhetorical-question`
|
|
95
|
-
| `emoji-list`
|
|
96
|
-
| `
|
|
97
|
-
| `what-comment`
|
|
98
|
-
| `quoted-error`
|
|
99
|
-
| `dramatic-verb`
|
|
100
|
-
| `parenthetical-aside`
|
|
101
|
-
| `long-sentence`
|
|
102
|
-
| `wall-of-text`
|
|
103
|
-
| `uniform-paragraphs`
|
|
104
|
-
| `uniform-sentences`
|
|
83
|
+
| Rule | Catches |
|
|
84
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
85
|
+
| `banned-word` | genuinely, load-bearing, crutch, spearheaded, fails loudly, and friends |
|
|
86
|
+
| `em-dash` | The em dash character |
|
|
87
|
+
| `bold-list-item` | List items like `- **Label:** plain text` |
|
|
88
|
+
| `filler-word` | simply, seamlessly, seamless, robust |
|
|
89
|
+
| `llm-vocabulary` | delve, tapestry, crucial, game-changer, battle-tested, and more |
|
|
90
|
+
| `chat-opener` | Lines that start with "Great question", "Certainly", "Let me", and more |
|
|
91
|
+
| `chat-closer` | "Hope this helps", "Let me know if", "Feel free to", and more |
|
|
92
|
+
| `ai-disclosure` | "As an AI", "my training data", and more |
|
|
93
|
+
| `contrast-cliche` | "not just X, but Y" and "it's not X, it's Y" |
|
|
94
|
+
| `rhetorical-question` | "Why? Because" and "The result?" |
|
|
95
|
+
| `emoji-list` | List items that start with an emoji |
|
|
96
|
+
| `no-short-term-relevance` | Comments that stop making sense once the change lands: "no longer", "no behavior change", "for now", "Previously," |
|
|
97
|
+
| `what-comment` | Comments that narrate the code: "This function returns", "Loop over" |
|
|
98
|
+
| `quoted-error` | Comments that quote an error message: `"Cannot read properties of..."` |
|
|
99
|
+
| `dramatic-verb` | blows up, dies with, falls over, chokes on, and friends |
|
|
100
|
+
| `parenthetical-aside` | Asides like `(and their compiled handles)` |
|
|
101
|
+
| `long-sentence` | A sentence over 30 words |
|
|
102
|
+
| `wall-of-text` | A paragraph over 120 words or 7 sentences |
|
|
103
|
+
| `uniform-paragraphs` | Three or more paragraphs in a row of about the same length |
|
|
104
|
+
| `uniform-sentences` | Four or more sentences of about the same length |
|
|
105
105
|
|
|
106
106
|
Run `nollm --list-rules` for the full list with the scope of each rule.
|
|
107
107
|
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -61,7 +61,7 @@ export async function main(
|
|
|
61
61
|
if (values["list-rules"]) {
|
|
62
62
|
for (let i = 0; i < rules.length; i++) {
|
|
63
63
|
const scope = (rules[i].scope ?? "text").padEnd(10);
|
|
64
|
-
stdout.write(`${rules[i].id.padEnd(
|
|
64
|
+
stdout.write(`${rules[i].id.padEnd(24)} ${scope} ${rules[i].message}\n`);
|
|
65
65
|
}
|
|
66
66
|
return 0;
|
|
67
67
|
}
|
package/src/config.js
CHANGED
|
@@ -62,7 +62,7 @@ function resolveRules(overrides = {}, words = []) {
|
|
|
62
62
|
|
|
63
63
|
for (let i = 0; i < builtinRules.length; i++) {
|
|
64
64
|
const rule = builtinRules[i];
|
|
65
|
-
const override = overrides
|
|
65
|
+
const override = overrideFor(overrides, rule);
|
|
66
66
|
if (override === false) continue;
|
|
67
67
|
rules.push(isObject(override) ? customRule(rule.id, override, rule) : rule);
|
|
68
68
|
}
|
|
@@ -70,7 +70,7 @@ function resolveRules(overrides = {}, words = []) {
|
|
|
70
70
|
for (const id in overrides) {
|
|
71
71
|
const override = overrides[id];
|
|
72
72
|
if (!isObject(override)) continue;
|
|
73
|
-
if (builtinRules.some((rule) => rule.id
|
|
73
|
+
if (builtinRules.some((rule) => namesOf(rule).includes(id))) continue;
|
|
74
74
|
rules.push(customRule(id, override));
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -86,6 +86,18 @@ function resolveRules(overrides = {}, words = []) {
|
|
|
86
86
|
return rules;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* The config entry for a built in rule, under its id or one of its old ids.
|
|
91
|
+
*/
|
|
92
|
+
function overrideFor(overrides, rule) {
|
|
93
|
+
const name = namesOf(rule).find((candidate) => candidate in overrides);
|
|
94
|
+
return name === undefined ? undefined : overrides[name];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function namesOf(rule) {
|
|
98
|
+
return [rule.id].concat(rule.aliases ?? []);
|
|
99
|
+
}
|
|
100
|
+
|
|
89
101
|
/**
|
|
90
102
|
* Builds a rule from a config entry.
|
|
91
103
|
* Keys that the entry leaves out come from the built in rule, when there is one.
|
package/src/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export type Scope = "prose" | "comments" | "text" | "everywhere";
|
|
|
2
2
|
|
|
3
3
|
export interface PatternRule {
|
|
4
4
|
id: string;
|
|
5
|
+
/** Old ids of this rule. A config may still refer to the rule by one of them. */
|
|
6
|
+
aliases?: string[];
|
|
5
7
|
message: string;
|
|
6
8
|
pattern: RegExp;
|
|
7
9
|
scope?: Scope;
|
|
@@ -15,6 +17,8 @@ export interface ShapeFinding {
|
|
|
15
17
|
|
|
16
18
|
export interface CheckRule {
|
|
17
19
|
id: string;
|
|
20
|
+
/** Old ids of this rule. A config may still refer to the rule by one of them. */
|
|
21
|
+
aliases?: string[];
|
|
18
22
|
message: string;
|
|
19
23
|
check: (segments: Segment[], scope: Scope) => ShapeFinding[];
|
|
20
24
|
scope?: Scope;
|
package/src/rules.js
CHANGED
|
@@ -131,17 +131,55 @@ const AI_DISCLOSURES = [
|
|
|
131
131
|
"my training data",
|
|
132
132
|
];
|
|
133
133
|
|
|
134
|
-
|
|
134
|
+
// Talk that only makes sense while the change is under review.
|
|
135
|
+
// Once merged, nobody reading the code knows what "the old way" or "this PR" was.
|
|
136
|
+
const PR_TALK = [
|
|
137
|
+
// The change itself
|
|
135
138
|
"as requested",
|
|
136
139
|
"as discussed",
|
|
137
140
|
"per the discussion",
|
|
138
141
|
"per our discussion",
|
|
139
142
|
"per the review",
|
|
140
143
|
"per review",
|
|
144
|
+
"per feedback",
|
|
145
|
+
"based on feedback",
|
|
146
|
+
"review feedback",
|
|
147
|
+
"review comment",
|
|
148
|
+
"review comments",
|
|
149
|
+
"addressing feedback",
|
|
150
|
+
"addresses feedback",
|
|
151
|
+
"addressed feedback",
|
|
152
|
+
"requested changes",
|
|
153
|
+
"code review",
|
|
154
|
+
"reviewer",
|
|
155
|
+
"reviewers",
|
|
141
156
|
"this pr",
|
|
157
|
+
"this mr",
|
|
158
|
+
"pr description",
|
|
159
|
+
"pull request",
|
|
160
|
+
"merge request",
|
|
142
161
|
"this commit",
|
|
143
162
|
"this diff",
|
|
144
163
|
"this change",
|
|
164
|
+
"this refactor",
|
|
165
|
+
"the refactor",
|
|
166
|
+
"this migration",
|
|
167
|
+
"this upgrade",
|
|
168
|
+
"the upgrade",
|
|
169
|
+
"after upgrading",
|
|
170
|
+
"before upgrading",
|
|
171
|
+
"since upgrading",
|
|
172
|
+
"version bump",
|
|
173
|
+
"this bump",
|
|
174
|
+
"cherry-picked",
|
|
175
|
+
"cherry picked",
|
|
176
|
+
"backported",
|
|
177
|
+
"rebased",
|
|
178
|
+
"merge conflict",
|
|
179
|
+
"merge conflicts",
|
|
180
|
+
"work in progress",
|
|
181
|
+
"wip",
|
|
182
|
+
// How the code used to be
|
|
145
183
|
"no longer",
|
|
146
184
|
"used to be",
|
|
147
185
|
"used to use",
|
|
@@ -164,10 +202,176 @@ const DIFF_TALK = [
|
|
|
164
202
|
"now handles",
|
|
165
203
|
"now lives",
|
|
166
204
|
"moved to",
|
|
205
|
+
"never worked",
|
|
206
|
+
"wasn't working",
|
|
207
|
+
"was not working",
|
|
208
|
+
"weren't working",
|
|
209
|
+
"were not working",
|
|
210
|
+
"didn't work before",
|
|
211
|
+
"did not work before",
|
|
212
|
+
"stopped working",
|
|
213
|
+
"was failing",
|
|
214
|
+
"were failing",
|
|
215
|
+
"started failing",
|
|
216
|
+
"kept failing",
|
|
217
|
+
"on the main branch",
|
|
218
|
+
"on the master branch",
|
|
219
|
+
"compared to main",
|
|
220
|
+
"compared to master",
|
|
221
|
+
// Claims that nothing changed
|
|
222
|
+
"no behavior change",
|
|
223
|
+
"no behaviour change",
|
|
224
|
+
"no functional change",
|
|
225
|
+
"no functional changes",
|
|
226
|
+
"no-op change",
|
|
227
|
+
"behavior is unchanged",
|
|
228
|
+
"behaviour is unchanged",
|
|
229
|
+
"behavior unchanged",
|
|
230
|
+
"behaviour unchanged",
|
|
231
|
+
"no change in behavior",
|
|
232
|
+
"no change in behaviour",
|
|
233
|
+
"same as before",
|
|
234
|
+
"same behavior as before",
|
|
235
|
+
"same behaviour as before",
|
|
236
|
+
"behaves as before",
|
|
237
|
+
"behaves the same",
|
|
238
|
+
"works the same",
|
|
239
|
+
"functionally equivalent",
|
|
240
|
+
"functionally identical",
|
|
241
|
+
"preserves behavior",
|
|
242
|
+
"preserves behaviour",
|
|
243
|
+
"preserve behavior",
|
|
244
|
+
"preserve behaviour",
|
|
245
|
+
"preserves existing behavior",
|
|
246
|
+
"preserves existing behaviour",
|
|
247
|
+
"existing behavior",
|
|
248
|
+
"existing behaviour",
|
|
249
|
+
"unchanged from",
|
|
250
|
+
// Leaving things as they were
|
|
251
|
+
"keeping it off",
|
|
252
|
+
"keeping it on",
|
|
253
|
+
"keeping this off",
|
|
254
|
+
"keeping this on",
|
|
255
|
+
"keeping it disabled",
|
|
256
|
+
"keeping it enabled",
|
|
257
|
+
"keeping this disabled",
|
|
258
|
+
"keeping this enabled",
|
|
259
|
+
"keep it off",
|
|
260
|
+
"keep this off",
|
|
261
|
+
"kept as is",
|
|
262
|
+
"kept as-is",
|
|
263
|
+
"left as is",
|
|
264
|
+
"left as-is",
|
|
265
|
+
"leave as is",
|
|
266
|
+
"leave as-is",
|
|
267
|
+
"leaving as is",
|
|
268
|
+
"leaving as-is",
|
|
269
|
+
"left in place",
|
|
270
|
+
"left untouched",
|
|
271
|
+
"left alone",
|
|
272
|
+
"leaving this alone",
|
|
273
|
+
"not touching",
|
|
274
|
+
"didn't touch",
|
|
275
|
+
"did not touch",
|
|
276
|
+
// Scope and follow-ups
|
|
277
|
+
"for now",
|
|
278
|
+
"out of scope",
|
|
279
|
+
"scope of this",
|
|
280
|
+
"follow-up pr",
|
|
281
|
+
"follow up pr",
|
|
282
|
+
"in a follow-up",
|
|
283
|
+
"in a follow up",
|
|
284
|
+
"as a follow-up",
|
|
285
|
+
"as a follow up",
|
|
286
|
+
"separate pr",
|
|
287
|
+
"later pr",
|
|
288
|
+
"future pr",
|
|
289
|
+
"another pr",
|
|
290
|
+
"next pr",
|
|
291
|
+
"will be removed",
|
|
292
|
+
"can be removed",
|
|
293
|
+
"to be removed",
|
|
294
|
+
"should be removed",
|
|
295
|
+
"safe to remove",
|
|
296
|
+
"safe to delete",
|
|
297
|
+
"can be deleted",
|
|
298
|
+
"will be deleted",
|
|
299
|
+
"remove this once",
|
|
300
|
+
"remove this after",
|
|
301
|
+
"remove this when",
|
|
302
|
+
"delete this once",
|
|
303
|
+
"delete this after",
|
|
304
|
+
"clean up later",
|
|
305
|
+
"cleanup later",
|
|
306
|
+
"clean this up later",
|
|
307
|
+
"will clean up",
|
|
308
|
+
"will be cleaned up",
|
|
309
|
+
"quick fix",
|
|
310
|
+
"quick hack",
|
|
311
|
+
"quick and dirty",
|
|
312
|
+
"band-aid",
|
|
313
|
+
"bandaid",
|
|
314
|
+
"band aid",
|
|
315
|
+
"stopgap",
|
|
316
|
+
"stop-gap",
|
|
317
|
+
"stop gap",
|
|
318
|
+
"hotfix",
|
|
319
|
+
"hot fix",
|
|
320
|
+
// The author talking about their own process
|
|
321
|
+
"tested locally",
|
|
322
|
+
"verified locally",
|
|
323
|
+
"confirmed locally",
|
|
324
|
+
"works locally",
|
|
325
|
+
"tested with",
|
|
326
|
+
"tested on",
|
|
327
|
+
"tested against",
|
|
328
|
+
"verified with",
|
|
329
|
+
"confirmed with",
|
|
330
|
+
"ci passes",
|
|
331
|
+
"passes ci",
|
|
332
|
+
"ci is green",
|
|
333
|
+
"ci was failing",
|
|
334
|
+
"ci fails",
|
|
335
|
+
"ci failed",
|
|
336
|
+
"i tested",
|
|
337
|
+
"i verified",
|
|
338
|
+
"i checked",
|
|
339
|
+
"i confirmed",
|
|
340
|
+
"i tried",
|
|
341
|
+
"i went with",
|
|
342
|
+
"i chose",
|
|
343
|
+
"i opted",
|
|
344
|
+
"i decided",
|
|
345
|
+
"i ended up",
|
|
346
|
+
"i left",
|
|
347
|
+
"i kept",
|
|
348
|
+
"i removed",
|
|
349
|
+
"i replaced",
|
|
350
|
+
"i added",
|
|
351
|
+
"i moved",
|
|
352
|
+
"i renamed",
|
|
353
|
+
"i changed",
|
|
354
|
+
"i updated",
|
|
355
|
+
"i bumped",
|
|
356
|
+
"i couldn't",
|
|
357
|
+
"i could not",
|
|
358
|
+
"i'm not sure",
|
|
359
|
+
"i am not sure",
|
|
360
|
+
"not sure if",
|
|
361
|
+
"not sure why",
|
|
362
|
+
"not sure whether",
|
|
363
|
+
"we tested",
|
|
364
|
+
"we verified",
|
|
365
|
+
"we confirmed",
|
|
366
|
+
"we decided",
|
|
367
|
+
"we went with",
|
|
368
|
+
"we opted",
|
|
369
|
+
"we couldn't",
|
|
370
|
+
"we could not",
|
|
167
371
|
];
|
|
168
372
|
|
|
169
|
-
//
|
|
170
|
-
const
|
|
373
|
+
// PR talk only when it opens a sentence. "used previously" is fine.
|
|
374
|
+
const PR_OPENERS = ["previously", "formerly", "originally"];
|
|
171
375
|
|
|
172
376
|
const DRAMATIC_VERBS = [
|
|
173
377
|
"blow up",
|
|
@@ -323,10 +527,11 @@ export const rules = [
|
|
|
323
527
|
scope: "prose",
|
|
324
528
|
},
|
|
325
529
|
{
|
|
326
|
-
id: "
|
|
327
|
-
|
|
530
|
+
id: "no-short-term-relevance",
|
|
531
|
+
aliases: ["diff-comment"],
|
|
532
|
+
message: "Comment only makes sense while the change is under review. Say it in the PR",
|
|
328
533
|
pattern: new RegExp(
|
|
329
|
-
String.raw`\b(?:${words(
|
|
534
|
+
String.raw`\b(?:${words(PR_TALK)})\b|${SENTENCE_START}(?:${words(PR_OPENERS)})\b`,
|
|
330
535
|
"gmi",
|
|
331
536
|
),
|
|
332
537
|
scope: "comments",
|