@sushichan044/eslint-todo 0.2.5 → 0.3.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 +1 -28
- package/config-schema.json +4 -7
- package/dist/action/delete-rule.mjs +1 -2
- package/dist/action/gen.mjs +1 -2
- package/dist/action/index.mjs +1 -2
- package/dist/cli/commands/common-arguments.mjs +5 -12
- package/dist/cli/commands/correct.mjs +1 -2
- package/dist/cli/commands/generate.mjs +1 -2
- package/dist/cli/commands/index.mjs +5 -12
- package/dist/cli/handlers/correct.mjs +6 -10
- package/dist/cli/handlers/generate.mjs +4 -7
- package/dist/config/validation.mjs +11 -16
- package/dist/eslint/index.mjs +2 -5
- package/dist/index.mjs +1 -2
- package/dist/node_modules/.pnpm/{typia@9.6.0_typescript@5.8.3 → typia@11.0.0_typescript@5.9.3}/node_modules/typia/lib/internal/_accessExpressionAsString.mjs +2 -2
- package/dist/node_modules/.pnpm/{typia@9.6.0_typescript@5.8.3 → typia@11.0.0_typescript@5.9.3}/node_modules/typia/lib/internal/_createStandardSchema.mjs +7 -7
- package/dist/node_modules/.pnpm/{typia@9.6.0_typescript@5.8.3 → typia@11.0.0_typescript@5.9.3}/node_modules/typia/lib/internal/_validateReport.mjs +2 -2
- package/dist/operation/select-rule.mjs +11 -17
- package/dist/package.mjs +1 -1
- package/dist/path.d.mts +0 -3
- package/dist/path.mjs +1 -2
- package/dist/serializer.mjs +2 -3
- package/dist/todofile/index.d.mts +0 -8
- package/dist/todofile/v1.mjs +5 -6
- package/dist/todofile/v2.d.mts +2 -0
- package/dist/todofile/v2.mjs +7 -10
- package/dist/utils/glob.mjs +1 -2
- package/dist/worker/core/client.mjs +2 -5
- package/package.json +54 -73
- package/dist/cli/commands/mcp.mjs +0 -22
- package/dist/cli/handlers/mcp.mjs +0 -22
- package/dist/lib/eslint.d.mts +0 -11
- package/dist/mcp/index.d.mts +0 -8
- package/dist/mcp/index.mjs +0 -12
- package/dist/mcp/setup.d.mts +0 -11
- package/dist/mcp/setup.mjs +0 -108
- package/dist/mcp/stdio.mjs +0 -7
- package/dist/mcp/transport/stdio.mjs +0 -10
- package/dist/mcp/types.d.mts +0 -14
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ Requires:
|
|
|
22
22
|
- **Flat Config Required**
|
|
23
23
|
- If you are using legacy config, you must migrate into flat config first.
|
|
24
24
|
- Utilities like [@eslint/compat](https://github.com/eslint/rewrite/tree/main/packages/compat) can help you.
|
|
25
|
-
- Node.js:
|
|
25
|
+
- Node.js: `^20.12.0 || ^22.0.0 || >=24.0.0`
|
|
26
26
|
- May work in Deno, but not tested.
|
|
27
27
|
|
|
28
28
|
## Getting Started
|
|
@@ -125,30 +125,3 @@ Sure!
|
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
</details>
|
|
128
|
-
|
|
129
|
-
## Use as MCP server (Experimental)
|
|
130
|
-
|
|
131
|
-
eslint-todo provides some useful tools to AI Agents via MCP.
|
|
132
|
-
|
|
133
|
-
You mus specify `--mcp` and `--root <root path>`.
|
|
134
|
-
|
|
135
|
-
### Setup for VSCode
|
|
136
|
-
|
|
137
|
-
update `.vscode/mcp.json` in your workspace:
|
|
138
|
-
|
|
139
|
-
```json
|
|
140
|
-
{
|
|
141
|
-
"servers": {
|
|
142
|
-
"eslint-todo": {
|
|
143
|
-
"type": "stdio",
|
|
144
|
-
"command": "npx",
|
|
145
|
-
"args": [
|
|
146
|
-
"@sushichan044/eslint-todo",
|
|
147
|
-
"--mcp",
|
|
148
|
-
"--root",
|
|
149
|
-
"${workspaceFolder}"
|
|
150
|
-
]
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
```
|
package/config-schema.json
CHANGED
|
@@ -5,8 +5,7 @@ import { deleteRule } from "../operation/delete-rule.mjs";
|
|
|
5
5
|
const deleteRuleAction = defineAction(async ({ core, hooks }, input) => {
|
|
6
6
|
const currentModule = await core.readTodoModule();
|
|
7
7
|
if (!TodoModuleV2Handler.isVersion(currentModule)) throw new Error("This action requires the latest version of the todo file.");
|
|
8
|
-
|
|
9
|
-
if (hasChanges) {
|
|
8
|
+
if (await core.todoModuleHasUncommittedChanges()) {
|
|
10
9
|
await hooks.callHook("warn:todo-module-is-dirty");
|
|
11
10
|
return;
|
|
12
11
|
}
|
package/dist/action/gen.mjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { TodoModuleSerializer } from "../serializer.mjs";
|
|
2
2
|
import { defineAction } from "./index.mjs";
|
|
3
3
|
const genAction = defineAction(async ({ core, hooks }) => {
|
|
4
|
-
|
|
5
|
-
if (hasChanges) {
|
|
4
|
+
if (await core.todoModuleHasUncommittedChanges()) {
|
|
6
5
|
await hooks.callHook("warn:todo-module-is-dirty");
|
|
7
6
|
return;
|
|
8
7
|
}
|
package/dist/action/index.mjs
CHANGED
|
@@ -16,8 +16,7 @@ function prepareAction(action, options) {
|
|
|
16
16
|
hooks
|
|
17
17
|
};
|
|
18
18
|
try {
|
|
19
|
-
|
|
20
|
-
return result;
|
|
19
|
+
return input === void 0 ? await action(actionApi) : await action(actionApi, input);
|
|
21
20
|
} catch (error) {
|
|
22
21
|
throw error;
|
|
23
22
|
} finally {
|
|
@@ -18,18 +18,11 @@ const commonArguments = {
|
|
|
18
18
|
type: "string"
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
|
-
const modeArguments = {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
},
|
|
27
|
-
mcp: {
|
|
28
|
-
default: false,
|
|
29
|
-
description: "Launch the MCP server. (default: false)",
|
|
30
|
-
type: "boolean"
|
|
31
|
-
}
|
|
32
|
-
};
|
|
21
|
+
const modeArguments = { correct: {
|
|
22
|
+
default: false,
|
|
23
|
+
description: "Launch the correct mode (default: false)",
|
|
24
|
+
type: "boolean"
|
|
25
|
+
} };
|
|
33
26
|
const correctModeArguments = {
|
|
34
27
|
"correct.autoFixableOnly": {
|
|
35
28
|
description: "Allow to select non auto-fixable rules.",
|
|
@@ -34,8 +34,7 @@ const correctCmd = define({
|
|
|
34
34
|
todoFile: context.values.todoFile
|
|
35
35
|
};
|
|
36
36
|
const cliCwd = cwd();
|
|
37
|
-
|
|
38
|
-
return await handleCorrect(cliCwd, userConfig);
|
|
37
|
+
return await handleCorrect(cliCwd, isDirty ? userCLIConfig : await resolveFileConfig(cliCwd));
|
|
39
38
|
}
|
|
40
39
|
});
|
|
41
40
|
export { correctCmd };
|
|
@@ -15,8 +15,7 @@ const generateCmd = define({
|
|
|
15
15
|
todoFile: context.values.todoFile
|
|
16
16
|
};
|
|
17
17
|
const cliCwd = cwd();
|
|
18
|
-
|
|
19
|
-
return await handleGenerate(cliCwd, userConfig);
|
|
18
|
+
return await handleGenerate(cliCwd, isDirty ? userCLIConfig : await resolveFileConfig(cliCwd));
|
|
20
19
|
}
|
|
21
20
|
});
|
|
22
21
|
export { generateCmd };
|
|
@@ -3,18 +3,16 @@ import { resolveFileConfig } from "../../config/resolve.mjs";
|
|
|
3
3
|
import { logger } from "../logger.mjs";
|
|
4
4
|
import { handleCorrect } from "../handlers/correct.mjs";
|
|
5
5
|
import { handleGenerate } from "../handlers/generate.mjs";
|
|
6
|
-
import { handleMCP } from "../handlers/mcp.mjs";
|
|
7
6
|
import { commonArguments, correctModeArguments, modeArguments } from "./common-arguments.mjs";
|
|
8
7
|
import { correctCmd } from "./correct.mjs";
|
|
9
8
|
import { generateCmd } from "./generate.mjs";
|
|
10
|
-
import { mcpCmd } from "./mcp.mjs";
|
|
11
9
|
import { cwd } from "node:process";
|
|
12
10
|
import { cli, define } from "gunshi";
|
|
13
11
|
import { renderHeader } from "gunshi/renderer";
|
|
14
|
-
const subCommands =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
const subCommands = {
|
|
13
|
+
correct: correctCmd,
|
|
14
|
+
generate: generateCmd
|
|
15
|
+
};
|
|
18
16
|
const mainCmd = define({
|
|
19
17
|
args: {
|
|
20
18
|
...commonArguments,
|
|
@@ -23,12 +21,11 @@ const mainCmd = define({
|
|
|
23
21
|
},
|
|
24
22
|
name: "root",
|
|
25
23
|
run: async (context) => {
|
|
26
|
-
const { correct: _explicitCorrect,
|
|
24
|
+
const { correct: _explicitCorrect, ...flagsExceptMode } = context.explicit;
|
|
27
25
|
const isDirty = Object.values(flagsExceptMode).includes(true);
|
|
28
26
|
if (isDirty) logger.warn("Ignoring config file because config is passed via CLI flags.");
|
|
29
27
|
const mode = (() => {
|
|
30
28
|
if (context.values.correct) return "correct";
|
|
31
|
-
if (context.values.mcp) return "mcp";
|
|
32
29
|
return "generate";
|
|
33
30
|
})();
|
|
34
31
|
const userCLIConfig = {
|
|
@@ -53,10 +50,6 @@ const mainCmd = define({
|
|
|
53
50
|
};
|
|
54
51
|
const cliCwd = cwd();
|
|
55
52
|
const userConfig = isDirty ? userCLIConfig : await resolveFileConfig(cliCwd);
|
|
56
|
-
if (mode === "mcp") {
|
|
57
|
-
logger.warn("The `--mcp` flag is deprecated and will be removed in v1. Use the `mcp` sub command instead.");
|
|
58
|
-
return await handleMCP(cliCwd, userConfig);
|
|
59
|
-
}
|
|
60
53
|
if (mode === "correct") {
|
|
61
54
|
logger.warn("The `--correct` flag is deprecated and will be removed in v1. Use the `correct` sub command instead.");
|
|
62
55
|
return await handleCorrect(cliCwd, userConfig);
|
|
@@ -10,19 +10,17 @@ import { resolveFlatConfig } from "@sushichan044/eslint-config-array-resolver";
|
|
|
10
10
|
import { colorize } from "consola/utils";
|
|
11
11
|
const handleCorrect = async (cwd, userConfig) => {
|
|
12
12
|
const config = configWithDefault(userConfig);
|
|
13
|
-
const
|
|
14
|
-
const eslintConfigSubset = createESLintConfigSubset(eslintConfig);
|
|
13
|
+
const eslintConfigSubset = createESLintConfigSubset(await resolveFlatConfig(config.root));
|
|
15
14
|
const eslintTodoCore = new ESLintTodoCore(config);
|
|
16
15
|
const todoFilePathFromCLI = relative(cwd, eslintTodoCore.getTodoModulePath().absolute);
|
|
17
|
-
|
|
18
|
-
if (todoModuleHasChanges) {
|
|
16
|
+
if (await eslintTodoCore.todoModuleHasUncommittedChanges()) {
|
|
19
17
|
logger.warn(`Attempting to run \`eslint-todo --correct\` on ${todoFilePathFromCLI} which has uncommitted changes. Please commit or stash these changes and try again.
|
|
20
18
|
|
|
21
19
|
This command makes ignored errors in ${todoFilePathFromCLI} detectable by ESLint again.
|
|
22
20
|
If you want to fix ESLint errors, please use \`eslint --fix\` instead.`);
|
|
23
21
|
return;
|
|
24
22
|
}
|
|
25
|
-
const
|
|
23
|
+
const result = await prepareAction(selectRulesToFixAction, {
|
|
26
24
|
config,
|
|
27
25
|
eslintConfig: eslintConfigSubset,
|
|
28
26
|
hooks: {
|
|
@@ -37,10 +35,9 @@ If you want to fix ESLint errors, please use \`eslint --fix\` instead.`);
|
|
|
37
35
|
logger.success(`Selected ${result$1.selection.ruleId}.`);
|
|
38
36
|
}
|
|
39
37
|
}
|
|
40
|
-
});
|
|
41
|
-
const result = await selectRulesToFixExecutor();
|
|
38
|
+
})();
|
|
42
39
|
if (!result.success) return;
|
|
43
|
-
|
|
40
|
+
await prepareAction(deleteRuleAction, {
|
|
44
41
|
config,
|
|
45
42
|
eslintConfig: eslintConfigSubset,
|
|
46
43
|
hooks: { "after:delete-and-write": () => {
|
|
@@ -56,7 +53,6 @@ If you want to fix ESLint errors, please use \`eslint --fix\` instead.`);
|
|
|
56
53
|
const _exhaustiveCheck = result.selection;
|
|
57
54
|
throw new Error(`Unknown selection type: ${JSON.stringify(_exhaustiveCheck)}`);
|
|
58
55
|
} }
|
|
59
|
-
});
|
|
60
|
-
await deleteRuleExecutor(result.selection);
|
|
56
|
+
})(result.selection);
|
|
61
57
|
};
|
|
62
58
|
export { handleCorrect };
|
|
@@ -8,11 +8,9 @@ import { relative } from "pathe";
|
|
|
8
8
|
import { resolveFlatConfig } from "@sushichan044/eslint-config-array-resolver";
|
|
9
9
|
const handleGenerate = async (cwd, userConfig) => {
|
|
10
10
|
const config = configWithDefault(userConfig);
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
const todoFilePathFromCLI = relative(cwd, eslintTodoCore.getTodoModulePath().absolute);
|
|
15
|
-
const genActionExecutor = prepareAction(genAction, {
|
|
11
|
+
const eslintConfigSubset = createESLintConfigSubset(await resolveFlatConfig(config.root));
|
|
12
|
+
const todoFilePathFromCLI = relative(cwd, new ESLintTodoCore(config).getTodoModulePath().absolute);
|
|
13
|
+
await prepareAction(genAction, {
|
|
16
14
|
config,
|
|
17
15
|
eslintConfig: eslintConfigSubset,
|
|
18
16
|
hooks: {
|
|
@@ -29,7 +27,6 @@ const handleGenerate = async (cwd, userConfig) => {
|
|
|
29
27
|
logger.success(`ESLint todo file generated at ${todoFilePathFromCLI}!`);
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
|
-
});
|
|
33
|
-
await genActionExecutor();
|
|
30
|
+
})();
|
|
34
31
|
};
|
|
35
32
|
export { handleGenerate };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { __toESM } from "../_virtual/rolldown_runtime.mjs";
|
|
2
|
-
import { require__accessExpressionAsString } from "../node_modules/.pnpm/typia@
|
|
3
|
-
import { require__validateReport } from "../node_modules/.pnpm/typia@
|
|
4
|
-
import { require__createStandardSchema } from "../node_modules/.pnpm/typia@
|
|
5
|
-
var import__accessExpressionAsString = __toESM(require__accessExpressionAsString()
|
|
6
|
-
var import__validateReport = __toESM(require__validateReport()
|
|
7
|
-
var import__createStandardSchema = __toESM(require__createStandardSchema()
|
|
2
|
+
import { require__accessExpressionAsString } from "../node_modules/.pnpm/typia@11.0.0_typescript@5.9.3/node_modules/typia/lib/internal/_accessExpressionAsString.mjs";
|
|
3
|
+
import { require__validateReport } from "../node_modules/.pnpm/typia@11.0.0_typescript@5.9.3/node_modules/typia/lib/internal/_validateReport.mjs";
|
|
4
|
+
import { require__createStandardSchema } from "../node_modules/.pnpm/typia@11.0.0_typescript@5.9.3/node_modules/typia/lib/internal/_createStandardSchema.mjs";
|
|
5
|
+
var import__accessExpressionAsString = /* @__PURE__ */ __toESM(require__accessExpressionAsString());
|
|
6
|
+
var import__validateReport = /* @__PURE__ */ __toESM(require__validateReport());
|
|
7
|
+
var import__createStandardSchema = /* @__PURE__ */ __toESM(require__createStandardSchema());
|
|
8
8
|
const UserConfigSchema = (() => {
|
|
9
9
|
const _io0 = (input, _exceptionable = true) => (void 0 === input.correct || "object" === typeof input.correct && null !== input.correct && false === Array.isArray(input.correct) && _io1(input.correct, _exceptionable)) && (void 0 === input.root || "string" === typeof input.root) && (void 0 === input.todoFile || "string" === typeof input.todoFile) && (0 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
10
10
|
if ([
|
|
@@ -12,8 +12,7 @@ const UserConfigSchema = (() => {
|
|
|
12
12
|
"root",
|
|
13
13
|
"todoFile"
|
|
14
14
|
].some((prop) => key === prop)) return true;
|
|
15
|
-
|
|
16
|
-
if (void 0 === value) return true;
|
|
15
|
+
if (void 0 === input[key]) return true;
|
|
17
16
|
return false;
|
|
18
17
|
}));
|
|
19
18
|
const _io1 = (input, _exceptionable = true) => (void 0 === input.autoFixableOnly || "boolean" === typeof input.autoFixableOnly) && (void 0 === input.exclude || "object" === typeof input.exclude && null !== input.exclude && false === Array.isArray(input.exclude) && _io2(input.exclude, _exceptionable)) && (void 0 === input.include || "object" === typeof input.include && null !== input.include && false === Array.isArray(input.include) && _io3(input.include, _exceptionable)) && (void 0 === input.limit || "object" === typeof input.limit && null !== input.limit && false === Array.isArray(input.limit) && _io4(input.limit, _exceptionable)) && (void 0 === input.partialSelection || "boolean" === typeof input.partialSelection) && (0 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
@@ -24,26 +23,22 @@ const UserConfigSchema = (() => {
|
|
|
24
23
|
"limit",
|
|
25
24
|
"partialSelection"
|
|
26
25
|
].some((prop) => key === prop)) return true;
|
|
27
|
-
|
|
28
|
-
if (void 0 === value) return true;
|
|
26
|
+
if (void 0 === input[key]) return true;
|
|
29
27
|
return false;
|
|
30
28
|
}));
|
|
31
29
|
const _io2 = (input, _exceptionable = true) => (void 0 === input.files || Array.isArray(input.files) && input.files.every((elem, _index1) => "string" === typeof elem)) && (void 0 === input.rules || Array.isArray(input.rules) && input.rules.every((elem, _index2) => "string" === typeof elem)) && (0 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
32
30
|
if (["files", "rules"].some((prop) => key === prop)) return true;
|
|
33
|
-
|
|
34
|
-
if (void 0 === value) return true;
|
|
31
|
+
if (void 0 === input[key]) return true;
|
|
35
32
|
return false;
|
|
36
33
|
}));
|
|
37
34
|
const _io3 = (input, _exceptionable = true) => (void 0 === input.files || Array.isArray(input.files) && input.files.every((elem, _index3) => "string" === typeof elem)) && (void 0 === input.rules || Array.isArray(input.rules) && input.rules.every((elem, _index4) => "string" === typeof elem)) && (0 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
38
35
|
if (["files", "rules"].some((prop) => key === prop)) return true;
|
|
39
|
-
|
|
40
|
-
if (void 0 === value) return true;
|
|
36
|
+
if (void 0 === input[key]) return true;
|
|
41
37
|
return false;
|
|
42
38
|
}));
|
|
43
39
|
const _io4 = (input, _exceptionable = true) => (void 0 === input.count || "number" === typeof input.count) && (void 0 === input.type || "file" === input.type || "violation" === input.type) && (0 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
44
40
|
if (["count", "type"].some((prop) => key === prop)) return true;
|
|
45
|
-
|
|
46
|
-
if (void 0 === value) return true;
|
|
41
|
+
if (void 0 === input[key]) return true;
|
|
47
42
|
return false;
|
|
48
43
|
}));
|
|
49
44
|
const _vo0 = (input, _path, _exceptionable = true) => [
|
package/dist/eslint/index.mjs
CHANGED
|
@@ -8,13 +8,10 @@ import { cwd } from "node:process";
|
|
|
8
8
|
const eslintConfigTodo = async (config) => {
|
|
9
9
|
const root = config?.cwd;
|
|
10
10
|
const todoFile = config?.todoFile;
|
|
11
|
-
const
|
|
12
|
-
const configFromFile = await resolveFileConfig(cwdString);
|
|
13
|
-
const resolvedConfig = mergeUserConfig(configFromFile, {
|
|
11
|
+
const core = new ESLintTodoCore(mergeUserConfig(await resolveFileConfig(cwd()), {
|
|
14
12
|
root,
|
|
15
13
|
todoFile
|
|
16
|
-
});
|
|
17
|
-
const core = new ESLintTodoCore(resolvedConfig);
|
|
14
|
+
}));
|
|
18
15
|
const todoModulePath = core.getTodoModulePath();
|
|
19
16
|
const module = await (async () => {
|
|
20
17
|
try {
|
package/dist/index.mjs
CHANGED
|
@@ -36,8 +36,7 @@ var ESLintTodoCore = class {
|
|
|
36
36
|
});
|
|
37
37
|
}
|
|
38
38
|
async lint() {
|
|
39
|
-
|
|
40
|
-
return result;
|
|
39
|
+
return await this.#eslint.lintFiles(resolve(this.#config.root, "**/*"));
|
|
41
40
|
}
|
|
42
41
|
async resetTodoModule() {
|
|
43
42
|
if (!existsSync(this.#todoFilePath.absolute)) return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __commonJSMin } from "../../../../../../../_virtual/rolldown_runtime.mjs";
|
|
2
|
-
var require__accessExpressionAsString = __commonJSMin((exports) => {
|
|
2
|
+
var require__accessExpressionAsString = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports._accessExpressionAsString = void 0;
|
|
5
5
|
const _accessExpressionAsString = (str) => variable(str) ? `.${str}` : `[${JSON.stringify(str)}]`;
|
|
@@ -44,6 +44,6 @@ var require__accessExpressionAsString = __commonJSMin((exports) => {
|
|
|
44
44
|
"while",
|
|
45
45
|
"with"
|
|
46
46
|
]);
|
|
47
|
-
});
|
|
47
|
+
}));
|
|
48
48
|
export default require__accessExpressionAsString();
|
|
49
49
|
export { require__accessExpressionAsString };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __commonJSMin } from "../../../../../../../_virtual/rolldown_runtime.mjs";
|
|
2
|
-
var require__createStandardSchema = __commonJSMin((exports) => {
|
|
2
|
+
var require__createStandardSchema = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports._createStandardSchema = void 0;
|
|
5
5
|
const _createStandardSchema = (fn) => Object.assign(fn, { "~standard": {
|
|
@@ -16,11 +16,11 @@ var require__createStandardSchema = __commonJSMin((exports) => {
|
|
|
16
16
|
} });
|
|
17
17
|
exports._createStandardSchema = _createStandardSchema;
|
|
18
18
|
var PathParserState;
|
|
19
|
-
(function(PathParserState
|
|
20
|
-
PathParserState
|
|
21
|
-
PathParserState
|
|
22
|
-
PathParserState
|
|
23
|
-
PathParserState
|
|
19
|
+
(function(PathParserState) {
|
|
20
|
+
PathParserState[PathParserState["Start"] = 0] = "Start";
|
|
21
|
+
PathParserState[PathParserState["Property"] = 1] = "Property";
|
|
22
|
+
PathParserState[PathParserState["StringKey"] = 2] = "StringKey";
|
|
23
|
+
PathParserState[PathParserState["NumberKey"] = 3] = "NumberKey";
|
|
24
24
|
})(PathParserState || (PathParserState = {}));
|
|
25
25
|
const typiaPathToStandardSchemaPath = (path) => {
|
|
26
26
|
if (!path.startsWith("$input")) throw new Error(`Invalid path: ${JSON.stringify(path)}`);
|
|
@@ -69,6 +69,6 @@ var require__createStandardSchema = __commonJSMin((exports) => {
|
|
|
69
69
|
if (state !== PathParserState.Start) throw new Error(`Failed to parse path: ${JSON.stringify(path)}`);
|
|
70
70
|
return segments;
|
|
71
71
|
};
|
|
72
|
-
});
|
|
72
|
+
}));
|
|
73
73
|
export default require__createStandardSchema();
|
|
74
74
|
export { require__createStandardSchema };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __commonJSMin } from "../../../../../../../_virtual/rolldown_runtime.mjs";
|
|
2
|
-
var require__validateReport = __commonJSMin((exports) => {
|
|
2
|
+
var require__validateReport = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports._validateReport = void 0;
|
|
5
5
|
const _validateReport = (array) => {
|
|
@@ -22,6 +22,6 @@ var require__validateReport = __commonJSMin((exports) => {
|
|
|
22
22
|
};
|
|
23
23
|
};
|
|
24
24
|
exports._validateReport = _validateReport;
|
|
25
|
-
});
|
|
25
|
+
}));
|
|
26
26
|
export default require__validateReport();
|
|
27
27
|
export { require__validateReport };
|
|
@@ -7,8 +7,7 @@ const countRuleViolationsByLimit = (rule, limitType) => {
|
|
|
7
7
|
};
|
|
8
8
|
const categorizeRulesForSelection = (violationInfos, limitCount, limitType) => {
|
|
9
9
|
return violationInfos.reduce((accumulator, rule) => {
|
|
10
|
-
|
|
11
|
-
if (totalCount <= limitCount) accumulator.fullSelectable.push(rule);
|
|
10
|
+
if (countRuleViolationsByLimit(rule, limitType) <= limitCount) accumulator.fullSelectable.push(rule);
|
|
12
11
|
else accumulator.partialSelectable.push(rule);
|
|
13
12
|
return accumulator;
|
|
14
13
|
}, {
|
|
@@ -47,16 +46,13 @@ function decideOptimalRule(violationInfos, config) {
|
|
|
47
46
|
const { limit: { count: limitCount, type: limitType }, partialSelection: allowPartialSelection } = config;
|
|
48
47
|
if (violationInfos.length === 0) return { success: false };
|
|
49
48
|
const partitionedRules = categorizeRulesForSelection(violationInfos, limitCount, limitType);
|
|
50
|
-
if (partitionedRules.fullSelectable.length > 0) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
success: true
|
|
58
|
-
};
|
|
59
|
-
}
|
|
49
|
+
if (partitionedRules.fullSelectable.length > 0) return {
|
|
50
|
+
selection: {
|
|
51
|
+
ruleId: sortRulesByPriority(partitionedRules.fullSelectable, limitType)[0].ruleId,
|
|
52
|
+
type: "full"
|
|
53
|
+
},
|
|
54
|
+
success: true
|
|
55
|
+
};
|
|
60
56
|
if (!allowPartialSelection) return { success: false };
|
|
61
57
|
if (partitionedRules.partialSelectable.length === 0) return { success: false };
|
|
62
58
|
const bestPartialSelectableRule = sortRulesByPriority(partitionedRules.partialSelectable, limitType)[0];
|
|
@@ -107,12 +103,10 @@ function selectRuleToCorrect(suppressions, eslintConfig, config) {
|
|
|
107
103
|
throw new Error(`The ${limitTypeLabel} limit must be greater than 0.`);
|
|
108
104
|
}
|
|
109
105
|
const ruleBasedSuppression = toRuleBasedSuppression(suppressions);
|
|
110
|
-
|
|
106
|
+
return decideOptimalRule(filterViolations(Object.entries(ruleBasedSuppression).map(([ruleId, violations]) => ({
|
|
111
107
|
isFixable: isRuleFixable(eslintConfig, ruleId),
|
|
112
108
|
ruleId,
|
|
113
|
-
violations
|
|
114
|
-
}));
|
|
115
|
-
const filteredViolations = filterViolations(violations, config);
|
|
116
|
-
return decideOptimalRule(filteredViolations, config);
|
|
109
|
+
violations
|
|
110
|
+
})), config), config);
|
|
117
111
|
}
|
|
118
112
|
export { selectRuleToCorrect };
|
package/dist/package.mjs
CHANGED
package/dist/path.d.mts
CHANGED
package/dist/path.mjs
CHANGED
|
@@ -2,10 +2,9 @@ import { relative, resolve } from "pathe";
|
|
|
2
2
|
const resolveTodoModulePath = (config) => {
|
|
3
3
|
const { root, todoFile } = config;
|
|
4
4
|
const absolutePath = resolve(root, todoFile);
|
|
5
|
-
const relativePath = relative(root, absolutePath);
|
|
6
5
|
return {
|
|
7
6
|
absolute: absolutePath,
|
|
8
|
-
relative:
|
|
7
|
+
relative: relative(root, absolutePath)
|
|
9
8
|
};
|
|
10
9
|
};
|
|
11
10
|
export { resolveTodoModulePath };
|
package/dist/serializer.mjs
CHANGED
|
@@ -11,7 +11,7 @@ const TodoModuleSerializer = {
|
|
|
11
11
|
}
|
|
12
12
|
};
|
|
13
13
|
const serializeTodoModule = (eslintTodo) => {
|
|
14
|
-
const
|
|
14
|
+
const module_ = parseModule([
|
|
15
15
|
"/* eslint-disable */",
|
|
16
16
|
"/**",
|
|
17
17
|
" * Auto generated file by eslint-todo. DO NOT EDIT MANUALLY.",
|
|
@@ -20,8 +20,7 @@ const serializeTodoModule = (eslintTodo) => {
|
|
|
20
20
|
"/* prettier-ignore */",
|
|
21
21
|
"// biome-ignore format: this is an auto-generated file",
|
|
22
22
|
"export default {};"
|
|
23
|
-
].join("\n");
|
|
24
|
-
const module_ = parseModule(js);
|
|
23
|
+
].join("\n"));
|
|
25
24
|
module_.exports.default = eslintTodo;
|
|
26
25
|
const { code: jsCode } = generateCode(module_, { format: {
|
|
27
26
|
objectCurlySpacing: true,
|
|
@@ -2,13 +2,5 @@ import { ESLint } from "eslint";
|
|
|
2
2
|
|
|
3
3
|
//#region src/todofile/index.d.ts
|
|
4
4
|
type TodoModuleLike = Record<string, unknown>;
|
|
5
|
-
/**
|
|
6
|
-
* Interface representing a handler for managing different versions of a todo module.
|
|
7
|
-
*
|
|
8
|
-
* @template CURRENT - The current version of the todo module.
|
|
9
|
-
* @template NEXT - The next version of the todo module, defaults to `TodoModuleLike`.
|
|
10
|
-
*
|
|
11
|
-
* @package
|
|
12
|
-
*/
|
|
13
5
|
//#endregion
|
|
14
6
|
export { TodoModuleLike };
|
package/dist/todofile/v1.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __toESM } from "../_virtual/rolldown_runtime.mjs";
|
|
2
|
-
import { require__accessExpressionAsString } from "../node_modules/.pnpm/typia@
|
|
3
|
-
import { require__validateReport } from "../node_modules/.pnpm/typia@
|
|
2
|
+
import { require__accessExpressionAsString } from "../node_modules/.pnpm/typia@11.0.0_typescript@5.9.3/node_modules/typia/lib/internal/_accessExpressionAsString.mjs";
|
|
3
|
+
import { require__validateReport } from "../node_modules/.pnpm/typia@11.0.0_typescript@5.9.3/node_modules/typia/lib/internal/_validateReport.mjs";
|
|
4
4
|
import { isNonEmptyString } from "../utils/string.mjs";
|
|
5
5
|
import { TodoModuleV2Handler } from "./v2.mjs";
|
|
6
6
|
import { relative } from "pathe";
|
|
7
|
-
var import__accessExpressionAsString = __toESM(require__accessExpressionAsString()
|
|
8
|
-
var import__validateReport = __toESM(require__validateReport()
|
|
7
|
+
var import__accessExpressionAsString = /* @__PURE__ */ __toESM(require__accessExpressionAsString());
|
|
8
|
+
var import__validateReport = /* @__PURE__ */ __toESM(require__validateReport());
|
|
9
9
|
const TodoModuleV1Handler = {
|
|
10
10
|
version: 1,
|
|
11
11
|
buildTodoFromLintResults(lintResult, config) {
|
|
@@ -38,8 +38,7 @@ const TodoModuleV1Handler = {
|
|
|
38
38
|
});
|
|
39
39
|
const _io1 = (input, _exceptionable = true) => "boolean" === typeof input.autoFix && Array.isArray(input.files) && input.files.every((elem, _index1) => "string" === typeof elem) && (2 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
40
40
|
if (["autoFix", "files"].some((prop) => key === prop)) return true;
|
|
41
|
-
|
|
42
|
-
if (void 0 === value) return true;
|
|
41
|
+
if (void 0 === input[key]) return true;
|
|
43
42
|
return false;
|
|
44
43
|
}));
|
|
45
44
|
const _vo0 = (input, _path, _exceptionable = true) => [false === _exceptionable || Object.keys(input).map((key) => {
|
package/dist/todofile/v2.d.mts
CHANGED
package/dist/todofile/v2.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { __toESM } from "../_virtual/rolldown_runtime.mjs";
|
|
2
|
-
import { require__accessExpressionAsString } from "../node_modules/.pnpm/typia@
|
|
3
|
-
import { require__validateReport } from "../node_modules/.pnpm/typia@
|
|
2
|
+
import { require__accessExpressionAsString } from "../node_modules/.pnpm/typia@11.0.0_typescript@5.9.3/node_modules/typia/lib/internal/_accessExpressionAsString.mjs";
|
|
3
|
+
import { require__validateReport } from "../node_modules/.pnpm/typia@11.0.0_typescript@5.9.3/node_modules/typia/lib/internal/_validateReport.mjs";
|
|
4
4
|
import { isNonEmptyString } from "../utils/string.mjs";
|
|
5
5
|
import { relative } from "pathe";
|
|
6
|
-
var import__accessExpressionAsString = __toESM(require__accessExpressionAsString()
|
|
7
|
-
var import__validateReport = __toESM(require__validateReport()
|
|
6
|
+
var import__accessExpressionAsString = /* @__PURE__ */ __toESM(require__accessExpressionAsString());
|
|
7
|
+
var import__validateReport = /* @__PURE__ */ __toESM(require__validateReport());
|
|
8
8
|
const TodoModuleV2Handler = {
|
|
9
9
|
version: 2,
|
|
10
10
|
buildTodoFromLintResults(lintResult, config) {
|
|
@@ -36,14 +36,12 @@ const TodoModuleV2Handler = {
|
|
|
36
36
|
return (() => {
|
|
37
37
|
const _io0 = (input, _exceptionable = true) => "object" === typeof input.meta && null !== input.meta && _io1(input.meta, _exceptionable) && "object" === typeof input.todo && null !== input.todo && false === Array.isArray(input.todo) && _io2(input.todo, _exceptionable) && (2 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
38
38
|
if (["meta", "todo"].some((prop) => key === prop)) return true;
|
|
39
|
-
|
|
40
|
-
if (void 0 === value) return true;
|
|
39
|
+
if (void 0 === input[key]) return true;
|
|
41
40
|
return false;
|
|
42
41
|
}));
|
|
43
42
|
const _io1 = (input, _exceptionable = true) => 2 === input.version && (1 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
44
43
|
if (["version"].some((prop) => key === prop)) return true;
|
|
45
|
-
|
|
46
|
-
if (void 0 === value) return true;
|
|
44
|
+
if (void 0 === input[key]) return true;
|
|
47
45
|
return false;
|
|
48
46
|
}));
|
|
49
47
|
const _io2 = (input, _exceptionable = true) => Object.keys(input).every((key) => {
|
|
@@ -53,8 +51,7 @@ const TodoModuleV2Handler = {
|
|
|
53
51
|
});
|
|
54
52
|
const _io3 = (input, _exceptionable = true) => "boolean" === typeof input.autoFix && "object" === typeof input.violations && null !== input.violations && false === Array.isArray(input.violations) && _io4(input.violations, _exceptionable) && (2 === Object.keys(input).length || Object.keys(input).every((key) => {
|
|
55
53
|
if (["autoFix", "violations"].some((prop) => key === prop)) return true;
|
|
56
|
-
|
|
57
|
-
if (void 0 === value) return true;
|
|
54
|
+
if (void 0 === input[key]) return true;
|
|
58
55
|
return false;
|
|
59
56
|
}));
|
|
60
57
|
const _io4 = (input, _exceptionable = true) => Object.keys(input).every((key) => {
|
package/dist/utils/glob.mjs
CHANGED
|
@@ -6,7 +6,6 @@ const extractPathsByGlobs = (filePaths, patterns) => {
|
|
|
6
6
|
};
|
|
7
7
|
const pathMatchesGlobs = (filePath, patterns) => {
|
|
8
8
|
if (patterns.length === 0) return true;
|
|
9
|
-
|
|
10
|
-
return matchFunction(filePath);
|
|
9
|
+
return picomatch(patterns, { format: (input) => normalize(input) })(filePath);
|
|
11
10
|
};
|
|
12
11
|
export { extractPathsByGlobs };
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import { dirname, join } from "pathe";
|
|
2
1
|
import * as Comlink from "comlink";
|
|
3
2
|
import nodeEndPoint from "comlink/dist/esm/node-adapter.mjs";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
3
|
import { Worker } from "node:worker_threads";
|
|
6
4
|
const launchRemoteESLintTodoCore = () => {
|
|
7
|
-
const worker = new Worker(
|
|
8
|
-
const remoteCore = Comlink.wrap(nodeEndPoint(worker));
|
|
5
|
+
const worker = new Worker(new URL(import.meta.resolve("./index.mjs")));
|
|
9
6
|
return {
|
|
10
|
-
RemoteESLintTodoCore:
|
|
7
|
+
RemoteESLintTodoCore: Comlink.wrap(nodeEndPoint(worker)),
|
|
11
8
|
terminate: async () => {
|
|
12
9
|
await worker.terminate();
|
|
13
10
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sushichan044/eslint-todo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "A simple tool to gradually resolve a large number of ESLint violations.",
|
|
5
|
-
"
|
|
6
|
-
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/sushichan044/eslint-todo.git"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"eslint-todo": "bin/eslint-todo.mjs"
|
|
11
|
+
},
|
|
7
12
|
"files": [
|
|
8
|
-
"
|
|
9
|
-
"
|
|
13
|
+
"config-schema.json",
|
|
14
|
+
"dist"
|
|
10
15
|
],
|
|
16
|
+
"type": "module",
|
|
17
|
+
"module": "./dist/index.mjs",
|
|
11
18
|
"exports": {
|
|
12
19
|
".": {
|
|
13
20
|
"types": "./dist/index.d.mts",
|
|
@@ -21,102 +28,76 @@
|
|
|
21
28
|
"types": "./dist/eslint/index.d.mts",
|
|
22
29
|
"import": "./dist/eslint/index.mjs"
|
|
23
30
|
},
|
|
24
|
-
"./mcp": {
|
|
25
|
-
"types": "./dist/mcp/index.d.mts",
|
|
26
|
-
"import": "./dist/mcp/index.mjs"
|
|
27
|
-
},
|
|
28
31
|
"./package.json": "./package.json"
|
|
29
32
|
},
|
|
30
|
-
"bin": {
|
|
31
|
-
"eslint-todo": "bin/eslint-todo.mjs"
|
|
32
|
-
},
|
|
33
|
-
"repository": {
|
|
34
|
-
"type": "git",
|
|
35
|
-
"url": "git+https://github.com/sushichan044/eslint-todo.git"
|
|
36
|
-
},
|
|
37
33
|
"publishConfig": {
|
|
38
34
|
"access": "public",
|
|
39
35
|
"registry": "https://registry.npmjs.org/"
|
|
40
36
|
},
|
|
41
|
-
"peerDependencies": {
|
|
42
|
-
"eslint": "^8.57.0 || ^9.0.0"
|
|
43
|
-
},
|
|
44
37
|
"dependencies": {
|
|
45
|
-
"@
|
|
46
|
-
"@sushichan044/eslint-config-array-resolver": "0.1.0",
|
|
47
|
-
"@typescript-eslint/utils": "8.38.0",
|
|
48
|
-
"bundle-require": "5.1.0",
|
|
38
|
+
"@sushichan044/eslint-config-array-resolver": "0.1.4",
|
|
49
39
|
"comlink": "4.4.2",
|
|
50
40
|
"consola": "3.4.2",
|
|
51
41
|
"defu": "6.1.4",
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"jiti": "2.5.1",
|
|
42
|
+
"gunshi": "0.27.5",
|
|
43
|
+
"hookable": "6.0.1",
|
|
44
|
+
"jiti": "2.6.1",
|
|
56
45
|
"klona": "2.0.6",
|
|
57
|
-
"magicast": "0.
|
|
58
|
-
"mlly": "1.7.4",
|
|
46
|
+
"magicast": "0.5.1",
|
|
59
47
|
"pathe": "2.0.3",
|
|
60
48
|
"picomatch": "4.0.3",
|
|
61
|
-
"tinyexec": "1.0.
|
|
62
|
-
"zod": "3.25.76"
|
|
49
|
+
"tinyexec": "1.0.2"
|
|
63
50
|
},
|
|
64
51
|
"devDependencies": {
|
|
65
|
-
"@arethetypeswrong/
|
|
66
|
-
"@prettier/plugin-oxc": "0.0.4",
|
|
52
|
+
"@arethetypeswrong/core": "0.18.2",
|
|
67
53
|
"@ryoppippi/unplugin-typia": "2.6.5",
|
|
68
54
|
"@types/fs-extra": "11.0.4",
|
|
69
|
-
"@types/node": "22.
|
|
70
|
-
"@types/picomatch": "4.0.
|
|
71
|
-
"@virtual-live-lab/eslint-config": "2.
|
|
72
|
-
"@virtual-live-lab/prettier-config": "2.0.
|
|
55
|
+
"@types/node": "22.18.0",
|
|
56
|
+
"@types/picomatch": "4.0.2",
|
|
57
|
+
"@virtual-live-lab/eslint-config": "2.3.1",
|
|
58
|
+
"@virtual-live-lab/prettier-config": "2.0.22",
|
|
73
59
|
"@virtual-live-lab/tsconfig": "2.1.21",
|
|
74
|
-
"@vitest/
|
|
75
|
-
"
|
|
76
|
-
"eslint": "
|
|
77
|
-
"eslint-
|
|
78
|
-
"eslint-plugin-
|
|
79
|
-
"eslint-plugin-unicorn": "60.0.0",
|
|
60
|
+
"@vitest/eslint-plugin": "1.6.4",
|
|
61
|
+
"eslint": "9.39.2",
|
|
62
|
+
"eslint-flat-config-utils": "2.1.4",
|
|
63
|
+
"eslint-plugin-import-access": "3.1.0",
|
|
64
|
+
"eslint-plugin-unicorn": "62.0.0",
|
|
80
65
|
"eslint-typegen": "2.3.0",
|
|
81
|
-
"fs-extra": "11.3.
|
|
82
|
-
"fs-fixture": "2.
|
|
83
|
-
"globals": "
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"publint": "0.3.
|
|
88
|
-
"release-it": "19.
|
|
66
|
+
"fs-extra": "11.3.3",
|
|
67
|
+
"fs-fixture": "2.11.0",
|
|
68
|
+
"globals": "17.0.0",
|
|
69
|
+
"oxfmt": "0.21.0",
|
|
70
|
+
"pkg-pr-new": "0.0.62",
|
|
71
|
+
"pnpm": "10.27.0",
|
|
72
|
+
"publint": "0.3.16",
|
|
73
|
+
"release-it": "19.2.2",
|
|
89
74
|
"release-it-pnpm": "4.6.6",
|
|
90
|
-
"rolldown": "1.0.0-beta.29",
|
|
91
75
|
"ts-patch": "3.3.0",
|
|
92
|
-
"tsdown": "0.
|
|
93
|
-
"typescript": "5.
|
|
94
|
-
"typescript-eslint": "8.
|
|
95
|
-
"typia": "
|
|
96
|
-
"unplugin-unused": "0.5.
|
|
97
|
-
"vite": "7.0
|
|
98
|
-
"vite-node": "
|
|
99
|
-
"vitest": "
|
|
76
|
+
"tsdown": "0.18.4",
|
|
77
|
+
"typescript": "5.9.3",
|
|
78
|
+
"typescript-eslint": "8.51.0",
|
|
79
|
+
"typia": "11.0.0",
|
|
80
|
+
"unplugin-unused": "0.5.6",
|
|
81
|
+
"vite": "7.3.0",
|
|
82
|
+
"vite-node": "5.2.0",
|
|
83
|
+
"vitest": "4.0.16"
|
|
84
|
+
},
|
|
85
|
+
"peerDependencies": {
|
|
86
|
+
"eslint": "^8.57.0 || ^9.0.0"
|
|
100
87
|
},
|
|
101
88
|
"engines": {
|
|
102
|
-
"node": "^20.
|
|
89
|
+
"node": "^20.12.0 || ^22.0.0 || >=24.0.0"
|
|
103
90
|
},
|
|
104
91
|
"scripts": {
|
|
105
|
-
"build": "tsdown",
|
|
92
|
+
"build": "tsdown --config-loader unrun",
|
|
106
93
|
"build:json-schema": "vite-node scripts/json-schema.ts",
|
|
107
|
-
"dev": "unbuild --stub",
|
|
108
94
|
"lint": "eslint --max-warnings 0 .",
|
|
109
|
-
"format": "
|
|
110
|
-
"format:ci": "
|
|
95
|
+
"format": "oxfmt",
|
|
96
|
+
"format:ci": "oxfmt --check",
|
|
97
|
+
"test": "vitest run",
|
|
111
98
|
"typecheck": "tsc --noEmit",
|
|
112
|
-
"
|
|
113
|
-
"test:run": "vitest run",
|
|
114
|
-
"bench": "vitest bench",
|
|
115
|
-
"bench:run": "vitest bench --run",
|
|
116
|
-
"eslint:inspect": "eslint --inspect-config",
|
|
99
|
+
"eslint-config-inspector": "eslint --inspect-config",
|
|
117
100
|
"pkg-pr-new": "pkg-pr-new publish --compact --comment=update --pnpm",
|
|
118
|
-
"check": "pnpm run build && pnpm run lint && pnpm run format:ci && pnpm run typecheck && pnpm run test
|
|
119
|
-
"attw:check": "pnpm run build && pnpm pack && attw",
|
|
120
|
-
"ai:prettier": "prettier --experimental-cli"
|
|
101
|
+
"check": "pnpm run build && pnpm run lint && pnpm run format:ci && pnpm run typecheck && pnpm run test"
|
|
121
102
|
}
|
|
122
103
|
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { resolveFileConfig } from "../../config/resolve.mjs";
|
|
2
|
-
import { logger } from "../logger.mjs";
|
|
3
|
-
import { handleMCP } from "../handlers/mcp.mjs";
|
|
4
|
-
import { commonArguments } from "./common-arguments.mjs";
|
|
5
|
-
import { cwd } from "node:process";
|
|
6
|
-
import { define } from "gunshi/definition";
|
|
7
|
-
const mcpCmd = define({
|
|
8
|
-
args: { ...commonArguments },
|
|
9
|
-
name: "mcp",
|
|
10
|
-
run: async (context) => {
|
|
11
|
-
const isDirty = Object.values(context.explicit).includes(true);
|
|
12
|
-
if (isDirty) logger.warn("Ignoring config file because config is passed via CLI flags.");
|
|
13
|
-
const userCLIConfig = {
|
|
14
|
-
root: context.values.root,
|
|
15
|
-
todoFile: context.values.todoFile
|
|
16
|
-
};
|
|
17
|
-
const cliCwd = cwd();
|
|
18
|
-
const userConfig = isDirty ? userCLIConfig : await resolveFileConfig(cliCwd);
|
|
19
|
-
await handleMCP(cliCwd, userConfig);
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
export { mcpCmd };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { configWithDefault } from "../../config/config.mjs";
|
|
2
|
-
import { createESLintConfigSubset } from "../../lib/eslint.mjs";
|
|
3
|
-
import { startMcpServerWithStdio } from "../../mcp/stdio.mjs";
|
|
4
|
-
import { resolveFlatConfig } from "@sushichan044/eslint-config-array-resolver";
|
|
5
|
-
const handleMCP = async (cwd, userConfig) => {
|
|
6
|
-
const config = configWithDefault(userConfig);
|
|
7
|
-
const eslintConfig = await resolveFlatConfig(config.root);
|
|
8
|
-
const eslintConfigSubset = createESLintConfigSubset(eslintConfig);
|
|
9
|
-
const stopMcpServer = await startMcpServerWithStdio({
|
|
10
|
-
config,
|
|
11
|
-
eslintConfig: eslintConfigSubset
|
|
12
|
-
});
|
|
13
|
-
process.on("SIGINT", () => {
|
|
14
|
-
stopMcpServer().then(() => {
|
|
15
|
-
process.exit(0);
|
|
16
|
-
}).catch((error) => {
|
|
17
|
-
console.error(error);
|
|
18
|
-
process.exit(1);
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
export { handleMCP };
|
package/dist/lib/eslint.d.mts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Linter } from "eslint";
|
|
2
|
-
import "@sushichan044/eslint-config-array-resolver";
|
|
3
|
-
|
|
4
|
-
//#region src/lib/eslint.d.ts
|
|
5
|
-
interface ESLintConfigSubset {
|
|
6
|
-
rules: Record<string, {
|
|
7
|
-
fixable: boolean;
|
|
8
|
-
}>;
|
|
9
|
-
}
|
|
10
|
-
//#endregion
|
|
11
|
-
export { ESLintConfigSubset };
|
package/dist/mcp/index.d.mts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { MCPServerContext } from "./types.mjs";
|
|
2
|
-
import { SetupMcpServerOptions } from "./setup.mjs";
|
|
3
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
-
|
|
5
|
-
//#region src/mcp/index.d.ts
|
|
6
|
-
declare const ESLintTodoMcpServer: (context: MCPServerContext, options?: Partial<SetupMcpServerOptions>) => McpServer;
|
|
7
|
-
//#endregion
|
|
8
|
-
export { ESLintTodoMcpServer };
|
package/dist/mcp/index.mjs
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { name, version } from "../package.mjs";
|
|
2
|
-
import { setupMcpServer } from "./setup.mjs";
|
|
3
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
-
const ESLintTodoMcpServer = (context, options = {}) => {
|
|
5
|
-
const server = new McpServer({
|
|
6
|
-
name,
|
|
7
|
-
version
|
|
8
|
-
});
|
|
9
|
-
setupMcpServer(server, context, options);
|
|
10
|
-
return server;
|
|
11
|
-
};
|
|
12
|
-
export { ESLintTodoMcpServer };
|
package/dist/mcp/setup.d.mts
DELETED
package/dist/mcp/setup.mjs
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { ESLintTodoCore } from "../index.mjs";
|
|
2
|
-
import { prepareAction } from "../action/index.mjs";
|
|
3
|
-
import { deleteRuleAction } from "../action/delete-rule.mjs";
|
|
4
|
-
import { selectRulesToFixAction } from "../action/select-rule.mjs";
|
|
5
|
-
import { mergeConfig } from "../config/index.mjs";
|
|
6
|
-
import { z } from "zod";
|
|
7
|
-
const setupMcpServer = (server, context, { onError } = {}) => {
|
|
8
|
-
onError ??= (error) => {
|
|
9
|
-
console.error(error);
|
|
10
|
-
};
|
|
11
|
-
server.server.onerror = onError;
|
|
12
|
-
server.tool("delete_suppression_with_limit", [
|
|
13
|
-
"Delete suppression from ESLint suppressions json file with specific limit.",
|
|
14
|
-
"",
|
|
15
|
-
"Use this tool when you need to reduce ESLint suppressions while controlling the amount of diff reviewable.",
|
|
16
|
-
"If you want to fix ESLint errors, please use `eslint --fix` instead.",
|
|
17
|
-
"",
|
|
18
|
-
"## Parameters",
|
|
19
|
-
"You only specify the parameters you need for your work."
|
|
20
|
-
].join("\n"), {
|
|
21
|
-
autoFixableOnly: z.boolean().optional().describe("Allow to select non auto-fixable rules"),
|
|
22
|
-
excludedRules: z.array(z.string()).optional().default([]).describe("List of rules to exclude"),
|
|
23
|
-
limitCount: z.number().optional().describe("Limit of suppression to delete"),
|
|
24
|
-
limitType: z.enum(["file", "violation"]).optional().describe("Type of limit"),
|
|
25
|
-
partialSelection: z.boolean().optional().describe("Allow to select partial suppressions of a rule")
|
|
26
|
-
}, {
|
|
27
|
-
destructiveHint: true,
|
|
28
|
-
idempotentHint: false,
|
|
29
|
-
openWorldHint: false,
|
|
30
|
-
readOnlyHint: false,
|
|
31
|
-
title: "Delete suppression with limit"
|
|
32
|
-
}, async (parameters) => {
|
|
33
|
-
try {
|
|
34
|
-
const config = mergeConfig(context.config, { correct: {
|
|
35
|
-
autoFixableOnly: parameters.autoFixableOnly,
|
|
36
|
-
exclude: { rules: parameters.excludedRules },
|
|
37
|
-
limit: {
|
|
38
|
-
count: parameters.limitCount,
|
|
39
|
-
type: parameters.limitType
|
|
40
|
-
},
|
|
41
|
-
partialSelection: parameters.partialSelection
|
|
42
|
-
} });
|
|
43
|
-
const core = new ESLintTodoCore(config);
|
|
44
|
-
const todoModuleHasChanges = await core.todoModuleHasUncommittedChanges();
|
|
45
|
-
if (todoModuleHasChanges) return {
|
|
46
|
-
content: [{
|
|
47
|
-
text: [
|
|
48
|
-
"# Warning: The suppressions file has uncommitted changes",
|
|
49
|
-
"You attempt to run this tool on a suppressions file that has uncommitted changes.",
|
|
50
|
-
"This will cause unexpected diff, so we stopped the tool.",
|
|
51
|
-
"",
|
|
52
|
-
"## Suggested action",
|
|
53
|
-
"1. Commit or stash these changes and try again. You should confirm with human reviewer.",
|
|
54
|
-
"2. If you want to fix ESLint errors, please use `eslint --fix` instead."
|
|
55
|
-
].join("\n"),
|
|
56
|
-
type: "text"
|
|
57
|
-
}],
|
|
58
|
-
isError: true
|
|
59
|
-
};
|
|
60
|
-
const selectRule = prepareAction(selectRulesToFixAction, {
|
|
61
|
-
config,
|
|
62
|
-
eslintConfig: context.eslintConfig
|
|
63
|
-
});
|
|
64
|
-
const selectionResult = await selectRule();
|
|
65
|
-
if (!selectionResult.success) return { content: [{
|
|
66
|
-
text: [
|
|
67
|
-
"# No rules to fix",
|
|
68
|
-
"Could not select rules to fix with given limit. Deletion from suppression json will not be performed.",
|
|
69
|
-
"## Recommended action",
|
|
70
|
-
"1. Check the eslint suppressions json file to ensure that the rule is suppressed.",
|
|
71
|
-
"2. If the rule is suppressed, try a larger limit.",
|
|
72
|
-
"3. If you can allow deleting partial suppressions of a rule, try to set `partialSelection` to `true`."
|
|
73
|
-
].join("\n"),
|
|
74
|
-
type: "text"
|
|
75
|
-
}] };
|
|
76
|
-
const deleteRule = prepareAction(deleteRuleAction, {
|
|
77
|
-
config: context.config,
|
|
78
|
-
eslintConfig: context.eslintConfig
|
|
79
|
-
});
|
|
80
|
-
await deleteRule(selectionResult.selection);
|
|
81
|
-
if (selectionResult.selection.type === "full") return { content: [{
|
|
82
|
-
text: ["# Tool call succeed", `All suppressions of ${selectionResult.selection.ruleId} have been deleted.`].join("\n"),
|
|
83
|
-
type: "text"
|
|
84
|
-
}] };
|
|
85
|
-
const deletedCount = Object.values(selectionResult.selection.violations).reduce((accumulator, current) => accumulator + current, 0);
|
|
86
|
-
return { content: [{
|
|
87
|
-
text: ["# Tool call succeed", `${deletedCount} suppressions of ${selectionResult.selection.ruleId} have been deleted.`].join("\n"),
|
|
88
|
-
type: "text"
|
|
89
|
-
}] };
|
|
90
|
-
} catch (error) {
|
|
91
|
-
console.error(error);
|
|
92
|
-
return {
|
|
93
|
-
content: [{
|
|
94
|
-
text: [
|
|
95
|
-
"# **Error Occurred**",
|
|
96
|
-
"It looks like there was an error while communicating with the eslint-todo API.",
|
|
97
|
-
"",
|
|
98
|
-
"## Error Details",
|
|
99
|
-
error instanceof Error ? error.message : String(error)
|
|
100
|
-
].join("\n"),
|
|
101
|
-
type: "text"
|
|
102
|
-
}],
|
|
103
|
-
isError: true
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
};
|
|
108
|
-
export { setupMcpServer };
|
package/dist/mcp/stdio.mjs
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { ESLintTodoMcpServer } from "./index.mjs";
|
|
2
|
-
import { startStdioTransport } from "./transport/stdio.mjs";
|
|
3
|
-
const startMcpServerWithStdio = async (context) => {
|
|
4
|
-
const server = ESLintTodoMcpServer(context);
|
|
5
|
-
return startStdioTransport(server);
|
|
6
|
-
};
|
|
7
|
-
export { startMcpServerWithStdio };
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
2
|
-
const startStdioTransport = async (server) => {
|
|
3
|
-
const transport = new StdioServerTransport();
|
|
4
|
-
await server.connect(transport);
|
|
5
|
-
return async () => {
|
|
6
|
-
await server.close();
|
|
7
|
-
await transport.close();
|
|
8
|
-
};
|
|
9
|
-
};
|
|
10
|
-
export { startStdioTransport };
|
package/dist/mcp/types.d.mts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Config } from "../config/config.mjs";
|
|
2
|
-
import { ESLintConfigSubset } from "../lib/eslint.mjs";
|
|
3
|
-
|
|
4
|
-
//#region src/mcp/types.d.ts
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @package
|
|
8
|
-
*/
|
|
9
|
-
interface MCPServerContext {
|
|
10
|
-
config: Config;
|
|
11
|
-
eslintConfig: ESLintConfigSubset;
|
|
12
|
-
}
|
|
13
|
-
//#endregion
|
|
14
|
-
export { MCPServerContext };
|