eslint-plugin-llm-core-mcp 0.25.2 โ 0.26.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedded-docs.d.ts","sourceRoot":"","sources":["../src/embedded-docs.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"embedded-docs.d.ts","sourceRoot":"","sources":["../src/embedded-docs.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkC/C,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,EAAgvB,CAAC"}
|
package/dist/embedded-docs.js
CHANGED
|
@@ -14,6 +14,7 @@ export const embeddedDocs = {
|
|
|
14
14
|
"naming-conventions": "# llm-core/naming-conventions\n\n๐ Enforce naming conventions: Base prefix for abstract classes, Error suffix for error classes.\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, โ
`recommended`, ๐จ `style`.\n\n<!-- end auto-generated rule header -->\n\nEnforce naming conventions: Base prefix for abstract classes, Error suffix for error classes.\n\n## Rule Details\n\nLLMs frequently create abstract classes without a `Base` prefix and error classes without an `Error` suffix. These naming conventions make class purpose immediately clear from the name alone.\n\n### Checks\n\n1. **Abstract classes** must start with `Base` (e.g., `BaseService`, `BaseRepository`)\n2. **Error classes** (extending `Error` or any `*Error` class) must end with `Error` (e.g., `NotFoundError`, `ValidationError`)\n\n## Examples\n\n### Incorrect\n\n```ts\n// Missing Base prefix\nabstract class Service {\n abstract run(): void;\n}\n\n// Missing Error suffix\nclass NotFound extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nclass BadRequest extends HttpError {}\n```\n\n### Correct\n\n```ts\n// Base prefix signals abstract class\nabstract class BaseService {\n abstract run(): void;\n}\n\n// Error suffix signals error class\nclass NotFoundError extends Error {\n constructor(message: string) {\n super(message);\n }\n}\n\nclass BadRequestError extends HttpError {}\n```\n\n## Error Messages\n\nError messages follow a structured teaching format designed for LLM self-correction:\n\n1. **What's wrong** โ identifies the class name and missing prefix/suffix\n2. **Why** โ explains what the naming convention signals to readers\n3. **How to fix** โ shows the exact rename with the class's actual name\n",
|
|
15
15
|
"no-any-in-generic": "# llm-core/no-any-in-generic\n\n๐ Disallow `any` as a generic type argument in type references, arrays, and other parameterized types.\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, โ
`recommended`, โจ๏ธ `typescript`.\n\n<!-- end auto-generated rule header -->\n\nDisallow `any` as a generic type argument in type references like `Array<any>`, `Record<string, any>`, `Map<string, any>`, and other parameterized types.\n\n## Rule Details\n\nLLMs frequently use `any` inside generic types as a \"good enough\" placeholder. Unlike bare `any` annotations, this pattern is subtler โ the code looks typed because there's a generic wrapper, but `any` silently leaks through every access, assignment, and function call that touches the contained values.\n\n## Examples\n\n### Incorrect\n\n```ts\n// any leaks into every array access\nconst items: Array<any> = [];\n\n// any leaks into every property access\nconst cache: Record<string, any> = {};\n\n// any leaks into every map.get() call\nconst lookup: Map<string, any> = new Map();\n\n// any leaks into the resolved value\nconst promise: Promise<any> = fetch(\"/api\");\n\n// any in generic function calls\nconst store = createStore<any>();\n```\n\n### Correct\n\n```ts\n// Specific types\nconst items: Array<User> = [];\nconst cache: Record<string, CacheEntry> = {};\nconst lookup: Map<string, Handler> = new Map();\nconst promise: Promise<Response> = fetch(\"/api\");\n\n// unknown when the type is genuinely dynamic\nconst items: Array<unknown> = [];\nconst cache: Record<string, unknown> = {};\n\n// Narrow unknown values with type guards\nfor (const item of items) {\n if (isUser(item)) {\n process(item); // TypeScript knows it's a User\n }\n}\n```\n\n## What This Rule Catches\n\nThe rule flags `any` used as a type argument in:\n\n1. **Type references** โ `Array<any>`, `Record<string, any>`, `Map<any, any>`, `Set<any>`, `Promise<any>`, custom generics\n2. **Generic function calls** โ `createStore<any>()`, `useState<any>()`\n3. **Multiple `any` arguments** โ `Map<any, any>` reports two errors\n\n### What This Rule Does NOT Catch\n\n- `any` in type annotations (`const x: any`) โ use `@typescript-eslint/no-explicit-any` for this\n- `any` in type assertions (`value as any`) โ use `llm-core/no-type-assertion-any` for this\n- Generic type parameter definitions (`interface Foo<T = any>`) โ these define defaults, not usage\n\n## Error Messages\n\nThe error message teaches the proper alternative:\n\n1. **What's wrong** โ `any` inside a generic disables type checking for contained values\n2. **Why** โ the `any` leaks into every access and assignment through the container\n3. **How to fix** โ use a specific type, or `unknown` with type guards for dynamic data\n",
|
|
16
16
|
"no-async-array-callbacks": "# llm-core/no-async-array-callbacks\n\n๐ Disallow async callbacks passed to array methods where Promises are silently discarded or misused.\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, ๐ `best-practices`, โ
`recommended`.\n\n<!-- end auto-generated rule header -->\n\nDisallow passing async functions to array methods where the returned Promises are silently discarded or semantically wrong.\n\n## Rule Details\n\nLLMs frequently write `items.forEach(async (item) => { await ... })` or `items.filter(async (item) => { return await check(item) })` assuming the method understands async callbacks. It doesn't โ these methods are synchronous and either ignore the return value (forEach) or receive a Promise object where a boolean was expected (filter, some, every).\n\n### Methods that always flag async callbacks\n\n| Method | Why async is wrong |\n| --------- | --------------------------------------------------------------- |\n| `forEach` | Return value is always ignored; Promises are silently discarded |\n| `filter` | Receives a truthy Promise object, not the resolved boolean |\n| `some` | Receives a truthy Promise, always returns `true` |\n| `every` | Receives a truthy Promise, always returns `true` |\n| `reduce` | Accumulator becomes a Promise, chaining breaks silently |\n| `flatMap` | Returns an array of Promises instead of flattened values |\n\n### `map` โ conditional flagging\n\n`items.map(async ...)` returns an array of Promises. This rule only allows that pattern when the result is **immediately awaited or returned** through `Promise.all(...)` or `Promise.allSettled(...)`. The rule flags async map callbacks in all other contexts.\n\n## Examples\n\n### Incorrect\n\n```ts\n// forEach: Promises are silently discarded\nitems.forEach(async (item) => {\n await processItem(item);\n});\n\n// filter: resolves to [Promise, Promise, ...] not booleans\nconst active = items.filter(async (item) => {\n return await isActive(item);\n});\n\n// map without Promise.all: returns array of unresolved Promises\nconst results = items.map(async (item) => {\n return await fetchData(item);\n});\n\n// Promise.all without await/return still drops the outer promise\nPromise.all(\n items.map(async (item) => {\n return await fetchData(item);\n }),\n);\n```\n\n### Correct\n\n```ts\n// Sequential with for...of\nfor (const item of items) {\n await processItem(item);\n}\n\n// Parallel with Promise.all โ the documented safe pattern for map\nawait Promise.all(\n items.map(async (item) => {\n return await processItem(item);\n }),\n);\n\n// Synchronous callbacks are always fine\nitems.forEach((item) => process(item));\nitems.filter((item) => item.active);\n```\n\n## What This Rule Does NOT Catch\n\n- Named function references (e.g., `forEach(processItem)`) โ cannot determine if the referenced function is async without type information\n- Async callbacks on named function references stored elsewhere\n\n## Syntax-Only Limitation\n\nThis rule is intentionally syntax-only. It looks for familiar method names like `.forEach()`, `.filter()`, or `.map()` and does **not** use type information to prove that the receiver is a real JavaScript array.\n\nThat means custom collection APIs that intentionally expose array-like method names may also be flagged. If your codebase relies on async-aware custom collections, scope or disable this rule for those files.\n\n## Error Messages\n\nTwo distinct messages are used:\n\n1. **`noAsyncArrayCallback`** โ for forEach, filter, some, every, reduce, flatMap: teaches that Promises are discarded or misused and offers concrete alternatives\n2. **`noAsyncMapCallback`** โ for map without immediate await/return through `Promise.all(...)`: teaches the `await Promise.all(items.map(...))` pattern\n",
|
|
17
|
+
"no-async-promise-executor": "# llm-core/no-async-promise-executor\n\n๐ Disallow async Promise executor functions because thrown errors are not captured by the outer Promise.\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, ๐ `best-practices`, โ
`recommended`.\n\n<!-- end auto-generated rule header -->\n\nDisallow `async` functions as `new Promise(...)` executors. LLMs often wrap an already-async operation in a Promise constructor and mark the executor `async`, but the Promise constructor does not await that executor.\n\n## Rule Details\n\nThe Promise constructor expects a synchronous executor. If an async executor throws after an `await`, that error belongs to the executor's implicit Promise, not the outer Promise being constructed. That can leave the outer Promise unresolved while the async failure escapes through an unhandled rejection.\n\n## Examples\n\n### Incorrect\n\n```ts\nconst result = new Promise(async (resolve) => {\n resolve(await loadValue());\n});\n\nconst loaded = new Promise(async function (resolve, reject) {\n try {\n resolve(await loadValue());\n } catch (error) {\n reject(error);\n }\n});\n```\n\n### Correct\n\n```ts\nconst result = loadValue();\n\nconst loaded = new Promise((resolve, reject) => {\n loadValue().then(resolve, reject);\n});\n\nconst fromCallback = new Promise((resolve, reject) => {\n readFile(path, (error, contents) => {\n if (error) {\n reject(error);\n return;\n }\n\n resolve(contents);\n });\n});\n```\n\n## What This Rule Catches\n\n| Pattern | Triggers? |\n| ------------------------------------------ | --------- |\n| `new Promise(async (resolve) => { ... })` | Yes |\n| `new Promise(async function () { ... })` | Yes |\n| `new Promise((resolve) => { ... })` | No |\n| `queueTask(async () => { await save(); })` | No |\n\n## Error Messages\n\nThe error message teaches:\n\n1. **What's wrong** -- an async function is being used as a Promise executor\n2. **Why** -- the Promise constructor does not await async executors\n3. **How to fix** -- return the async operation directly, or keep manual Promise executors synchronous\n",
|
|
17
18
|
"no-commented-out-code": "# llm-core/no-commented-out-code\n\n๐ Disallow commented-out code to keep the codebase clean and reduce noise.\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, ๐งน `hygiene`, โ
`recommended`.\n\n<!-- end auto-generated rule header -->\n\nDisallow commented-out code to keep the codebase clean and reduce noise.\n\n## Rule Details\n\nLLMs frequently leave commented-out code in their output โ old implementations, \"alternative approaches\", half-removed logic, and abandoned experiments. This is one of the most recognizable LLM code smells. Commented-out code adds noise, creates confusion about intent, and makes files harder to read.\n\nThis rule detects comments that contain code-like patterns (variable declarations, function calls, control flow, imports/exports) and flags them for removal.\n\n## Examples\n\n### Incorrect\n\n```ts\n// const oldConfig = loadLegacyConfig();\n// if (oldConfig.enabled) {\n// processLegacy(oldConfig);\n// }\nfunction loadConfig() {\n return getNewConfig();\n}\n```\n\n```ts\n/* const previousImplementation = async () => {\n const data = await fetchData();\n return transform(data);\n}; */\nasync function fetchAndTransform() {\n return newApproach();\n}\n```\n\n```ts\n// import { oldHelper } from './utils';\n\n// processData(items);\n\nfunction main() {\n newProcess(items);\n}\n```\n\n### Correct\n\n```ts\n// This function handles the new config loading approach\nfunction loadConfig() {\n return getNewConfig();\n}\n```\n\n```ts\n// TODO: add caching support in next sprint\nasync function fetchAndTransform() {\n return newApproach();\n}\n```\n\n```ts\n/**\n * @param items - The items to process\n * @returns The processed result\n */\nfunction main(items: Item[]) {\n return newProcess(items);\n}\n```\n\n## What This Rule Allows\n\nThe following comment patterns are **not** flagged:\n\n- **Prose comments** โ explanations, notes, descriptions\n- **TODO/FIXME/HACK/NOTE** โ task markers\n- **JSDoc comments** โ documentation blocks starting with `/**`\n- **ESLint directives** โ `eslint-disable`, `eslint-enable`\n- **TypeScript directives** โ `@ts-expect-error`, `@ts-ignore`\n- **URLs** โ links to documentation or references\n- **Short comments** โ comments under 3 characters\n\n## Detection Heuristic\n\nThe rule uses pattern matching to identify code in comments. It looks for:\n\n- Variable declarations (`const`, `let`, `var`)\n- Function and class declarations\n- Import/export statements\n- Control flow (`if`, `for`, `while`, `switch`, `try/catch`)\n- Function/method calls ending with semicolons\n- Assignments ending with semicolons\n- `await` expressions\n- `return`/`throw` statements\n\nConsecutive line comments (`//`) on adjacent lines are grouped and analyzed together, catching multi-line commented-out code blocks.\n\n## Error Messages\n\nError messages follow a structured teaching format designed for LLM self-correction:\n\n1. **What's wrong** โ identifies the commented-out code\n2. **Why** โ explains that git preserves history, making commented-out code unnecessary\n3. **How to fix** โ instructs to delete the code or link to the relevant commit\n",
|
|
18
19
|
"no-empty-catch": "# llm-core/no-empty-catch\n\n๐ Disallow catch blocks with no meaningful error handling (empty or comment-only blocks).\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, ๐ `best-practices`, โ
`recommended`.\n\n<!-- end auto-generated rule header -->\n\nDisallow `catch` blocks that are empty, comment-only, or contain only empty statements such as `;`.\n\n## Rule Details\n\nLLMs frequently generate empty catch blocks or catch blocks with only a comment like `// ignore`. This silently swallows errors, making bugs invisible and systems degrade without warning. Even when error suppression is intentional, an empty block gives future readers no signal that the omission was deliberate.\n\nA catch block is considered **meaningful** when it contains at least one executable statement: a log call, a `throw`, a `return`, a variable assignment, or any other expression statement.\n\nA catch block containing **only comments** (including `// intentional`) is flagged โ a comment is documentation, not handling. A block containing only semicolons is also flagged, because `;` performs no handling.\n\n## Examples\n\n### Incorrect\n\n```ts\n// Empty โ errors are completely hidden\ntry {\n await fetchData();\n} catch (e) {}\n\n// Comment-only โ no actual handling\ntry {\n await saveRecord();\n} catch (e) {\n // TODO: handle this\n}\n\n// Semicolon-only โ still no handling\ntry {\n await saveRecord();\n} catch {}\n```\n\n### Correct\n\n```ts\n// Log and continue\ntry {\n await sendNotification(user);\n} catch (e) {\n logger.error(\"notification failed\", e);\n}\n\n// Rethrow with context\ntry {\n await writeFile(path, data);\n} catch (e) {\n throw new Error(`failed to write ${path}`, { cause: e });\n}\n\n// Return a safe default\nfunction safeParse(json: string): unknown {\n try {\n return JSON.parse(json);\n } catch {\n return null;\n }\n}\n\n// Rethrow is meaningful โ the catch was used for cleanup\ntry {\n await tx.begin();\n await doWork();\n} catch (e) {\n await tx.rollback();\n throw e;\n}\n```\n\n## What Counts as Meaningful\n\n| Statement in catch body | Meaningful? |\n| ----------------------------------- | ----------- |\n| `throw e` / `throw new Error(...)` | โ
Yes |\n| `return` / `return null` | โ
Yes |\n| `logger.error(e)` or any expression | โ
Yes |\n| `const msg = e.message` | โ
Yes |\n| `// comment` only | โ No |\n| `;` only | โ No |\n| empty `{}` | โ No |\n\n## Error Messages\n\nThe error message teaches:\n\n1. **What's wrong** โ catch block silently swallows errors\n2. **Why** โ failures become invisible, debugging is impossible\n3. **How to fix** โ log, rethrow, return default, or document with a real statement\n",
|
|
19
20
|
"no-exported-function-expressions": "# llm-core/no-exported-function-expressions\n\n๐ Enforce that exported functions use function declarations instead of function expressions or arrow functions.\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, โ
`recommended`, ๐จ `style`.\n\n๐ก This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).\n\n<!-- end auto-generated rule header -->\n\nEnforce that exported functions use function declarations instead of function expressions or arrow functions.\n\n## Rationale\n\nLLMs consistently default to `export const fn = () => {}` when generating code. Function declarations are preferred because:\n\n- **Hoisting**: Function declarations are hoisted, making code order more flexible\n- **Stack traces**: Named function declarations produce clearer stack traces for debugging\n- **Intent**: Declarations signal \"this is a named function\" more clearly than variable assignments\n- **Consistency**: Enforces a single style across the codebase\n\nThis rule provides structured error messages that teach the LLM the correct pattern. Through iteration, the LLM learns to use function declarations automatically.\n\n## Rule Details\n\nThis rule reports when:\n\n1. A named export uses an arrow function or function expression (`export const fn = () => {}`)\n2. A default export uses an anonymous arrow function (`export default () => {}`)\n3. A default export uses an anonymous function expression (`export default function() {}`)\n\n### What This Rule Catches\n\n| Pattern | Caught? |\n| ---------------------------------------- | ---------- |\n| `export const fn = () => {}` | Yes |\n| `export const fn = async () => {}` | Yes |\n| `export const fn = function() {}` | Yes |\n| `export const fn = async function() {}` | Yes |\n| `export default () => {}` | Yes |\n| `export default function() {}` | Yes |\n| `export function fn() {}` | No (valid) |\n| `export default function fn() {}` | No (valid) |\n| `const fn = () => {}` (non-exported) | No (valid) |\n| `export const value = 42` (non-function) | No (valid) |\n\n## Examples\n\n### Incorrect\n\n```ts\n// Arrow function exports\nexport const fetchData = async () => {\n return await api.get('/data');\n};\n\n// Function expression exports\nexport const processItem = function(item) {\n return item.value * 2;\n};\n\n// Anonymous default exports\nexport default () => <div>Hello</div>;\n\n// Expression body arrows\nexport const double = (x: number) => x * 2;\n```\n\n### Correct\n\n```ts\n// Named function declarations\nexport async function fetchData() {\n return await api.get('/data');\n}\n\nexport function processItem(item) {\n return item.value * 2;\n}\n\n// Named default export\nexport default function HelloComponent() {\n return <div>Hello</div>;\n}\n\nexport function double(x: number) {\n return x * 2;\n}\n\n// Non-exported arrow functions are fine (internal helpers)\nconst helper = () => 'internal';\n```\n\n## Suggestions\n\nThis rule provides manual fix suggestions (not auto-fix) to convert function expressions to declarations. Auto-fix is intentionally avoided because converting arrow functions to declarations can change `this` binding semantics in some contexts.\n\n## No Escape Hatches\n\nFollowing the [deterministic linting approach](https://understandingdata.com/posts/custom-eslint-rules-determinism/), this rule is designed to be used alongside `eslint-comments/no-use` or similar rules that prevent `eslint-disable` comments. This ensures LLM agents cannot bypass the rule and must learn the correct pattern.\n\n## Error Message Format\n\nError messages follow a structured teaching format:\n\n1. **What's wrong**: Clear statement of the violation\n2. **Why**: Explanation of why the pattern is preferred\n3. **How to fix**: Concrete before/after code example\n\nThis format is designed to be parseable by LLMs, enabling self-correction through the lint-fix loop.\n",
|
|
@@ -33,5 +34,5 @@ export const embeddedDocs = {
|
|
|
33
34
|
"throw-error-objects": "# llm-core/throw-error-objects\n\n๐ Disallow throwing non-Error values such as strings, template literals, plain objects, or arrays.\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, ๐ `best-practices`, โ
`recommended`.\n\n<!-- end auto-generated rule header -->\n\nDisallow throwing string literals, template literals, plain objects, arrays, or other non-Error values.\n\n## Rule Details\n\nLLMs often generate `throw \"something went wrong\"` or `throw { code: 404 }` as a shorthand. These patterns lose the stack trace, break `e instanceof Error` checks, and cause silent failures in logging and error-reporting tools that expect an `Error` object.\n\nThis is a syntax-only rule and does not require type information. It allows `throw` of identifiers, member expressions, call expressions, and `new` expressions because it cannot statically prove their type โ those forms are assumed to be Error instances or safe wrappers.\n\n## Examples\n\n### Incorrect\n\n```ts\n// String literal โ no stack trace\nthrow \"something went wrong\";\n\n// Template literal โ still no stack trace\nthrow `failed to connect to ${host}`;\n\n// Plain object โ instanceof Error fails, .stack is undefined\nthrow { code: 404, message: \"not found\" };\n\n// Array โ completely wrong type\nthrow [\"validation\", \"failed\"];\n\n// Number\nthrow 500;\n```\n\n### Correct\n\n```ts\n// Error instance โ stack trace, instanceof, .message all work\nthrow new Error(\"something went wrong\");\n\n// Error subclass\nthrow new ValidationError(\"invalid input\");\n\n// Identifier โ may hold an Error, allowed\nthrow err;\n\n// Call expression โ assumed to create a proper Error\nthrow createError(\"context\", { cause: err });\n\n// Enrich an existing error with context\nthrow Object.assign(new Error(\"not found\"), { code: 404 });\n```\n\n## What This Rule Does NOT Flag\n\n- `throw identifier` โ the identifier may hold an Error; type-checking would be needed to verify\n- `throw expr.property` โ same reason\n- `throw callExpression()` โ assumed to return an Error\n- `throw new SomeThing()` โ assumed to construct an Error\n\n## Error Messages\n\nThe error message teaches:\n\n1. **What's wrong** โ the thrown value is not an Error instance\n2. **Why** โ stack traces are lost, catch handlers receive unexpected types\n3. **How to fix** โ `new Error(msg)`, `Object.assign(new Error(...), extras)`, or Error subclasses\n",
|
|
34
35
|
"uninvoked-array-callback": "# llm-core/uninvoked-array-callback\n\n๐ Disallow callbacks on sparse arrays created with Array(length) because holes skip callback invocation.\n\n๐ผ This rule is enabled in the following configs: ๐ `all`, ๐ `best-practices`, โ
`recommended`.\n\n<!-- end auto-generated rule header -->\n\n## Rule details\n\nThis rule flags array callback methods called directly on sparse arrays created with `Array(length)` or `new Array(length)`. Those constructors create holes, not present `undefined` elements. JavaScript array callback methods skip holes, so callbacks such as `.map(...)`, `.forEach(...)`, `.filter(...)`, `.some(...)`, and `.every(...)` may run zero times even though the code looks like it should run once per index.\n\nLLMs often generate this pattern when they want to create `n` rows, placeholders, tasks, or test cases. The code silently returns another sparse array or performs no side effects.\n\nFlagged patterns:\n\n```ts\nconst rows = new Array(5).map((_, index) => createRow(index));\n\nArray(count).forEach((_, index) => {\n save(index);\n});\n\nconst ids = new Array(3).map((_, index) => index).filter((index) => index > 0);\n```\n\nCorrect patterns:\n\n```ts\nconst rows = Array.from({ length: 5 }, (_, index) => createRow(index));\n\nnew Array(count).fill(null).forEach((_, index) => {\n save(index);\n});\n\nconst ids = [...new Array(3)]\n .map((_, index) => index)\n .filter((index) => index > 0);\n```\n\n## What counts as a sparse array callback\n\n| Pattern | Triggers? | Why |\n| --------------------------------------- | --------- | ----------------------------------------------------------- |\n| `new Array(5).map(callback)` | Yes | Length-only arrays contain holes, so callbacks are skipped. |\n| `Array(count).forEach(callback)` | Yes | `Array(length)` has the same sparse-array behavior. |\n| `new Array(5).fill(null).map(callback)` | No | `.fill(...)` materializes present elements first. |\n| `new Array(5).fill(null, 1).map(cb)` | Yes | Partial fills leave holes outside the filled range. |\n| `[...new Array(5)].map(callback)` | No | Spreading materializes present `undefined` elements. |\n| `Array.from({ length: 5 }, callback)` | No | `Array.from` invokes the mapping callback for each index. |\n| `new Array(\"a\", \"b\").map(callback)` | No | Multiple arguments create present elements. |\n| `Array(true).map(callback)` | No | Non-number single arguments create one present element. |\n| `collection.map(callback)` | No | The rule stays narrow and only targets Array constructors. |\n\n## Error messages\n\nThe error message teaches:\n\n1. **What's wrong** โ `Array(length)` created sparse slots, so the callback will not run for them.\n2. **Why** โ LLM-generated code often expects one callback invocation per index, but array methods skip holes.\n3. **How to fix** โ use `Array.from({ length }, mapper)` or materialize elements with `.fill(...)` before calling callback methods.\n",
|
|
35
36
|
};
|
|
36
|
-
export const ruleNames = ["bad-comparison-sequence", "bad-min-max-func", "consistent-catch-param-name", "explicit-export-types", "filename-match-export", "max-complexity", "max-file-length", "max-function-length", "max-nesting-depth", "max-params", "missing-throw", "naming-conventions", "no-any-in-generic", "no-async-array-callbacks", "no-commented-out-code", "no-empty-catch", "no-exported-function-expressions", "no-floating-promise", "no-hallucinated-local-imports", "no-incorrect-sort", "no-inline-disable", "no-llm-artifacts", "no-magic-numbers", "no-redundant-logic", "no-swallowed-errors", "no-type-assertion-any", "prefer-early-return", "prefer-nullish-coalescing", "prefer-unknown-in-catch", "structured-logging", "throw-error-objects", "uninvoked-array-callback"];
|
|
37
|
+
export const ruleNames = ["bad-comparison-sequence", "bad-min-max-func", "consistent-catch-param-name", "explicit-export-types", "filename-match-export", "max-complexity", "max-file-length", "max-function-length", "max-nesting-depth", "max-params", "missing-throw", "naming-conventions", "no-any-in-generic", "no-async-array-callbacks", "no-async-promise-executor", "no-commented-out-code", "no-empty-catch", "no-exported-function-expressions", "no-floating-promise", "no-hallucinated-local-imports", "no-incorrect-sort", "no-inline-disable", "no-llm-artifacts", "no-magic-numbers", "no-redundant-logic", "no-swallowed-errors", "no-type-assertion-any", "prefer-early-return", "prefer-nullish-coalescing", "prefer-unknown-in-catch", "structured-logging", "throw-error-objects", "uninvoked-array-callback"];
|
|
37
38
|
//# sourceMappingURL=embedded-docs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedded-docs.js","sourceRoot":"","sources":["../src/embedded-docs.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,yBAAyB,EAAE,yyEAAyyE;IACp0E,kBAAkB,EAAE,6oFAA6oF;IACjqF,6BAA6B,EAAE,ipGAAipG;IAChrG,uBAAuB,EAAE,slLAAslL;IAC/mL,uBAAuB,EAAE,8qFAA8qF;IACvsF,gBAAgB,EAAE,8mHAA8mH;IAChoH,iBAAiB,EAAE,wrEAAwrE;IAC3sE,qBAAqB,EAAE,ksEAAksE;IACztE,mBAAmB,EAAE,+qEAA+qE;IACpsE,YAAY,EAAE,i8EAAi8E;IAC/8E,eAAe,EAAE,2vDAA2vD;IAC5wD,oBAAoB,EAAE,0sDAA0sD;IAChuD,mBAAmB,EAAE,srFAAsrF;IAC3sF,0BAA0B,EAAE,yyHAAyyH;IACr0H,uBAAuB,EAAE,8kGAA8kG;IACvmG,gBAAgB,EAAE,kxFAAkxF;IACpyF,kCAAkC,EAAE,6/HAA6/H;IACjiI,qBAAqB,EAAE,4iHAA4iH;IACnkH,+BAA+B,EAAE,qhFAAqhF;IACtjF,mBAAmB,EAAE,gwDAAgwD;IACrxD,mBAAmB,EAAE,w7DAAw7D;IAC78D,kBAAkB,EAAE,63HAA63H;IACj5H,kBAAkB,EAAE,o5GAAo5G;IACx6G,oBAAoB,EAAE,g1HAAg1H;IACt2H,qBAAqB,EAAE,kyFAAkyF;IACzzF,uBAAuB,EAAE,oqEAAoqE;IAC7rE,qBAAqB,EAAE,8mGAA8mG;IACroG,2BAA2B,EAAE,kwDAAkwD;IAC/xD,yBAAyB,EAAE,uzEAAuzE;IACl1E,oBAAoB,EAAE,6hGAA6hG;IACnjG,qBAAqB,EAAE,+2EAA+2E;IACt4E,0BAA0B,EAAE,4nGAA4nG;CACzpG,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAa,CAAC,yBAAyB,EAAC,kBAAkB,EAAC,6BAA6B,EAAC,uBAAuB,EAAC,uBAAuB,EAAC,gBAAgB,EAAC,iBAAiB,EAAC,qBAAqB,EAAC,mBAAmB,EAAC,YAAY,EAAC,eAAe,EAAC,oBAAoB,EAAC,mBAAmB,EAAC,0BAA0B,EAAC,uBAAuB,EAAC,gBAAgB,EAAC,kCAAkC,EAAC,qBAAqB,EAAC,+BAA+B,EAAC,mBAAmB,EAAC,mBAAmB,EAAC,kBAAkB,EAAC,kBAAkB,EAAC,oBAAoB,EAAC,qBAAqB,EAAC,uBAAuB,EAAC,qBAAqB,EAAC,2BAA2B,EAAC,yBAAyB,EAAC,oBAAoB,EAAC,qBAAqB,EAAC,0BAA0B,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"embedded-docs.js","sourceRoot":"","sources":["../src/embedded-docs.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,yBAAyB,EAAE,yyEAAyyE;IACp0E,kBAAkB,EAAE,6oFAA6oF;IACjqF,6BAA6B,EAAE,ipGAAipG;IAChrG,uBAAuB,EAAE,slLAAslL;IAC/mL,uBAAuB,EAAE,8qFAA8qF;IACvsF,gBAAgB,EAAE,8mHAA8mH;IAChoH,iBAAiB,EAAE,wrEAAwrE;IAC3sE,qBAAqB,EAAE,ksEAAksE;IACztE,mBAAmB,EAAE,+qEAA+qE;IACpsE,YAAY,EAAE,i8EAAi8E;IAC/8E,eAAe,EAAE,2vDAA2vD;IAC5wD,oBAAoB,EAAE,0sDAA0sD;IAChuD,mBAAmB,EAAE,srFAAsrF;IAC3sF,0BAA0B,EAAE,yyHAAyyH;IACr0H,2BAA2B,EAAE,ooEAAooE;IACjqE,uBAAuB,EAAE,8kGAA8kG;IACvmG,gBAAgB,EAAE,kxFAAkxF;IACpyF,kCAAkC,EAAE,6/HAA6/H;IACjiI,qBAAqB,EAAE,4iHAA4iH;IACnkH,+BAA+B,EAAE,qhFAAqhF;IACtjF,mBAAmB,EAAE,gwDAAgwD;IACrxD,mBAAmB,EAAE,w7DAAw7D;IAC78D,kBAAkB,EAAE,63HAA63H;IACj5H,kBAAkB,EAAE,o5GAAo5G;IACx6G,oBAAoB,EAAE,g1HAAg1H;IACt2H,qBAAqB,EAAE,kyFAAkyF;IACzzF,uBAAuB,EAAE,oqEAAoqE;IAC7rE,qBAAqB,EAAE,8mGAA8mG;IACroG,2BAA2B,EAAE,kwDAAkwD;IAC/xD,yBAAyB,EAAE,uzEAAuzE;IACl1E,oBAAoB,EAAE,6hGAA6hG;IACnjG,qBAAqB,EAAE,+2EAA+2E;IACt4E,0BAA0B,EAAE,4nGAA4nG;CACzpG,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAa,CAAC,yBAAyB,EAAC,kBAAkB,EAAC,6BAA6B,EAAC,uBAAuB,EAAC,uBAAuB,EAAC,gBAAgB,EAAC,iBAAiB,EAAC,qBAAqB,EAAC,mBAAmB,EAAC,YAAY,EAAC,eAAe,EAAC,oBAAoB,EAAC,mBAAmB,EAAC,0BAA0B,EAAC,2BAA2B,EAAC,uBAAuB,EAAC,gBAAgB,EAAC,kCAAkC,EAAC,qBAAqB,EAAC,+BAA+B,EAAC,mBAAmB,EAAC,mBAAmB,EAAC,kBAAkB,EAAC,kBAAkB,EAAC,oBAAoB,EAAC,qBAAqB,EAAC,uBAAuB,EAAC,qBAAqB,EAAC,2BAA2B,EAAC,yBAAyB,EAAC,oBAAoB,EAAC,qBAAqB,EAAC,0BAA0B,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-llm-core-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "MCP server for just-in-time linting guidance from eslint-plugin-llm-core",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
43
43
|
"@typescript-eslint/parser": "^8.0.0",
|
|
44
44
|
"eslint": "^10.1.0",
|
|
45
|
-
"eslint-plugin-llm-core": "0.
|
|
45
|
+
"eslint-plugin-llm-core": "0.26.0",
|
|
46
46
|
"zod": "^3.23.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|