opengrammar-server 2.0.615350
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.npm.md +95 -0
- package/bin/opengrammar-server.js +111 -0
- package/dist/server.js +48639 -0
- package/package.json +80 -0
- package/server-node.ts +159 -0
- package/server.ts +15 -0
- package/src/analyzer.ts +542 -0
- package/src/dictionary.ts +1973 -0
- package/src/index.ts +978 -0
- package/src/nlp/nlp-engine.ts +17 -0
- package/src/nlp/tone-analyzer.ts +269 -0
- package/src/rephraser.ts +146 -0
- package/src/rules/categories/academic-writing.ts +182 -0
- package/src/rules/categories/adjectives-adverbs.ts +152 -0
- package/src/rules/categories/articles.ts +160 -0
- package/src/rules/categories/business-writing.ts +250 -0
- package/src/rules/categories/capitalization.ts +79 -0
- package/src/rules/categories/clarity.ts +117 -0
- package/src/rules/categories/common-errors.ts +601 -0
- package/src/rules/categories/confused-words.ts +219 -0
- package/src/rules/categories/conjunctions.ts +176 -0
- package/src/rules/categories/dangling-modifiers.ts +123 -0
- package/src/rules/categories/formality.ts +274 -0
- package/src/rules/categories/formatting-idioms.ts +323 -0
- package/src/rules/categories/gerund-infinitive.ts +274 -0
- package/src/rules/categories/grammar-advanced.ts +294 -0
- package/src/rules/categories/grammar.ts +286 -0
- package/src/rules/categories/inclusive-language.ts +280 -0
- package/src/rules/categories/nouns-pronouns.ts +233 -0
- package/src/rules/categories/prepositions-extended.ts +217 -0
- package/src/rules/categories/prepositions.ts +159 -0
- package/src/rules/categories/punctuation.ts +347 -0
- package/src/rules/categories/quantity-agreement.ts +200 -0
- package/src/rules/categories/readability.ts +293 -0
- package/src/rules/categories/sentence-structure.ts +100 -0
- package/src/rules/categories/spelling-advanced.ts +164 -0
- package/src/rules/categories/spelling.ts +119 -0
- package/src/rules/categories/style-tone.ts +511 -0
- package/src/rules/categories/style.ts +78 -0
- package/src/rules/categories/subject-verb-agreement.ts +201 -0
- package/src/rules/categories/tone-rules.ts +206 -0
- package/src/rules/categories/verb-tense.ts +582 -0
- package/src/rules/context-filter.ts +446 -0
- package/src/rules/index.ts +96 -0
- package/src/rules/ruleset-part1-cj-pu-sp.json +657 -0
- package/src/rules/ruleset-part1-np-ad-aa-pr.json +831 -0
- package/src/rules/ruleset-part1-ss-vt.json +907 -0
- package/src/rules/ruleset-part2-cw-st-nf.json +318 -0
- package/src/rules/ruleset-part3-aw-bw-il-rd.json +161 -0
- package/src/rules/types.ts +79 -0
- package/src/shared-types.ts +152 -0
- package/src/spellchecker.ts +418 -0
- package/tsconfig.json +25 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { createRegexRule, type Rule } from '../types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ════════════════════════════════════════════════════════
|
|
5
|
+
* Subject-Verb Agreement — SVA Module
|
|
6
|
+
* The #1 grammar error category worldwide.
|
|
7
|
+
* ════════════════════════════════════════════════════════
|
|
8
|
+
*/
|
|
9
|
+
export const subjectVerbAgreementRules: Rule[] = [
|
|
10
|
+
|
|
11
|
+
// ─── PLURAL PRONOUNS + WAS ───
|
|
12
|
+
createRegexRule({
|
|
13
|
+
id: 'SVA_they_was',
|
|
14
|
+
category: 'grammar',
|
|
15
|
+
pattern: /\bthey\s+was\b/i,
|
|
16
|
+
suggestion: 'they were',
|
|
17
|
+
reason: 'Use "were" with plural subjects: "they were".',
|
|
18
|
+
}),
|
|
19
|
+
createRegexRule({
|
|
20
|
+
id: 'SVA_we_was',
|
|
21
|
+
category: 'grammar',
|
|
22
|
+
pattern: /\bwe\s+was\b/i,
|
|
23
|
+
suggestion: 'we were',
|
|
24
|
+
reason: 'Use "were" with plural subjects: "we were".',
|
|
25
|
+
}),
|
|
26
|
+
createRegexRule({
|
|
27
|
+
id: 'SVA_you_was',
|
|
28
|
+
category: 'grammar',
|
|
29
|
+
pattern: /\byou\s+was\b/i,
|
|
30
|
+
suggestion: 'you were',
|
|
31
|
+
reason: 'Use "were" with "you": "you were".',
|
|
32
|
+
}),
|
|
33
|
+
|
|
34
|
+
// ─── 3RD PERSON SINGULAR: DON'T / DOESN'T ───
|
|
35
|
+
createRegexRule({
|
|
36
|
+
id: 'SVA_he_dont',
|
|
37
|
+
category: 'grammar',
|
|
38
|
+
pattern: /\b(he|she|it)\s+don'?t\b/i,
|
|
39
|
+
suggestion: (m) => `${m[1]} doesn't`,
|
|
40
|
+
reason: 'Use "doesn\'t" (not "don\'t") with he/she/it.',
|
|
41
|
+
}),
|
|
42
|
+
createRegexRule({
|
|
43
|
+
id: 'SVA_name_dont',
|
|
44
|
+
category: 'grammar',
|
|
45
|
+
pattern: /\b(John|Jane|Mary|David|Sarah|Mike|Tom|Anna|Bob|Alice|Peter|Paul|Mark|Luke|James|Emma|Olivia|Liam|Noah|Sophia|Ava|student|teacher|manager|doctor|user|player|person|child|boy|girl|man|woman)\s+don'?t\b/i,
|
|
46
|
+
suggestion: (m) => `${m[1]} doesn't`,
|
|
47
|
+
reason: 'Use "doesn\'t" (not "don\'t") with a singular third-person subject.',
|
|
48
|
+
}),
|
|
49
|
+
|
|
50
|
+
// ─── 3RD PERSON SINGULAR: DO → DOES ───
|
|
51
|
+
createRegexRule({
|
|
52
|
+
id: 'SVA_he_do',
|
|
53
|
+
category: 'grammar',
|
|
54
|
+
pattern: /\b(he|she|it)\s+do\s+(not|well|better|worse|good|badly|much|little|more|less|anything|everything|nothing|something)\b/i,
|
|
55
|
+
suggestion: (m) => `${m[1]} does ${m[2]}`,
|
|
56
|
+
reason: 'Use "does" (not "do") with he/she/it.',
|
|
57
|
+
}),
|
|
58
|
+
|
|
59
|
+
// ─── SINGULAR INDEFINITE PRONOUNS + PLURAL VERB ───
|
|
60
|
+
createRegexRule({
|
|
61
|
+
id: 'SVA_everyone_have',
|
|
62
|
+
category: 'grammar',
|
|
63
|
+
pattern: /\b(everyone|everybody|someone|somebody|anyone|anybody|no one|nobody|each|either|neither)\s+have\b/i,
|
|
64
|
+
suggestion: (m) => `${m[1]} has`,
|
|
65
|
+
reason: `"${'"Everyone/somebody/each"'}" is singular. Use "has", not "have".`,
|
|
66
|
+
}),
|
|
67
|
+
createRegexRule({
|
|
68
|
+
id: 'SVA_everyone_are',
|
|
69
|
+
category: 'grammar',
|
|
70
|
+
pattern: /\b(everyone|everybody|someone|somebody|anyone|anybody|nobody|each)\s+are\b/i,
|
|
71
|
+
suggestion: (m) => `${m[1]} is`,
|
|
72
|
+
reason: 'Indefinite pronouns like "everyone" are singular. Use "is", not "are".',
|
|
73
|
+
}),
|
|
74
|
+
createRegexRule({
|
|
75
|
+
id: 'SVA_everyone_were',
|
|
76
|
+
category: 'grammar',
|
|
77
|
+
pattern: /\b(everyone|everybody|someone|somebody|anyone|anybody|nobody|each)\s+were\b(?!\s+to\b)/i,
|
|
78
|
+
suggestion: (m) => `${m[1]} was`,
|
|
79
|
+
reason: 'Indefinite pronouns like "everyone" are singular. Use "was", not "were".',
|
|
80
|
+
}),
|
|
81
|
+
|
|
82
|
+
// ─── NEITHER/EITHER + OF + PLURAL + PLURAL VERB ───
|
|
83
|
+
createRegexRule({
|
|
84
|
+
id: 'SVA_neither_of_are',
|
|
85
|
+
category: 'grammar',
|
|
86
|
+
pattern: /\b(neither|either)\s+of\s+(them|us|the\s+\w+)\s+are\b/i,
|
|
87
|
+
suggestion: (m) => `${m[1]} of ${m[2]} is`,
|
|
88
|
+
reason: '"Neither of" and "either of" take a singular verb.',
|
|
89
|
+
}),
|
|
90
|
+
createRegexRule({
|
|
91
|
+
id: 'SVA_neither_of_were',
|
|
92
|
+
category: 'grammar',
|
|
93
|
+
pattern: /\b(neither|either)\s+of\s+(them|us|the\s+\w+)\s+were\b/i,
|
|
94
|
+
suggestion: (m) => `${m[1]} of ${m[2]} was`,
|
|
95
|
+
reason: '"Neither of" and "either of" take a singular verb.',
|
|
96
|
+
}),
|
|
97
|
+
createRegexRule({
|
|
98
|
+
id: 'SVA_neither_of_have',
|
|
99
|
+
category: 'grammar',
|
|
100
|
+
pattern: /\b(neither|either)\s+of\s+(them|us|the\s+\w+)\s+have\b/i,
|
|
101
|
+
suggestion: (m) => `${m[1]} of ${m[2]} has`,
|
|
102
|
+
reason: '"Neither of" and "either of" take a singular verb.',
|
|
103
|
+
}),
|
|
104
|
+
|
|
105
|
+
// ─── EACH OF + PLURAL NOUN + PLURAL VERB ───
|
|
106
|
+
createRegexRule({
|
|
107
|
+
id: 'SVA_each_of_are',
|
|
108
|
+
category: 'grammar',
|
|
109
|
+
pattern: /\beach\s+of\s+(?:the\s+)?\w+\s+are\b/i,
|
|
110
|
+
suggestion: (m) => m[0].replace(/\bare\b/, 'is'),
|
|
111
|
+
reason: '"Each of" takes a singular verb.',
|
|
112
|
+
}),
|
|
113
|
+
|
|
114
|
+
// ─── "-ICS" NOUNS (always singular) ───
|
|
115
|
+
createRegexRule({
|
|
116
|
+
id: 'SVA_ics_are',
|
|
117
|
+
category: 'grammar',
|
|
118
|
+
pattern: /\b(mathematics|physics|economics|statistics|politics|athletics|ethics|genetics|linguistics|acoustics|aesthetics|electronics|gymnastics|cybernetics|robotics|phonetics|semantics|logistics)\s+are\b/i,
|
|
119
|
+
suggestion: (m) => `${m[1]} is`,
|
|
120
|
+
reason: `"${'"Mathematics/physics/economics"'}" and other -ics subjects are treated as singular.`,
|
|
121
|
+
}),
|
|
122
|
+
|
|
123
|
+
// ─── COLLECTIVE NOUNS (British vs American) ───
|
|
124
|
+
createRegexRule({
|
|
125
|
+
id: 'SVA_collective_is',
|
|
126
|
+
category: 'grammar',
|
|
127
|
+
pattern: /\b(the\s+)?(team|committee|board|jury|class|staff|faculty|government|army|club|crowd|family|audience|group|company|council|parliament|senate|congress|cabinet|band|crew|squad|panel)\s+are\b/i,
|
|
128
|
+
suggestion: (m) => `${m[1] || ''}${m[2]} is`,
|
|
129
|
+
reason: 'In American English, collective nouns like "team" and "committee" take a singular verb.',
|
|
130
|
+
}),
|
|
131
|
+
|
|
132
|
+
// ─── NEWS / DATA / SERIES (singular-only nouns) ───
|
|
133
|
+
createRegexRule({
|
|
134
|
+
id: 'SVA_news_are',
|
|
135
|
+
category: 'grammar',
|
|
136
|
+
pattern: /\b(the\s+)?news\s+are\b/i,
|
|
137
|
+
suggestion: (m) => `${m[1] || ''}news is`,
|
|
138
|
+
reason: '"News" is singular. Use "is", not "are".',
|
|
139
|
+
}),
|
|
140
|
+
createRegexRule({
|
|
141
|
+
id: 'SVA_series_are',
|
|
142
|
+
category: 'grammar',
|
|
143
|
+
pattern: /\bthe\s+series\s+are\b/i,
|
|
144
|
+
suggestion: 'the series is',
|
|
145
|
+
reason: '"Series" is singular (not plural). Use "is".',
|
|
146
|
+
}),
|
|
147
|
+
createRegexRule({
|
|
148
|
+
id: 'SVA_species_are',
|
|
149
|
+
category: 'grammar',
|
|
150
|
+
pattern: /\bthe\s+species\s+are\b/i,
|
|
151
|
+
suggestion: 'the species is',
|
|
152
|
+
reason: '"Species" is singular. Use "is".',
|
|
153
|
+
}),
|
|
154
|
+
|
|
155
|
+
// ─── THERE IS/ARE AGREEMENT ───
|
|
156
|
+
createRegexRule({
|
|
157
|
+
id: 'SVA_there_is_plural',
|
|
158
|
+
category: 'grammar',
|
|
159
|
+
pattern: /\bthere\s+is\s+(many|several|a\s+few|multiple|numerous|various|countless|different)\s+\w+s\b/i,
|
|
160
|
+
suggestion: (m) => m[0].replace(/\bthere\s+is\b/, 'there are'),
|
|
161
|
+
reason: 'Use "there are" before plural nouns.',
|
|
162
|
+
}),
|
|
163
|
+
createRegexRule({
|
|
164
|
+
id: 'SVA_there_are_singular',
|
|
165
|
+
category: 'grammar',
|
|
166
|
+
pattern: /\bthere\s+are\s+(a|an|one|the)\s+\w+\b(?!\s*s\b)/i,
|
|
167
|
+
suggestion: (m) => m[0].replace(/\bthere\s+are\b/, 'there is'),
|
|
168
|
+
reason: 'Use "there is" before singular nouns.',
|
|
169
|
+
}),
|
|
170
|
+
|
|
171
|
+
// ─── 3RD PERSON SINGULAR: MISSING -S ───
|
|
172
|
+
// (Common high-frequency verbs only to avoid false positives)
|
|
173
|
+
createRegexRule({
|
|
174
|
+
id: 'SVA_he_go',
|
|
175
|
+
category: 'grammar',
|
|
176
|
+
pattern: /\b(he|she|it)\s+go\s+to\b/i,
|
|
177
|
+
suggestion: (m) => `${m[1]} goes to`,
|
|
178
|
+
reason: 'With he/she/it, add -s to the verb: "goes".',
|
|
179
|
+
}),
|
|
180
|
+
createRegexRule({
|
|
181
|
+
id: 'SVA_he_come',
|
|
182
|
+
category: 'grammar',
|
|
183
|
+
pattern: /\b(he|she|it)\s+come\s+(to|from|here|there|back|in|out|home|every|each)\b/i,
|
|
184
|
+
suggestion: (m) => `${m[1]} comes ${m[2]}`,
|
|
185
|
+
reason: 'With he/she/it, add -s to the verb: "comes".',
|
|
186
|
+
}),
|
|
187
|
+
createRegexRule({
|
|
188
|
+
id: 'SVA_he_have',
|
|
189
|
+
category: 'grammar',
|
|
190
|
+
pattern: /\b(he|she|it)\s+have\b(?!\s+(been|had|done|come|gone|made|taken|given|seen|known|got))/i,
|
|
191
|
+
suggestion: (m) => `${m[1]} has`,
|
|
192
|
+
reason: 'With he/she/it, use "has" not "have".',
|
|
193
|
+
}),
|
|
194
|
+
createRegexRule({
|
|
195
|
+
id: 'SVA_he_do_verb',
|
|
196
|
+
category: 'grammar',
|
|
197
|
+
pattern: /\b(he|she|it)\s+do\b(?!\s+not\b)/i,
|
|
198
|
+
suggestion: (m) => `${m[1]} does`,
|
|
199
|
+
reason: 'With he/she/it, use "does" not "do".',
|
|
200
|
+
}),
|
|
201
|
+
];
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { createRegexRule, type Rule } from '../types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ════════════════════════════════════════════════════════
|
|
5
|
+
* Tone Rules — TNR Module
|
|
6
|
+
* Rule-based tone issue flags (same Issue format as grammar rules).
|
|
7
|
+
* These appear as "style" type issues inline in the grammar card.
|
|
8
|
+
* ════════════════════════════════════════════════════════
|
|
9
|
+
*/
|
|
10
|
+
export const toneRules: Rule[] = [
|
|
11
|
+
|
|
12
|
+
// ═══════════════════════════════════════════════
|
|
13
|
+
// A. PASSIVE AGGRESSION SIGNALS
|
|
14
|
+
// ═══════════════════════════════════════════════
|
|
15
|
+
createRegexRule({
|
|
16
|
+
id: 'TNR_per_my_last',
|
|
17
|
+
category: 'style',
|
|
18
|
+
pattern: /\bper my (last|previous|earlier|recent|prior|above|below)\s+(email|message|note|memo|request|reply|response|comment)\b/i,
|
|
19
|
+
suggestion: (m) => `As I ${m[0].includes('last') ? 'previously mentioned' : 'noted'} ...`,
|
|
20
|
+
reason: '"Per my last email" can sound passive-aggressive in professional settings. Try "As I previously mentioned" or just restate the point directly.',
|
|
21
|
+
}),
|
|
22
|
+
createRegexRule({
|
|
23
|
+
id: 'TNR_as_i_mentioned',
|
|
24
|
+
category: 'style',
|
|
25
|
+
pattern: /\bAs (I|we) (said|mentioned|noted|stated|explained|indicated|pointed out) (earlier|before|previously|above|in my last|already)\b/i,
|
|
26
|
+
suggestion: 'Restate the point directly without referencing the previous mention',
|
|
27
|
+
reason: 'Referencing previous statements can sound passive-aggressive. Simply restate the information.',
|
|
28
|
+
}),
|
|
29
|
+
createRegexRule({
|
|
30
|
+
id: 'TNR_circle_back',
|
|
31
|
+
category: 'style',
|
|
32
|
+
pattern: /\bcircle back\b/i,
|
|
33
|
+
suggestion: 'follow up',
|
|
34
|
+
reason: '"Circle back" is corporate jargon that can feel passive-aggressive. Use "follow up" instead.',
|
|
35
|
+
}),
|
|
36
|
+
createRegexRule({
|
|
37
|
+
id: 'TNR_moving_forward',
|
|
38
|
+
category: 'style',
|
|
39
|
+
pattern: /\bgoing forward\b/i,
|
|
40
|
+
suggestion: 'in the future / from now on',
|
|
41
|
+
reason: '"Going forward" can sound passive-aggressive after a criticism. Try "in the future" or "from now on".',
|
|
42
|
+
}),
|
|
43
|
+
|
|
44
|
+
// ═══════════════════════════════════════════════
|
|
45
|
+
// B. APOLOGY FILLERS (Confidence Weakeners)
|
|
46
|
+
// ═══════════════════════════════════════════════
|
|
47
|
+
createRegexRule({
|
|
48
|
+
id: 'TNR_just_wanted',
|
|
49
|
+
category: 'style',
|
|
50
|
+
pattern: /\bI just wanted to\b/i,
|
|
51
|
+
suggestion: 'I want to / I am writing to',
|
|
52
|
+
reason: '"I just wanted to" is an unnecessary softener that weakens your message. Be direct.',
|
|
53
|
+
}),
|
|
54
|
+
createRegexRule({
|
|
55
|
+
id: 'TNR_sorry_to_bother',
|
|
56
|
+
category: 'style',
|
|
57
|
+
pattern: /\bsorry (to (bother|bug|trouble|disturb|interrupt|pester|contact) you|for (bothering|bugging|troubling|interrupting|disturbing))\b/i,
|
|
58
|
+
suggestion: 'Remove the apology and state your need directly',
|
|
59
|
+
reason: 'Apologizing for contacting someone preemptively weakens your message. Start with your request directly.',
|
|
60
|
+
}),
|
|
61
|
+
createRegexRule({
|
|
62
|
+
id: 'TNR_does_that_make_sense',
|
|
63
|
+
category: 'style',
|
|
64
|
+
pattern: /\bdoes that make sense\??\b/i,
|
|
65
|
+
suggestion: 'Let me know if you have questions.',
|
|
66
|
+
reason: '"Does that make sense?" can sound uncertain or condescending. Try "Let me know if you have questions."',
|
|
67
|
+
}),
|
|
68
|
+
createRegexRule({
|
|
69
|
+
id: 'TNR_if_thats_okay',
|
|
70
|
+
category: 'style',
|
|
71
|
+
pattern: /\bif that'?s? (okay|ok|alright|fine|good|acceptable|convenient|possible)\b/i,
|
|
72
|
+
suggestion: 'Remove — state your request confidently',
|
|
73
|
+
reason: 'Seeking permission after making a request undermines your authority. Remove this phrase.',
|
|
74
|
+
}),
|
|
75
|
+
createRegexRule({
|
|
76
|
+
id: 'TNR_hopefully',
|
|
77
|
+
category: 'style',
|
|
78
|
+
pattern: /^Hopefully,?\s+/i,
|
|
79
|
+
suggestion: 'State your expectation directly',
|
|
80
|
+
reason: 'Starting with "Hopefully" signals uncertainty. State what you expect or need directly.',
|
|
81
|
+
}),
|
|
82
|
+
createRegexRule({
|
|
83
|
+
id: 'TNR_no_rush',
|
|
84
|
+
category: 'style',
|
|
85
|
+
pattern: /\bno rush(,| but| though| however)\b/i,
|
|
86
|
+
suggestion: 'Remove or specify a deadline: "Please reply by [date]"',
|
|
87
|
+
reason: '"No rush" is vague and undermines urgency. If you have a deadline, state it; if not, remove this phrase.',
|
|
88
|
+
}),
|
|
89
|
+
|
|
90
|
+
// ═══════════════════════════════════════════════
|
|
91
|
+
// C. HEDGING OVERUSE
|
|
92
|
+
// ═══════════════════════════════════════════════
|
|
93
|
+
createRegexRule({
|
|
94
|
+
id: 'TNR_i_think_that',
|
|
95
|
+
category: 'style',
|
|
96
|
+
pattern: /\bI think that\b/i,
|
|
97
|
+
suggestion: 'State your point directly (remove "I think that")',
|
|
98
|
+
reason: '"I think that" weakens your statement. Remove it and state your point with confidence.',
|
|
99
|
+
}),
|
|
100
|
+
createRegexRule({
|
|
101
|
+
id: 'TNR_i_guess',
|
|
102
|
+
category: 'style',
|
|
103
|
+
pattern: /\bI would guess\b/i,
|
|
104
|
+
suggestion: 'I estimate / I expect',
|
|
105
|
+
reason: '"I would guess" sounds uncertain. Use "I estimate" or "I expect" for a more confident tone.',
|
|
106
|
+
}),
|
|
107
|
+
createRegexRule({
|
|
108
|
+
id: 'TNR_i_suppose',
|
|
109
|
+
category: 'style',
|
|
110
|
+
pattern: /\bI suppose\b/i,
|
|
111
|
+
suggestion: 'State your view directly',
|
|
112
|
+
reason: '"I suppose" sounds hesitant. State your position directly.',
|
|
113
|
+
}),
|
|
114
|
+
createRegexRule({
|
|
115
|
+
id: 'TNR_sort_of',
|
|
116
|
+
category: 'style',
|
|
117
|
+
pattern: /\bsort of (like|similar|the same|related|connected|associated)\b/i,
|
|
118
|
+
suggestion: (m) => `similar to / ${m[1]}`,
|
|
119
|
+
reason: '"Sort of" hedges your comparison unnecessarily. Be specific.',
|
|
120
|
+
}),
|
|
121
|
+
|
|
122
|
+
// ═══════════════════════════════════════════════
|
|
123
|
+
// D. AGGRESSIVE / DEMANDING LANGUAGE
|
|
124
|
+
// ═══════════════════════════════════════════════
|
|
125
|
+
createRegexRule({
|
|
126
|
+
id: 'TNR_you_always_fail',
|
|
127
|
+
category: 'style',
|
|
128
|
+
pattern: /\byou (always|never|constantly|consistently|repeatedly) (fail|forget|ignore|miss|avoid|dismiss|neglect)\b/i,
|
|
129
|
+
suggestion: (m) => `This has happened [X times] — let's work on a solution for ${m[2]}ing`,
|
|
130
|
+
reason: '"You always/never [verb]" is accusatory and absolute. Focus on specific incidents and collaborative solutions instead.',
|
|
131
|
+
}),
|
|
132
|
+
createRegexRule({
|
|
133
|
+
id: 'TNR_i_demand',
|
|
134
|
+
category: 'style',
|
|
135
|
+
pattern: /\bI demand\b/i,
|
|
136
|
+
suggestion: 'I need / I require / I expect',
|
|
137
|
+
reason: '"I demand" sounds aggressive and unprofessional. Use "I need" or "I require" instead.',
|
|
138
|
+
}),
|
|
139
|
+
createRegexRule({
|
|
140
|
+
id: 'TNR_unacceptable',
|
|
141
|
+
category: 'style',
|
|
142
|
+
pattern: /\bthis is (completely |absolutely |totally |simply |truly |utterly )?(unacceptable|ridiculous|absurd|outrageous|disgraceful|pathetic)\b/i,
|
|
143
|
+
suggestion: 'This does not meet [the standard]. Here is what I need: ...',
|
|
144
|
+
reason: 'Expressing frustration with absolute negativity rarely achieves results. State specifically what needs to change.',
|
|
145
|
+
}),
|
|
146
|
+
|
|
147
|
+
// ═══════════════════════════════════════════════
|
|
148
|
+
// E. WORDY CORPORATE JARGON (Tone-adjacent)
|
|
149
|
+
// ═══════════════════════════════════════════════
|
|
150
|
+
createRegexRule({
|
|
151
|
+
id: 'TNR_synergy',
|
|
152
|
+
category: 'style',
|
|
153
|
+
pattern: /\bsynerg(y|ies|ize|istic)\b/i,
|
|
154
|
+
suggestion: 'collaboration / combined effort',
|
|
155
|
+
reason: '"Synergy" is overused corporate jargon that often obscures meaning. Use plain language.',
|
|
156
|
+
}),
|
|
157
|
+
createRegexRule({
|
|
158
|
+
id: 'TNR_leverage',
|
|
159
|
+
category: 'style',
|
|
160
|
+
pattern: /\bleverage\b(?!\s+the|\s+a|\s+our)/i,
|
|
161
|
+
suggestion: 'use / utilize / apply',
|
|
162
|
+
reason: '"Leverage" as a verb is corporate jargon. Use "use", "apply", or "take advantage of".',
|
|
163
|
+
}),
|
|
164
|
+
createRegexRule({
|
|
165
|
+
id: 'TNR_touch_base',
|
|
166
|
+
category: 'style',
|
|
167
|
+
pattern: /\btouch (base|bases)\b/i,
|
|
168
|
+
suggestion: 'check in / follow up / meet',
|
|
169
|
+
reason: '"Touch base" is overused corporate jargon. Use plain language like "check in" or "follow up".',
|
|
170
|
+
}),
|
|
171
|
+
createRegexRule({
|
|
172
|
+
id: 'TNR_at_the_end_of_the_day',
|
|
173
|
+
category: 'style',
|
|
174
|
+
pattern: /\bat the end of the day\b/i,
|
|
175
|
+
suggestion: 'ultimately / in the end / finally',
|
|
176
|
+
reason: '"At the end of the day" is an overused cliché. Use "ultimately" or "in the end" for clarity.',
|
|
177
|
+
}),
|
|
178
|
+
createRegexRule({
|
|
179
|
+
id: 'TNR_thinking_outside_the_box',
|
|
180
|
+
category: 'style',
|
|
181
|
+
pattern: /\bthink(ing)? outside (the|of the) box\b/i,
|
|
182
|
+
suggestion: 'creative thinking / innovation / unconventional approach',
|
|
183
|
+
reason: '"Thinking outside the box" is an overused cliché that undermines the creativity you\'re trying to express.',
|
|
184
|
+
}),
|
|
185
|
+
createRegexRule({
|
|
186
|
+
id: 'TNR_low_hanging_fruit',
|
|
187
|
+
category: 'style',
|
|
188
|
+
pattern: /\blow[- ]hanging fruit\b/i,
|
|
189
|
+
suggestion: 'easy wins / quick opportunities',
|
|
190
|
+
reason: '"Low-hanging fruit" is overused corporate jargon. Try "easy wins" or "quick opportunities".',
|
|
191
|
+
}),
|
|
192
|
+
createRegexRule({
|
|
193
|
+
id: 'TNR_bandwidth',
|
|
194
|
+
category: 'style',
|
|
195
|
+
pattern: /\bhave (the |enough |sufficient )?(bandwidth)\b/i,
|
|
196
|
+
suggestion: 'have the capacity / have time / be available',
|
|
197
|
+
reason: '"Bandwidth" in a human context is tech jargon. Use "capacity", "time", or "availability".',
|
|
198
|
+
}),
|
|
199
|
+
createRegexRule({
|
|
200
|
+
id: 'TNR_deep_dive',
|
|
201
|
+
category: 'style',
|
|
202
|
+
pattern: /\bdeep.?dive\b/i,
|
|
203
|
+
suggestion: 'detailed analysis / thorough review / in-depth look',
|
|
204
|
+
reason: '"Deep dive" is overused jargon. Use "detailed analysis" or "thorough review".',
|
|
205
|
+
}),
|
|
206
|
+
];
|