@sushichan044/eslint-todo 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,15 +1,11 @@
1
1
  {
2
2
  "name": "@sushichan044/eslint-todo",
3
- "repository": {
4
- "type": "git",
5
- "url": "https://github.com/sushichan044/eslint-todo.git"
6
- },
7
- "version": "0.0.3",
3
+ "version": "0.0.4",
8
4
  "type": "module",
9
- "bin": {
10
- "eslint-todo": "bin/eslint-todo.mjs"
11
- },
12
5
  "module": "./dist/index.mjs",
6
+ "files": [
7
+ "dist"
8
+ ],
13
9
  "exports": {
14
10
  ".": {
15
11
  "import": "./dist/index.mjs",
@@ -20,9 +16,17 @@
20
16
  "types": "./dist/eslint/index.d.ts"
21
17
  }
22
18
  },
23
- "files": [
24
- "dist"
25
- ],
19
+ "bin": {
20
+ "eslint-todo": "bin/eslint-todo.mjs"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/sushichan044/eslint-todo.git"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public",
28
+ "registry": "https://registry.npmjs.org/"
29
+ },
26
30
  "peerDependencies": {
27
31
  "eslint": "^8.57.0 || ^9.0.0"
28
32
  },
@@ -31,7 +35,6 @@
31
35
  "comlink": "4.4.2",
32
36
  "consola": "3.4.0",
33
37
  "defu": "6.1.4",
34
- "es-toolkit": "1.32.0",
35
38
  "jiti": "2.4.2",
36
39
  "klona": "2.0.6",
37
40
  "magicast": "0.3.5",
@@ -55,6 +58,8 @@
55
58
  "pkg-pr-new": "0.0.40",
56
59
  "pnpm": "10.5.2",
57
60
  "prettier": "3.5.3",
61
+ "release-it": "18.1.2",
62
+ "release-it-pnpm": "4.6.4",
58
63
  "typescript": "5.7.3",
59
64
  "typescript-eslint": "8.25.0",
60
65
  "unbuild": "3.5.0",
@@ -1,3 +0,0 @@
1
- declare const run: (argv: string[]) => Promise<void>;
2
-
3
- export { run };
@@ -1,3 +0,0 @@
1
- declare const run: (argv: string[]) => Promise<void>;
2
-
3
- export { run };
@@ -1,478 +0,0 @@
1
- import { defineCommand, runMain } from 'citty';
2
- import { createConsola } from 'consola';
3
- import { colorize } from 'consola/utils';
4
- import { L as LATEST_MODULE_HANDLER, i as isNonEmptyString, T as TodoModuleV1Handler, E as ESLintTodoCore } from '../shared/eslint-todo.BShlgWEx.mjs';
5
- import { launchRemoteESLintTodoCore } from '../remote/client.mjs';
6
- import { klona } from 'klona/json';
7
- import defu from 'defu';
8
- import { relative } from 'pathe';
9
- import * as v from 'valibot';
10
- import 'eslint';
11
- import 'node:fs';
12
- import 'node:fs/promises';
13
- import 'magicast';
14
- import 'es-toolkit/compat';
15
- import 'node:process';
16
- import 'jiti';
17
- import 'comlink';
18
- import 'comlink/dist/esm/node-adapter.mjs';
19
- import 'node:url';
20
- import 'node:worker_threads';
21
-
22
- const version = "0.0.3";
23
-
24
- const defineAction = (action) => action;
25
- const NO_INPUT = Symbol("NO_INPUT");
26
- async function runAction(action, options, input = NO_INPUT) {
27
- const { consola, options: coreOptions } = options;
28
- const remoteService = launchRemoteESLintTodoCore();
29
- const remoteCore = await new remoteService.RemoteESLintTodoCore(coreOptions);
30
- const actionApi = {
31
- core: remoteCore,
32
- logger: consola
33
- };
34
- try {
35
- if (input === NO_INPUT) {
36
- return await action(actionApi);
37
- }
38
- return await action(actionApi, input);
39
- } catch (error) {
40
- consola.error(error);
41
- throw error;
42
- } finally {
43
- await remoteService.terminate();
44
- }
45
- }
46
-
47
- const deleteRule = (currentModule, ruleSelection) => {
48
- if (!Object.hasOwn(currentModule.todo, ruleSelection.ruleId)) {
49
- return currentModule;
50
- }
51
- if (ruleSelection.type === "full") {
52
- const newModule = klona(currentModule);
53
- delete newModule.todo[ruleSelection.ruleId];
54
- return newModule;
55
- }
56
- if (ruleSelection.type === "partial") {
57
- const newModule = klona(currentModule);
58
- const entry = newModule.todo[ruleSelection.ruleId];
59
- for (const [file, count] of Object.entries(ruleSelection.violations)) {
60
- if (!Object.hasOwn(entry.violations, file)) {
61
- continue;
62
- }
63
- if (entry.violations[file] == null || entry.violations[file] !== count) {
64
- continue;
65
- }
66
- delete entry.violations[file];
67
- }
68
- return newModule;
69
- }
70
- const _exhaustiveCheck = ruleSelection;
71
- throw new Error(
72
- `Unknown rule selection type ${JSON.stringify(_exhaustiveCheck)}`
73
- );
74
- };
75
-
76
- const deleteRuleAction = defineAction(async ({ core }, input) => {
77
- const currentModule = await core.readTodoModule();
78
- if (!LATEST_MODULE_HANDLER.isVersion(currentModule)) {
79
- throw new Error(
80
- "This action requires the latest version of the todo file."
81
- );
82
- }
83
- const newModule = deleteRule(currentModule, input);
84
- await core.writeTodoModule(newModule);
85
- });
86
-
87
- const genAction = defineAction(async ({ core, logger }) => {
88
- await core.resetTodoModule();
89
- logger.start("Running ESLint ...");
90
- const lintResults = await core.lint();
91
- logger.success("ESLint finished!");
92
- logger.start("Generating ESLint todo file ...");
93
- const todo = await core.buildTodoFromLintResults(lintResults);
94
- await core.writeTodoModule(todo);
95
- });
96
-
97
- const operationOptionsWithDefault = (options = {}) => {
98
- return defu(options, getDefaultOperationOptions());
99
- };
100
- const getDefaultOperationOptions = () => ({
101
- allowPartialSelection: false,
102
- autoFixableOnly: true
103
- });
104
-
105
- const selectRuleBasedOnLimit = (todoModule, limit, options = {}) => {
106
- const resolvedOptions = operationOptionsWithDefault(options);
107
- switch (limit.type) {
108
- case "file": {
109
- return selectRuleBasedOnFilesLimit(todoModule, limit, resolvedOptions);
110
- }
111
- case "violation": {
112
- return selectRuleBasedOnViolationsLimit(
113
- todoModule,
114
- limit,
115
- resolvedOptions
116
- );
117
- }
118
- default: {
119
- const l = limit;
120
- throw new Error(`Got unknown limit: ${JSON.stringify(l)}`);
121
- }
122
- }
123
- };
124
- const selectRuleBasedOnFilesLimit = (todoModule, limit, options) => {
125
- const { count: limitCount } = limit;
126
- const { allowPartialSelection, autoFixableOnly } = options;
127
- if (limitCount <= 0) {
128
- throw new Error("The file limit must be greater than 0.");
129
- }
130
- let fullSelectableRule = null;
131
- let selectedTargetCount = 0;
132
- let partialSelectableRule = null;
133
- for (const [ruleId, entry] of Object.entries(todoModule.todo)) {
134
- if (autoFixableOnly && !entry.autoFix) {
135
- continue;
136
- }
137
- const violatedFiles = Object.keys(entry.violations).length;
138
- if (violatedFiles > limitCount) {
139
- if (allowPartialSelection && partialSelectableRule == null) {
140
- partialSelectableRule = ruleId;
141
- }
142
- continue;
143
- }
144
- if (violatedFiles > selectedTargetCount) {
145
- fullSelectableRule = ruleId;
146
- selectedTargetCount = violatedFiles;
147
- }
148
- }
149
- if (fullSelectableRule != null) {
150
- return {
151
- selection: {
152
- ruleId: fullSelectableRule,
153
- type: "full"
154
- },
155
- success: true
156
- };
157
- }
158
- if (allowPartialSelection && isKeyOfTodo(todoModule.todo, partialSelectableRule)) {
159
- const rule = todoModule.todo[partialSelectableRule];
160
- const selectedPaths = Object.keys(rule.violations).slice(0, limitCount);
161
- const selectedViolations = {};
162
- for (const file of selectedPaths) {
163
- selectedViolations[file] = rule.violations[file];
164
- }
165
- return {
166
- selection: {
167
- ruleId: partialSelectableRule,
168
- type: "partial",
169
- violations: selectedViolations
170
- },
171
- success: true
172
- };
173
- }
174
- return { success: false };
175
- };
176
- const selectRuleBasedOnViolationsLimit = (todoModule, limit, options) => {
177
- const { count: limitCount } = limit;
178
- const { allowPartialSelection, autoFixableOnly } = options;
179
- if (limitCount <= 0) {
180
- throw new Error("The violation limit must be greater than 0.");
181
- }
182
- let fullSelectableRule = null;
183
- let selectedTargetCount = 0;
184
- let partialSelectableRule = null;
185
- for (const [ruleId, entry] of Object.entries(todoModule.todo)) {
186
- if (autoFixableOnly && !entry.autoFix) {
187
- continue;
188
- }
189
- const totalViolationCount = Object.values(entry.violations).reduce(
190
- (sum, count) => sum + count,
191
- 0
192
- );
193
- if (totalViolationCount > limitCount) {
194
- if (allowPartialSelection && partialSelectableRule == null) {
195
- partialSelectableRule = ruleId;
196
- }
197
- continue;
198
- }
199
- if (totalViolationCount > selectedTargetCount) {
200
- fullSelectableRule = ruleId;
201
- selectedTargetCount = totalViolationCount;
202
- }
203
- }
204
- if (fullSelectableRule != null) {
205
- return {
206
- selection: {
207
- ruleId: fullSelectableRule,
208
- type: "full"
209
- },
210
- success: true
211
- };
212
- }
213
- if (allowPartialSelection && isKeyOfTodo(todoModule.todo, partialSelectableRule)) {
214
- const rule = todoModule.todo[partialSelectableRule];
215
- let selectedCount = 0;
216
- const selectedViolations = {};
217
- for (const [file, count] of Object.entries(rule.violations)) {
218
- if (selectedCount + count > limitCount) {
219
- break;
220
- }
221
- selectedCount += count;
222
- selectedViolations[file] = count;
223
- }
224
- if (Object.keys(selectedViolations).length === 0) {
225
- return { success: false };
226
- }
227
- return {
228
- selection: {
229
- ruleId: partialSelectableRule,
230
- type: "partial",
231
- violations: selectedViolations
232
- },
233
- success: true
234
- };
235
- }
236
- return { success: false };
237
- };
238
- const isKeyOfTodo = (todoModule, ruleId) => {
239
- return isNonEmptyString(ruleId) && Object.hasOwn(todoModule, ruleId);
240
- };
241
-
242
- const selectRulesToFixAction = defineAction(
243
- async ({ core, logger }, input) => {
244
- const { limit, options } = input;
245
- const currentModule = await core.readTodoModule();
246
- if (!LATEST_MODULE_HANDLER.isVersion(currentModule)) {
247
- throw new Error(
248
- "This action requires the latest version of the todo file."
249
- );
250
- }
251
- logger.start("Refining ESLint todo file ...");
252
- return selectRuleBasedOnLimit(currentModule, limit, options);
253
- }
254
- );
255
-
256
- const updateAction = defineAction(async ({ core, logger }) => {
257
- const currentModule = await core.readTodoModule();
258
- if (!TodoModuleV1Handler.isVersion(currentModule)) {
259
- return;
260
- }
261
- logger.start(
262
- "Detected old version of todo file. Automatically upgrading ..."
263
- );
264
- const nextModule = TodoModuleV1Handler.upgradeToNextVersion(currentModule);
265
- if (nextModule === false) {
266
- logger.error("Upgrade failed!");
267
- return;
268
- }
269
- await core.writeTodoModule(nextModule);
270
- logger.success("Upgrade finished!");
271
- });
272
-
273
- const safeTryNumber = (value) => {
274
- const parsed = Number(value);
275
- return Number.isNaN(parsed) ? null : parsed;
276
- };
277
-
278
- const resolveCLIContext = (input) => {
279
- const todoFilePath = relative(input.cwd, input.todoFileAbsolutePath);
280
- return {
281
- mode: input.mode.correct ? "correct" : "generate",
282
- operation: resolveCLIOperation(input.operation),
283
- todoFilePath
284
- };
285
- };
286
- const limitTypeSchema = v.union([v.literal("violation"), v.literal("file")]);
287
- const resolveCLIOperation = (input) => {
288
- const parsedLimitType = v.safeParse(limitTypeSchema, input.limitType);
289
- if (!parsedLimitType.success) {
290
- throw new Error("limit-type must be either 'violation' or 'file'");
291
- }
292
- const limitCount = safeTryNumber(input.limit);
293
- if (limitCount === null) {
294
- throw new Error("limit must be a number");
295
- }
296
- const limit = {
297
- count: limitCount,
298
- type: parsedLimitType.output
299
- };
300
- return {
301
- limit,
302
- options: {
303
- allowPartialSelection: input.allowPartialSelection,
304
- autoFixableOnly: input.autoFixableOnly
305
- }
306
- };
307
- };
308
-
309
- const consola = createConsola({ formatOptions: { date: false } });
310
- const cli = defineCommand({
311
- args: {
312
- // IMPORTANT:
313
- // do not set default values for boolean options!
314
- // CLI flag name is unexpected behavior when default value is set.
315
- //
316
- // example: `auto-fixable-only` with `default: true` results in
317
- // $ eslint-todo --no-auto-fixable-only
318
- // because the default value is true, the flag is negated.
319
- // general options
320
- "cwd": {
321
- description: "Current working directory (default: .)",
322
- required: false,
323
- type: "string",
324
- valueHint: "path"
325
- },
326
- "todo-file": {
327
- alias: "f",
328
- description: "ESLint todo file name (default: .eslint-todo.js)",
329
- required: false,
330
- type: "string",
331
- valueHint: "filename"
332
- },
333
- // mode toggle
334
- "correct": {
335
- default: false,
336
- description: "Launch the correct mode (default: false)",
337
- required: false,
338
- type: "boolean"
339
- },
340
- // operation options
341
- "allow-partial-selection": {
342
- description: "Allow partial selection of violations. Only works with --correct. (default: false)",
343
- required: false,
344
- type: "boolean",
345
- valueHint: "boolean"
346
- },
347
- "auto-fixable-only": {
348
- description: "Only handle auto-fixable violations. (default: true)",
349
- required: false,
350
- type: "boolean",
351
- valueHint: "boolean"
352
- },
353
- "limit": {
354
- default: "100",
355
- description: "Limit the number of violations or files to fix. Only works with --correct. (default: 100)",
356
- required: false,
357
- type: "string",
358
- valueHint: "number"
359
- },
360
- "limit-type": {
361
- default: "violation",
362
- description: "Type of limit to apply. Only works with --correct. (default: violation)",
363
- required: false,
364
- type: "string",
365
- valueHint: "violation | file"
366
- },
367
- // logging
368
- "debug": {
369
- description: "Enable debug mode",
370
- required: false,
371
- type: "boolean"
372
- },
373
- "trace": {
374
- description: "Enable trace mode",
375
- required: false,
376
- type: "boolean"
377
- },
378
- "verbose": {
379
- description: "Enable verbose mode",
380
- required: false,
381
- type: "boolean"
382
- }
383
- },
384
- meta: {
385
- description: "Generate ESLint todo file and temporally suppress ESLint errors!",
386
- name: "@sushichan044/eslint-todo/cli",
387
- version: version
388
- },
389
- async run({ args }) {
390
- const cliCwd = process.cwd();
391
- const options = {
392
- cwd: args.cwd,
393
- todoFile: args["todo-file"]
394
- };
395
- const eslintTodoCore = new ESLintTodoCore(options);
396
- const context = resolveCLIContext({
397
- cwd: cliCwd,
398
- mode: {
399
- correct: args.correct
400
- },
401
- operation: {
402
- allowPartialSelection: args["allow-partial-selection"],
403
- autoFixableOnly: args["auto-fixable-only"],
404
- limit: args.limit,
405
- limitType: args["limit-type"]
406
- },
407
- todoFileAbsolutePath: eslintTodoCore.getTodoModulePath().absolute
408
- });
409
- await runAction(updateAction, { consola, options });
410
- if (context.mode === "generate") {
411
- await runAction(genAction, { consola, options });
412
- consola.success(`ESLint todo file generated at ${context.todoFilePath}!`);
413
- return;
414
- }
415
- if (context.mode === "correct") {
416
- const result = await runAction(
417
- selectRulesToFixAction,
418
- { consola, options },
419
- context.operation
420
- );
421
- if (!result.success) {
422
- consola.warn(
423
- "Couldn't find any rule to fix. Increase the limit and retry."
424
- );
425
- return;
426
- }
427
- await runAction(deleteRuleAction, { consola, options }, result.selection);
428
- if (result.selection.type === "full") {
429
- consola.success(
430
- `All violations of rule ${colorize(
431
- "magenta",
432
- result.selection.ruleId
433
- )} are deleted from the todo file and now ESLint will detect the violations.`
434
- );
435
- return;
436
- }
437
- if (result.selection.type === "partial") {
438
- const violationCount = Object.entries(
439
- result.selection.violations
440
- ).reduce((sum, [, count]) => sum + count, 0);
441
- consola.success(
442
- `${violationCount} violations of rule ${colorize(
443
- "magenta",
444
- result.selection.ruleId
445
- )} are deleted from the todo file and now ESLint will detect the violations.`
446
- );
447
- return;
448
- }
449
- const _exhaustiveCheck = result.selection;
450
- throw new Error(
451
- `Unknown selection type: ${JSON.stringify(_exhaustiveCheck)}`
452
- );
453
- }
454
- throw new Error(`Unknown mode: ${JSON.stringify(context.mode)}`);
455
- },
456
- setup({ args }) {
457
- consola.info(`eslint-todo CLI ${version}`);
458
- switch (true) {
459
- case args.debug: {
460
- consola.level = 4;
461
- break;
462
- }
463
- case args.trace: {
464
- consola.level = 5;
465
- break;
466
- }
467
- case args.verbose: {
468
- consola.level = 999;
469
- break;
470
- }
471
- }
472
- }
473
- });
474
- const run = async (argv) => {
475
- await runMain(cli, { rawArgs: argv });
476
- };
477
-
478
- export { run };
@@ -1,11 +0,0 @@
1
- import { Linter } from 'eslint';
2
- import { U as UserOptions } from '../shared/eslint-todo.BijUMnSZ.mjs';
3
-
4
- declare const eslintConfigTodo: (userOptions?: UserOptions) => Promise<Linter.Config[]>;
5
- /**
6
- * @deprecated
7
- * You should import this from default export.
8
- */
9
- declare const _old_eslintConfigTodo: (userOptions?: UserOptions) => Promise<Linter.Config[]>;
10
-
11
- export { eslintConfigTodo as default, _old_eslintConfigTodo as eslintConfigTodo };
@@ -1,11 +0,0 @@
1
- import { Linter } from 'eslint';
2
- import { U as UserOptions } from '../shared/eslint-todo.BijUMnSZ.js';
3
-
4
- declare const eslintConfigTodo: (userOptions?: UserOptions) => Promise<Linter.Config[]>;
5
- /**
6
- * @deprecated
7
- * You should import this from default export.
8
- */
9
- declare const _old_eslintConfigTodo: (userOptions?: UserOptions) => Promise<Linter.Config[]>;
10
-
11
- export { eslintConfigTodo as default, _old_eslintConfigTodo as eslintConfigTodo };
@@ -1,47 +0,0 @@
1
- import { E as ESLintTodoCore, T as TodoModuleV1Handler, a as TodoModuleV2Handler, b as buildESLintConfigForModule } from '../shared/eslint-todo.BShlgWEx.mjs';
2
- import 'eslint';
3
- import 'node:fs';
4
- import 'node:fs/promises';
5
- import 'pathe';
6
- import 'magicast';
7
- import 'es-toolkit/compat';
8
- import 'valibot';
9
- import 'defu';
10
- import 'node:process';
11
- import 'jiti';
12
-
13
- const eslintConfigTodo = async (userOptions = {}) => {
14
- const core = new ESLintTodoCore(userOptions);
15
- const todoModulePath = core.getTodoModulePath();
16
- const module = await (async () => {
17
- try {
18
- return await core._DO_NOT_USE_DIRECTLY_unsafeReadTodoModule();
19
- } catch {
20
- return null;
21
- }
22
- })();
23
- const configs = [
24
- {
25
- name: "@sushichan044/eslint-todo/setup"
26
- },
27
- {
28
- ignores: [todoModulePath.relative],
29
- name: "@sushichan044/eslint-todo/ignore"
30
- }
31
- ];
32
- if (module == null || !TodoModuleV1Handler.isVersion(module) && !TodoModuleV2Handler.isVersion(module)) {
33
- configs.push({
34
- files: [todoModulePath.relative],
35
- name: "@sushichan044/eslint-todo/warning/FILE_NOT_FOUND_OR_INVALID_TODO_FILE"
36
- });
37
- return configs;
38
- }
39
- const builtConfigs = buildESLintConfigForModule(module, "off");
40
- if (builtConfigs != null) {
41
- configs.push(...builtConfigs);
42
- }
43
- return configs;
44
- };
45
- const _old_eslintConfigTodo = eslintConfigTodo;
46
-
47
- export { eslintConfigTodo as default, _old_eslintConfigTodo as eslintConfigTodo };
package/dist/index.d.mts DELETED
@@ -1,3 +0,0 @@
1
- import 'eslint';
2
- import './shared/eslint-todo.BijUMnSZ.mjs';
3
- export { E as ESLintTodoCore } from './shared/eslint-todo.BR1uwV1v.mjs';
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import 'eslint';
2
- import './shared/eslint-todo.BijUMnSZ.js';
3
- export { E as ESLintTodoCore } from './shared/eslint-todo.DyfNwDMO.js';
package/dist/index.mjs DELETED
@@ -1,11 +0,0 @@
1
- import 'eslint';
2
- import 'node:fs';
3
- import 'node:fs/promises';
4
- import 'pathe';
5
- export { E as ESLintTodoCore } from './shared/eslint-todo.BShlgWEx.mjs';
6
- import 'magicast';
7
- import 'es-toolkit/compat';
8
- import 'valibot';
9
- import 'defu';
10
- import 'node:process';
11
- import 'jiti';
@@ -1,25 +0,0 @@
1
- import * as Comlink from 'comlink';
2
- import { RemoteESLintTodoCore } from './core.mjs';
3
- import '../shared/eslint-todo.BijUMnSZ.mjs';
4
- import '../shared/eslint-todo.BR1uwV1v.mjs';
5
- import 'eslint';
6
-
7
- type RemoteCore = {
8
- RemoteESLintTodoCore: Comlink.Remote<typeof RemoteESLintTodoCore>;
9
- terminate: () => Promise<number>;
10
- };
11
- /**
12
- * Launch a remote ESLintTodoCore worker with new process.
13
- *
14
- * @example
15
- * ```ts
16
- * const remote = launchRemoteESLintTodoCore();
17
- const remoteCore = await new remote.RemoteESLintTodoCore(options);
18
- const currentModule = await remoteCore.safeReadTodoModule();
19
-
20
- await remote.terminate();
21
- ```
22
- */
23
- declare const launchRemoteESLintTodoCore: () => RemoteCore;
24
-
25
- export { launchRemoteESLintTodoCore };
@@ -1,25 +0,0 @@
1
- import * as Comlink from 'comlink';
2
- import { RemoteESLintTodoCore } from './core.js';
3
- import '../shared/eslint-todo.BijUMnSZ.js';
4
- import '../shared/eslint-todo.DyfNwDMO.js';
5
- import 'eslint';
6
-
7
- type RemoteCore = {
8
- RemoteESLintTodoCore: Comlink.Remote<typeof RemoteESLintTodoCore>;
9
- terminate: () => Promise<number>;
10
- };
11
- /**
12
- * Launch a remote ESLintTodoCore worker with new process.
13
- *
14
- * @example
15
- * ```ts
16
- * const remote = launchRemoteESLintTodoCore();
17
- const remoteCore = await new remote.RemoteESLintTodoCore(options);
18
- const currentModule = await remoteCore.safeReadTodoModule();
19
-
20
- await remote.terminate();
21
- ```
22
- */
23
- declare const launchRemoteESLintTodoCore: () => RemoteCore;
24
-
25
- export { launchRemoteESLintTodoCore };