@d3lm/lint-preset 1.5.6 → 1.6.1

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 CHANGED
@@ -233,7 +233,7 @@ createOxlintConfig({
233
233
 
234
234
  ## Comment Formatting (`comments`)
235
235
 
236
- The preset ships a `comments` CLI that checks how comments in JavaScript and TypeScript files fit the configured width. Line breaks are left to the tool, except where only the meaning of the prose shows whether a line ends with the start of a sentence. `list`, `check`, and `wrap` never change files. By default, `agent` and the hook send an agent only the comments with hints, plus comments with issues in parts the tool never rewraps (see [Text Kept as Written](#text-kept-as-written)). That default is a cheap triage, not a full review of the language. With `--all` or `agent.scope: 'all'`, the agent reviews the wording of every comment in scope against its rules. The agent fixes the wording and moves the start of a sentence to the next line where a hint applies. Then the tool applies its exact rewrap to every comment in scope that still has a layout issue. The rewrap only changes whitespace in prose, like line breaks, runs of spaces, trailing spaces, and the indentation of continuation lines. It never changes a word, a punctuation character, a code span, or text kept as written, and it keeps the line endings of the file. Comments are found with a real parser, so strings, template literals, and regexes never produce false matches. Only block and JSDoc comments are checked, and line comments (`//`) are always left alone.
236
+ The preset ships a `comments` CLI that checks how comments in JavaScript, TypeScript, and Rust files fit the configured width. Line breaks are left to the tool, except where only the meaning of the prose shows whether a line ends with the start of a sentence. `list`, `check`, and `wrap` never change files. By default, `agent` and the hook send an agent only the comments with hints, plus comments with issues in parts the tool never rewraps (see [Text Kept as Written](#text-kept-as-written)). That default is a cheap triage, not a full review of the language. With `--failing` or `agent.scope: 'failing'`, the agent only gets the comments that fail `check`, and none that only have hints. With `--all` or `agent.scope: 'all'`, the agent reviews the wording of every comment in scope against its rules. The agent fixes the wording and moves the start of a sentence to the next line where a hint applies. Then the tool applies its exact rewrap to every comment in scope that still has a layout issue. The rewrap only changes whitespace in prose, like line breaks, runs of spaces, trailing spaces, and the indentation of continuation lines. It never changes a word, a punctuation character, a code span, or text kept as written, and it keeps the line endings of the file. Comments are found with a real parser, so strings, template literals, and regexes never produce false matches. Block and JSDoc comments get every check. Line comments (`//`) are never rewrapped, and they are only reported when a line is longer than `maxWidth` (see [Text Kept as Written](#text-kept-as-written)). Rust files get the same checks for their doc comments too (see [Rust](#rust)).
237
237
 
238
238
  ```bash
239
239
  comments list # comments in uncommitted changes, with line lengths and issues
@@ -242,6 +242,7 @@ comments check --base main # print layout violations and exit with code
242
242
  comments list src/a.ts:42 --json # the comment on line 42, with its rewrap suggestion
243
243
  comments wrap src/a.ts:42 # print the exact rewrap of that comment to stdout
244
244
  comments agent # hand suspicious comments to an agent, then verify the result
245
+ comments agent --failing # hand only the comments that fail check to an agent
245
246
  comments check --cwd ../other-app # run as if started in another project
246
247
  ```
247
248
 
@@ -256,7 +257,7 @@ Verdicts are layout issues that can be measured without reading the prose. They
256
257
  - `overflow` means a measured prose line exceeds `maxWidth`
257
258
  - `underfill` means a line ends early, so the paragraph needs more lines than it should
258
259
  - `widow` means fewer than three words sit on the last line of a paragraph
259
- - `unbalanced` means the lines are less even than in the suggested rewrap
260
+ - `unbalanced` means the lines are less even than in the suggested rewrap, or a line ends inside a link, code span, or `{...}` group (see [Text That Stays on One Line](#text-that-stays-on-one-line))
260
261
 
261
262
  Hints come from heuristics and can be false positives, because only the meaning of the prose shows whether the rule applies. A hint only sends a comment to the agent, which decides whether to change it. `check` only prints comments with verdicts, so a passing check stays quiet apart from its summary, even when hints remain after review. Use `list --suspicious` to inspect hints, which are marked with `(hint)` and never fail a check:
262
263
 
@@ -275,21 +276,43 @@ In the same way, a paragraph that splits a parenthetical is not reported as `unb
275
276
 
276
277
  With a `tolerance`, a paragraph has no `underfill`, `widow`, or `unbalanced` verdict when it already has the layout that the tool produces for a wider `width`, up to `width` plus `tolerance`. Its suggestion then keeps the lines as they are. With `width: 100` and `tolerance: 5`, a paragraph that is laid out the way the tool lays it out for a width of 105 passes. A paragraph that only has hints keeps them, and a line past `maxWidth` is still an `overflow`.
277
278
 
279
+ The `tolerance` also holds for each line on its own, in both directions. A paragraph is not `unbalanced` when it has as many lines as the suggested rewrap and no line is more than `tolerance` columns shorter or longer than the same line of the rewrap. Its suggestion then keeps the lines as they are too. With `tolerance: 5`, a short word like `as` can start a line where the rewrap ends the line before with it. A line that is longer than in the rewrap must still end within `width` plus `tolerance`. This only applies to a paragraph whose only layout issue is `unbalanced`. A `widow` is still reported, and so is a paragraph that has an `orphan` hint too, so the rewrap still moves that word. A line that ends inside a link, code span, `{...}` group, or the head of a JSDoc tag is still `unbalanced` as well.
280
+
278
281
  Hints are only checked in prose, never in code spans, code blocks, `@example`, or URLs. Rules that can't be measured, like writing complete sentences, are part of the agent's prompt (see `DEFAULT_RULES` in `src/comments/agent.ts`). The prompt treats the style rules as preferences, so the agent keeps punctuation that carries meaning or reads clearly, and never changes code, code spans, literals, patterns, or quotations.
279
282
 
283
+ ### Text That Stays on One Line
284
+
285
+ The rewrap never breaks a line inside a code span, a `{...}` group like a JSDoc type or `{@link ...}`, or a Markdown link like `[text](target)`, `[text][label]`, or `[text]`. Links split across lines can't be followed in an editor, so a line that ends inside one of these is `unbalanced`, and the rewrap joins it. If one is too long to fit within `maxWidth`, it stays intact and is reported as `overflow`.
286
+
280
287
  ### Text Kept as Written
281
288
 
282
- The tool rewraps prose paragraphs, list items, and JSDoc tag descriptions. Everything else is kept exactly as written and has no suggestion, so the agent or you have to fix it by hand:
289
+ The tool only rewraps prose paragraphs, list items, and JSDoc tag descriptions. Everything else keeps its line breaks and has no suggestion:
290
+
291
+ - **Code** gets no checks except `banner`. This covers code blocks, `@example`, `@default`, tool directives like `eslint-disable-next-line`, legal comments, and paragraphs that parse as code.
292
+ - **Layout syntax** gets hints but no verdicts. This covers Markdown tables, box-drawing characters, divider lines, and aligned columns.
293
+ - **Text that only looks like code or hand layout** keeps its line breaks, but it still gets `overflow`.
294
+ - **Line comments** (`//`) only get `overflow`. To fix one, the agent shortens it or turns it into a block comment, which the tool then rewraps.
295
+
296
+ To keep a drawing that's wider than the width, put it in a code fence or add `comments-ignore` to the comment.
297
+
298
+ ### Rust
299
+
300
+ In `.rs` files, the tool checks doc comments (`///`, `//!`, `/** */`, `/*! */`) and plain block comments the same way it checks JSDoc. Plain `//` comments only get `overflow`. Comments are found with rustc's own lexer, which ships as a native addon built with [NAPI-RS](https://napi.rs). Doctests, intra-doc links, and anything else that would change what rustdoc renders are left intact.
283
301
 
284
- - Code gets no checks besides `banner`. This covers code blocks, `@example`, `@default`, and `@defaultValue`, tool directives like `eslint-disable-next-line` or `@ts-expect-error`, legal comments (`/*!`, `@license`, `@preserve`, and copyright notices), and paragraphs that parse as JavaScript.
285
- - Layout syntax gets hints but no verdicts, in the whole paragraph around it. This covers Markdown tables (a line that starts with `|`, or a delimiter row like `--- | ---`), box-drawing characters (U+2500 to U+257F), a line that starts with four or more of the same character among `-=*#_~+/\` or ends with four or more among `-=*#_~` (except Markdown headings and column underlines like `---- ----`), and aligned columns (a gap of two or more spaces after which text continues at the same column on at least two lines).
286
- - Text that only looks like code or hand layout keeps its line breaks but still gets `overflow`, since prose can look like that too. Lines that look like code, such as ones that end with `{` or `;` or start with `import`, get no hints. Hand layout, such as Markdown hard line breaks, headings, quotes, arrows, and `term - description` lists, still gets hints.
302
+ The width defaults to `comment_width` from `rustfmt.toml`, or 80 if it isn't set. Setting `width` in the `comments` config overrides it.
287
303
 
288
- To keep a drawing that is wider than the width, put it in a code fence or add `comments-ignore` to the comment.
304
+ The addon ships for macOS (arm64, x64) and Linux with glibc (x64, arm64). On other platforms, Rust files fail with a message that explains how to build the addon (`pnpm run build:native`, which needs a Rust toolchain). To skip Rust files, leave `.rs` out of `extensions`.
305
+
306
+ `native/verify/verify.mjs` checks that rewrapping Rust comments never changes code or rustdoc output. It runs on a fixture crate and, optionally, on a `--corpus` of real crates:
307
+
308
+ ```bash
309
+ pnpm run build
310
+ node native/verify/verify.mjs --corpus ~/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f
311
+ ```
289
312
 
290
313
  ### Configuration
291
314
 
292
- `width` is the preferred line length, and `maxWidth` is the hard maximum, including indentation and the comment prefix. The CLI defaults `maxWidth` to 120, or to `width` if that is larger. The wrapper may go past `width`, up to `maxWidth`, to keep a parenthetical on one line. `tolerance` (default 0) lets lines in paragraphs of three or more lines go that many columns past `width` when that saves a line. `check` also accepts a paragraph that already has the layout for a wider `width`, up to `width` plus `tolerance`, while the tool itself still wraps to `width`. A comment that is one paragraph stays on one line up to `singleLineWidth` plus `tolerance`, capped by `maxWidth`. A word or code span longer than `maxWidth` is never split and is reported as `overflow`.
315
+ `width` is the preferred line length, and `maxWidth` is the hard maximum, including indentation and the comment prefix. The CLI defaults `maxWidth` to 120, or to `width` if that is larger. The wrapper may go past `width`, up to `maxWidth`, to keep a parenthetical on one line. `tolerance` (default 0) lets lines in paragraphs of three or more lines go that many columns past `width` when that saves a line. `check` also accepts a paragraph that already has the layout for a wider `width`, up to `width` plus `tolerance`, and a paragraph whose lines are each within `tolerance` columns of the suggested rewrap (see [Issues](#issues)), while the tool itself still wraps to `width`. A comment that is one paragraph stays on one line up to `singleLineWidth` plus `tolerance`, capped by `maxWidth`. A word, code span, or link longer than `maxWidth` is never split and is reported as `overflow`.
293
316
 
294
317
  Like prettier, `comments` looks for a config file in the current directory and its parents, up to the repository root. The config can be a `comments.config.{ts,mts,js,mjs,cjs}`, `.commentsrc`, or `.commentsrc.json` file, or a `comments` key in `package.json`. All options are optional.
295
318
 
@@ -298,7 +321,7 @@ Like prettier, `comments` looks for a config file in the current directory and i
298
321
  import { defineConfig } from '@d3lm/lint-preset/comments';
299
322
 
300
323
  export default defineConfig({
301
- // defaults to prettier's printWidth, or 80
324
+ // defaults to prettier's printWidth, or 80, and to rustfmt's comment_width in Rust files
302
325
  width: 100,
303
326
  maxWidth: 120,
304
327
  tolerance: 0,
@@ -306,6 +329,8 @@ export default defineConfig({
306
329
  avoidSentenceOrphans: true,
307
330
  // report the style hints, like `em-dash` and `semicolon`
308
331
  style: true,
332
+ // only these files, unless `ignore` skips them
333
+ include: ['src/**'],
309
334
  ignore: ['src/generated/**'],
310
335
  agent: {
311
336
  runner: 'claude', // or 'codex', 'cursor'
@@ -314,7 +339,7 @@ export default defineConfig({
314
339
  batchSize: 20, // most comments per agent
315
340
  maxFiles: 10, // most files per agent
316
341
  maxAgents: 6, // most agents running at once
317
- scope: 'suspicious', // a triage, or 'all' to review the wording of every changed comment
342
+ scope: 'suspicious', // a triage, 'failing' for only comments that fail check, or 'all' for every changed comment
318
343
  instructions: 'Rewording is allowed when a sentence reads awkwardly.',
319
344
  },
320
345
  hook: {
@@ -325,6 +350,8 @@ export default defineConfig({
325
350
 
326
351
  Most options also have a command line flag that overrides the config file for a single run. See `comments --help` for the full list.
327
352
 
353
+ `include` and `ignore` take globs relative to the repository root, and apply to every scope, including files and directories passed as targets. A file is checked when it has one of the `extensions`, matches an `include` glob (or `include` is empty), and matches no `ignore` glob. `--include` replaces `include` from the config file, and `--ignore` adds to `ignore`, so `comments check --repo --include '**/*.rs'` checks only Rust files, and `--ignore '**/*.rs'` skips them.
354
+
328
355
  Comments are split across several agents, and all comments of a file go to the same agent. In a terminal, `comments agent` shows the agents while they run, then lists the comments that still have issues. `--no-interactive` skips that list, and `--verbose` prints every agent's reply.
329
356
 
330
357
  `agent.rules` points to a Markdown file that replaces the built-in formatting rules. `agent.command` runs any other agent CLI, like `['my-agent', '--prompt', '{prompt}']`. Without a `{prompt}` placeholder, the prompt goes to stdin.