slopless 0.2.3 → 0.2.4
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 +83 -148
- package/dist/cli.js +57 -12
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,177 +1,116 @@
|
|
|
1
1
|
# slopless
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Slopless is a deterministic Markdown checker for AI and human slop in writing.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
npm install -D slopless
|
|
7
|
-
```
|
|
5
|
+
It reports patterns that make prose padded, vague, generic, formulaic, or mechanically careless. It does not call an LLM. Output is always textlint JSON.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
## Install
|
|
10
8
|
|
|
11
9
|
```bash
|
|
12
|
-
|
|
10
|
+
npm install -D slopless
|
|
13
11
|
```
|
|
14
12
|
|
|
15
|
-
Run
|
|
13
|
+
## Run
|
|
16
14
|
|
|
17
15
|
```bash
|
|
18
16
|
npx slopless "docs/**/*.md"
|
|
17
|
+
npx slopless draft.md > slopless.json
|
|
18
|
+
cat draft.md | npx slopless --stdin --stdin-filename draft.md
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npx slopless "docs/**/*.md" > slopless.json
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Npm Script
|
|
28
|
-
|
|
29
|
-
Add this to `package.json`:
|
|
21
|
+
Add an npm script:
|
|
30
22
|
|
|
31
23
|
```json
|
|
32
24
|
{
|
|
33
25
|
"scripts": {
|
|
34
|
-
"lint:prose": "slopless"
|
|
26
|
+
"lint:prose": "slopless \"docs/**/*.md\""
|
|
35
27
|
}
|
|
36
28
|
}
|
|
37
29
|
```
|
|
38
30
|
|
|
39
|
-
Run:
|
|
40
|
-
|
|
41
31
|
```bash
|
|
42
32
|
npm run lint:prose
|
|
43
33
|
```
|
|
44
34
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Slopless is a deterministic prose checker for Markdown.
|
|
48
|
-
|
|
49
|
-
It reports concrete writing patterns that often make generated or careless prose feel padded, vague, generic, or formulaic.
|
|
50
|
-
|
|
51
|
-
It is built for local scripts, CI checks, review pipelines, and tools that need structured prose findings without calling an LLM.
|
|
52
|
-
|
|
53
|
-
## What Slopless Is Not
|
|
54
|
-
|
|
55
|
-
Slopless does not rewrite text.
|
|
56
|
-
|
|
57
|
-
Slopless does not check facts.
|
|
58
|
-
|
|
59
|
-
Slopless does not judge taste.
|
|
35
|
+
Slopless requires a file path, glob, or stdin input. A bare `npx slopless` exits with code `2`.
|
|
60
36
|
|
|
61
|
-
|
|
37
|
+
## Behavior
|
|
62
38
|
|
|
63
|
-
It reports rule findings. A person or another tool decides what to do with them.
|
|
64
|
-
|
|
65
|
-
## Defaults
|
|
66
|
-
|
|
67
|
-
- Checks `**/*.md` when no path is passed.
|
|
68
|
-
- Emits JSON only.
|
|
69
39
|
- Requires Node.js 20 or newer.
|
|
70
40
|
- Requires no `.textlintrc.json`.
|
|
71
41
|
- Requires no separate `textlint` install.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
npx slopless
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
`--format` and `-f` are rejected because Slopless always emits JSON.
|
|
146
|
-
|
|
147
|
-
## What It Checks
|
|
148
|
-
|
|
149
|
-
Slopless checks for:
|
|
150
|
-
|
|
151
|
-
- stock AI-style phrasing
|
|
152
|
-
- empty or generic prose patterns
|
|
153
|
-
- rhetorical filler
|
|
154
|
-
- weak lead-ins and closers
|
|
155
|
-
- hedge stacking
|
|
156
|
-
- prohibited or overused vocabulary
|
|
157
|
-
- cliches and corporate phrasing
|
|
158
|
-
- fake precision signals
|
|
159
|
-
- readability and sentence metrics
|
|
160
|
-
- Markdown style signals
|
|
161
|
-
|
|
162
|
-
## Why It Exists
|
|
163
|
-
|
|
164
|
-
Generated prose often repeats the same rhetorical moves: vague contrast, empty emotional payoff, overconfident summaries, generic transitions, and formulaic conclusions.
|
|
165
|
-
|
|
166
|
-
General grammar tools are not aimed at those patterns. LLM review can catch them, but it is slower, non-deterministic, and harder to use as a stable CI gate.
|
|
167
|
-
|
|
168
|
-
Slopless keeps that layer deterministic. It gives projects a repeatable JSON report of known prose issues.
|
|
169
|
-
|
|
170
|
-
## Advanced Textlint Use
|
|
171
|
-
|
|
172
|
-
The package also exports a textlint preset for users who already run textlint directly.
|
|
173
|
-
|
|
174
|
-
`.textlintrc.json`:
|
|
42
|
+
- Emits textlint JSON only.
|
|
43
|
+
- Rejects `--format` and `-f`.
|
|
44
|
+
- Exits `0` for no findings, `1` for prose findings, and `2` for command failure.
|
|
45
|
+
|
|
46
|
+
Each JSON message includes the rule ID, line, column, message, and range data when textlint provides it. Rule IDs use `slopless/<rule-name>` in wrapped textlint output, such as `slopless/semantic-thinness`.
|
|
47
|
+
|
|
48
|
+
## Rules
|
|
49
|
+
|
|
50
|
+
Metrics:
|
|
51
|
+
|
|
52
|
+
- `avg-sentence-length`: average sentence length above 24 words.
|
|
53
|
+
- `paragraph-length`: paragraphs over 6 sentences.
|
|
54
|
+
- `word-repetition`: one non-trivial word repeated over 5 times.
|
|
55
|
+
- `flesch-kincaid`: Flesch Reading Ease below 61.
|
|
56
|
+
- `gunning-fog` and `coleman-liau`: grade scores above 12.
|
|
57
|
+
|
|
58
|
+
Orthography:
|
|
59
|
+
|
|
60
|
+
- `colon-dramatic`: short reveals after a colon, such as `And then: everything changed.`
|
|
61
|
+
- `em-dashes`: closed em dashes.
|
|
62
|
+
- `exclamation-density`: more than 1 exclamation mark per paragraph.
|
|
63
|
+
- `fake-timestamps`: clock specificity, such as `5:47 PM`.
|
|
64
|
+
- `sentence-case`: title-case headings.
|
|
65
|
+
- `smart-quotes`: curly quotes.
|
|
66
|
+
|
|
67
|
+
Phrases and words:
|
|
68
|
+
|
|
69
|
+
- `cliches`: stock phrases, such as `at the end of the day`.
|
|
70
|
+
- `corporate-speak`: business filler, such as `move the needle`.
|
|
71
|
+
- `hedge-stacking`: stacked hedges, such as `might perhaps`.
|
|
72
|
+
- `humble-bragger`: credential lead-ins, such as `in my experience`.
|
|
73
|
+
- `jargon-faker`: borrowed tech metaphors, such as `debug your morning`.
|
|
74
|
+
- `llm-disclaimer`: assistant disclaimers, such as `as an AI language model`.
|
|
75
|
+
- `llm-vocabulary`: common AI diction, such as `delve`.
|
|
76
|
+
- `prohibited-phrases` and `prohibited-words`: package-owned banned lists.
|
|
77
|
+
- `recommended-terms` and `required-terms`: configured missing terms.
|
|
78
|
+
- `simplicity`: complex words with simple replacements, such as `utilize`.
|
|
79
|
+
- `skunked-terms`: contested broad-use terms.
|
|
80
|
+
- `uncomparables`: impossible modifiers, such as `very unique`.
|
|
81
|
+
|
|
82
|
+
Semantic thinness:
|
|
83
|
+
|
|
84
|
+
- `semantic-thinness`: low-information templates, such as `Something shifted in the room.`
|
|
85
|
+
|
|
86
|
+
Syntactic patterns:
|
|
87
|
+
|
|
88
|
+
- `affirmation-closers`: empty certainty endings, such as `and that is the key`.
|
|
89
|
+
- `authority-padding`: soft authority padding, such as `research shows`.
|
|
90
|
+
- `blame-reframe`: blame-to-insight reframes, such as `the problem is not X, it is Y`.
|
|
91
|
+
- `boilerplate-conclusion`: generic endings, such as `in conclusion`.
|
|
92
|
+
- `boilerplate-framing`: generic setup, such as `when it comes to`.
|
|
93
|
+
- `contrastive-aphorism`: slogan contrasts, such as `not faster, but smarter`.
|
|
94
|
+
- `demonstrative-emphasis`: vague `this is what` emphasis.
|
|
95
|
+
- `empty-emphasis`: unsupported importance claims, such as `this matters`.
|
|
96
|
+
- `false-question`: rhetorical questions, such as `isn't that what we all want?`
|
|
97
|
+
- `fragment-stacking`: clipped cadence, such as `Too broad. Too vague. Too late.`
|
|
98
|
+
- `generic-signposting`: generic transitions, such as `it is important to note`.
|
|
99
|
+
- `lesson-framing`: lesson extraction, such as `the lesson is`.
|
|
100
|
+
- `llm-openers`: generic openers, such as `the important thing is`.
|
|
101
|
+
- `negation-reframe`: `not X. It is Y.` constructions.
|
|
102
|
+
- `observer-guidance`: reader-instruction frames, such as `notice how`.
|
|
103
|
+
- `response-wrapper`: chat wrappers, such as `here is a revised version`.
|
|
104
|
+
- `softening-language`: vague softeners, such as `in many ways`.
|
|
105
|
+
- `summative-closer`: summary payoff lines, such as `that is what makes it work`.
|
|
106
|
+
- `triple-repeat`: repeated sentence openers, such as `It is X. It is Y. It is Z.`
|
|
107
|
+
- `universalizing-claims`: broad claims, such as `everyone knows`.
|
|
108
|
+
|
|
109
|
+
## Direct Textlint Use
|
|
110
|
+
|
|
111
|
+
Most users should run `npx slopless "docs/**/*.md"`.
|
|
112
|
+
|
|
113
|
+
The package also exports a textlint preset:
|
|
175
114
|
|
|
176
115
|
```json
|
|
177
116
|
{
|
|
@@ -181,10 +120,6 @@ The package also exports a textlint preset for users who already run textlint di
|
|
|
181
120
|
}
|
|
182
121
|
```
|
|
183
122
|
|
|
184
|
-
Direct textlint use:
|
|
185
|
-
|
|
186
123
|
```bash
|
|
187
124
|
npx textlint "docs/**/*.md"
|
|
188
125
|
```
|
|
189
|
-
|
|
190
|
-
Most users should use `npx slopless` instead.
|
package/dist/cli.js
CHANGED
|
@@ -2,30 +2,46 @@
|
|
|
2
2
|
import { dirname, resolve } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
import { cli } from "textlint/lib/src/cli.js";
|
|
5
|
-
const DEFAULT_TARGET = "**/*.md";
|
|
6
5
|
const FORMAT_FLAGS = new Set(["--format", "-f"]);
|
|
7
6
|
const HELP_FLAGS = new Set(["--help", "-h"]);
|
|
7
|
+
const STDIN_FLAGS = new Set(["--stdin"]);
|
|
8
8
|
const VERSION_FLAGS = new Set(["--version", "-v"]);
|
|
9
|
-
const
|
|
10
|
-
|
|
9
|
+
const VALUE_OPTIONS = new Set([
|
|
10
|
+
"--cache-location",
|
|
11
|
+
"--config",
|
|
12
|
+
"--ignore-path",
|
|
13
|
+
"--output-file",
|
|
14
|
+
"--plugin",
|
|
15
|
+
"--preset",
|
|
16
|
+
"--rule",
|
|
17
|
+
"--rules-base-directory",
|
|
18
|
+
"--rulesdir",
|
|
19
|
+
"--stdin-filename",
|
|
20
|
+
"-c",
|
|
21
|
+
"-o"
|
|
22
|
+
]);
|
|
23
|
+
const VERSION = "0.2.4";
|
|
24
|
+
const HELP_TEXT = `Slopless checks Markdown prose for deterministic AI and human slop signals.
|
|
25
|
+
|
|
26
|
+
It reports concrete patterns that make writing padded, vague, generic,
|
|
27
|
+
formulaic, or mechanically careless. Output is always textlint JSON.
|
|
11
28
|
|
|
12
29
|
Install:
|
|
13
30
|
npm install -D slopless
|
|
14
31
|
|
|
15
32
|
Run:
|
|
16
|
-
npx slopless
|
|
17
33
|
npx slopless "docs/**/*.md"
|
|
18
34
|
npx slopless draft.md > slopless.json
|
|
19
35
|
|
|
20
36
|
Package script:
|
|
21
37
|
{
|
|
22
38
|
"scripts": {
|
|
23
|
-
"lint:prose": "slopless"
|
|
39
|
+
"lint:prose": "slopless \\"docs/**/*.md\\""
|
|
24
40
|
}
|
|
25
41
|
}
|
|
26
42
|
|
|
27
43
|
Default behavior:
|
|
28
|
-
-
|
|
44
|
+
- A file path, glob, or stdin input is required.
|
|
29
45
|
- Output is always JSON.
|
|
30
46
|
- Exit 0 means no findings.
|
|
31
47
|
- Exit 1 means Slopless found prose issues.
|
|
@@ -35,9 +51,9 @@ Default behavior:
|
|
|
35
51
|
|
|
36
52
|
What it is for:
|
|
37
53
|
Slopless is for deterministic prose checks in CI, local scripts, and review
|
|
38
|
-
pipelines. It catches
|
|
39
|
-
|
|
40
|
-
|
|
54
|
+
pipelines. It catches AI-style phrasing, empty claims, rhetorical filler,
|
|
55
|
+
weak lead-ins and closers, hedge stacking, readability problems, and Markdown
|
|
56
|
+
style signals.
|
|
41
57
|
|
|
42
58
|
What it is not for:
|
|
43
59
|
Slopless does not rewrite text, check facts, judge taste, or replace human
|
|
@@ -61,12 +77,37 @@ function hasFlag(args, flags) {
|
|
|
61
77
|
return args.some((arg) => flags.has(arg));
|
|
62
78
|
}
|
|
63
79
|
function hasFileTarget(args) {
|
|
64
|
-
|
|
80
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
81
|
+
const arg = args[index];
|
|
82
|
+
if (arg === undefined) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (VALUE_OPTIONS.has(arg)) {
|
|
86
|
+
index += 1;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (arg.startsWith("--") && arg.includes("=")) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (arg.startsWith("-")) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
65
98
|
}
|
|
66
99
|
function packageNodeModules() {
|
|
67
100
|
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
68
101
|
return resolve(packageRoot, "..");
|
|
69
102
|
}
|
|
103
|
+
async function readStdin() {
|
|
104
|
+
let text = "";
|
|
105
|
+
const stream = process.stdin.setEncoding("utf8");
|
|
106
|
+
for await (const chunk of stream) {
|
|
107
|
+
text += chunk;
|
|
108
|
+
}
|
|
109
|
+
return text;
|
|
110
|
+
}
|
|
70
111
|
async function main() {
|
|
71
112
|
const userArgs = process.argv.slice(2);
|
|
72
113
|
if (hasFlag(userArgs, HELP_FLAGS)) {
|
|
@@ -81,6 +122,10 @@ async function main() {
|
|
|
81
122
|
process.stderr.write("slopless always writes JSON output. Remove --format / -f.\n");
|
|
82
123
|
return 2;
|
|
83
124
|
}
|
|
125
|
+
if (!hasFileTarget(userArgs) && !hasFlag(userArgs, STDIN_FLAGS)) {
|
|
126
|
+
process.stderr.write("slopless requires a file path, glob, or --stdin input. Run slopless --help.\n");
|
|
127
|
+
return 2;
|
|
128
|
+
}
|
|
84
129
|
const args = [
|
|
85
130
|
"node",
|
|
86
131
|
"slopless",
|
|
@@ -92,8 +137,8 @@ async function main() {
|
|
|
92
137
|
"json",
|
|
93
138
|
...userArgs
|
|
94
139
|
];
|
|
95
|
-
if (
|
|
96
|
-
|
|
140
|
+
if (hasFlag(userArgs, STDIN_FLAGS)) {
|
|
141
|
+
return cli.execute(args, await readStdin());
|
|
97
142
|
}
|
|
98
143
|
return cli.execute(args);
|
|
99
144
|
}
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAE9C,MAAM,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|