From 4cd6b94b041658c4392751bdcbfa0ec2acaecd53 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:14:46 +0000 Subject: [PATCH 1/6] Initial plan From 2c8b08a6a5955642e10b560c69e8c97db5b86bcf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:23:55 +0000 Subject: [PATCH 2/6] Migrate to ESLint 9 flat config format Co-authored-by: MishaKav <289035+MishaKav@users.noreply.github.com> --- eslint.config.js | 112 +++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 ++- 2 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 eslint.config.js diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 00000000..adf75edd --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,112 @@ +const eslint = require('@eslint/js') +const tseslint = require('typescript-eslint') +const jestPlugin = require('eslint-plugin-jest') +const githubPlugin = require('eslint-plugin-github') +const prettierPlugin = require('eslint-plugin-prettier') + +module.exports = tseslint.config( + // Ignore patterns + { + ignores: [ + '**/node_modules/**', + '**/dist/**', + '**/coverage/**', + '**/*.json' + ] + }, + + // Base ESLint recommended rules + eslint.configs.recommended, + + // TypeScript recommended configurations + ...tseslint.configs.recommended, + + // TypeScript type-checked rules + ...tseslint.configs.recommendedTypeChecked, + + // TypeScript files configuration + { + files: ['**/*.ts'], + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: __dirname + } + }, + plugins: { + jest: jestPlugin, + github: githubPlugin, + prettier: prettierPlugin + }, + rules: { + // ESLint core rules + 'camelcase': 'off', + 'no-console': 'off', + 'no-unused-vars': 'off', + 'semi': ['error', 'never'], + 'func-call-spacing': ['error', 'never'], + + // Prettier integration + 'prettier/prettier': 'error', + + // TypeScript custom rules + '@typescript-eslint/array-type': 'error', + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/ban-ts-comment': 'error', + '@typescript-eslint/consistent-type-assertions': 'error', + '@typescript-eslint/explicit-member-accessibility': [ + 'error', + { accessibility: 'no-public' } + ], + '@typescript-eslint/explicit-function-return-type': [ + 'error', + { allowExpressions: true } + ], + '@typescript-eslint/no-array-constructor': 'error', + '@typescript-eslint/no-empty-interface': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/no-extraneous-class': 'error', + '@typescript-eslint/no-for-in-array': 'error', + '@typescript-eslint/no-inferrable-types': 'error', + '@typescript-eslint/no-misused-new': 'error', + '@typescript-eslint/no-namespace': 'error', + '@typescript-eslint/no-non-null-assertion': 'warn', + '@typescript-eslint/no-require-imports': 'error', + '@typescript-eslint/no-unnecessary-qualifier': 'error', + '@typescript-eslint/no-unnecessary-type-assertion': 'error', + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-useless-constructor': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/prefer-for-of': 'warn', + '@typescript-eslint/prefer-function-type': 'warn', + '@typescript-eslint/prefer-includes': 'error', + '@typescript-eslint/prefer-string-starts-ends-with': 'error', + '@typescript-eslint/promise-function-async': 'error', + '@typescript-eslint/require-array-sort-compare': 'error', + '@typescript-eslint/restrict-plus-operands': 'error', + '@typescript-eslint/space-before-function-paren': 'off', + '@typescript-eslint/unbound-method': 'error', + + // GitHub plugin rules + 'eslint-comments/no-use': 'off', + 'eslint-comments/no-unused-disable': 'off', + 'i18n-text/no-en': 'off', + 'import/no-namespace': 'off', + + // Jest plugin rules + ...jestPlugin.configs.recommended.rules + } + }, + + // JavaScript files configuration + { + files: ['**/*.js'], + ...tseslint.configs.disableTypeChecked, + rules: { + // Disable TypeScript-specific rules for JavaScript files + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/explicit-member-accessibility': 'off' + } + } +) diff --git a/package.json b/package.json index 512204bc..88f686e3 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "bundle": "npm run format:write && npm run package", "format:write": "prettier --write .", "format:check": "prettier --check .", - "lint": "eslint . -c ./.github/linters/.eslintrc.yml", + "lint": "eslint .", "package": "ncc build --minify src/index.ts -o dist --license licenses.txt", "test": "jest", "all": "npm run format:write && npm run lint && npm run test && npm run package", @@ -56,7 +56,8 @@ "prettier": "^3.6.2", "prettier-eslint": "^16.4.2", "ts-jest": "^29.4.5", - "typescript": "^5.9.3" + "typescript": "^5.9.3", + "typescript-eslint": "^8.46.3" }, "jest": { "preset": "ts-jest", From 5dad4d788d677555a8301cfa0159a18e50acc8bc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:28:51 +0000 Subject: [PATCH 3/6] Simplify ESLint 9 config - remove type-checked rules Co-authored-by: MishaKav <289035+MishaKav@users.noreply.github.com> --- eslint.config.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index adf75edd..b357e5b5 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -21,9 +21,6 @@ module.exports = tseslint.config( // TypeScript recommended configurations ...tseslint.configs.recommended, - // TypeScript type-checked rules - ...tseslint.configs.recommendedTypeChecked, - // TypeScript files configuration { files: ['**/*.ts'], From 59b836e0af18849fafc45da4ddeaa3675ebcbfa8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:32:24 +0000 Subject: [PATCH 4/6] Remove legacy .eslintrc.yml file Co-authored-by: MishaKav <289035+MishaKav@users.noreply.github.com> --- .github/linters/.eslintrc.yml | 106 ---------------------------------- 1 file changed, 106 deletions(-) delete mode 100644 .github/linters/.eslintrc.yml diff --git a/.github/linters/.eslintrc.yml b/.github/linters/.eslintrc.yml deleted file mode 100644 index 36a4d2d3..00000000 --- a/.github/linters/.eslintrc.yml +++ /dev/null @@ -1,106 +0,0 @@ -env: - node: true - es6: true - jest: true - -globals: - Atomics: readonly - SharedArrayBuffer: readonly - -ignorePatterns: - - '!.*' - - '**/node_modules/.*' - - '**/dist/.*' - - '**/coverage/.*' - - '*.json' - -parser: '@typescript-eslint/parser' - -parserOptions: - ecmaVersion: 2023 - sourceType: module - project: - - './.github/linters/tsconfig.json' - - './tsconfig.json' - -plugins: - - jest - - github - - '@typescript-eslint' - -extends: - - eslint:recommended - - plugin:@typescript-eslint/eslint-recommended - - plugin:@typescript-eslint/recommended - - plugin:github/recommended - - plugin:jest/recommended - -rules: { - 'camelcase': 'off', - 'eslint-comments/no-use': 'off', - 'eslint-comments/no-unused-disable': 'off', - 'i18n-text/no-en': 'off', - 'import/no-namespace': 'off', - 'no-console': 'off', - 'no-unused-vars': 'off', - 'prettier/prettier': 'error', - 'semi': ['error', 'never'], - '@typescript-eslint/array-type': 'error', - '@typescript-eslint/await-thenable': 'error', - '@typescript-eslint/ban-ts-comment': 'error', - '@typescript-eslint/consistent-type-assertions': 'error', - '@typescript-eslint/explicit-member-accessibility': - ['error', { 'accessibility': 'no-public' }], - '@typescript-eslint/explicit-function-return-type': - ['error', { 'allowExpressions': true }], - # Use ESLint's built-in rules for formatting instead of deprecated TS-ESLint rules - 'func-call-spacing': ['error', 'never'], - '@typescript-eslint/no-array-constructor': 'error', - '@typescript-eslint/no-empty-interface': 'error', - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-extraneous-class': 'error', - '@typescript-eslint/no-for-in-array': 'error', - '@typescript-eslint/no-inferrable-types': 'error', - '@typescript-eslint/no-misused-new': 'error', - '@typescript-eslint/no-namespace': 'error', - '@typescript-eslint/no-non-null-assertion': 'warn', - '@typescript-eslint/no-require-imports': 'error', - '@typescript-eslint/no-unnecessary-qualifier': 'error', - '@typescript-eslint/no-unnecessary-type-assertion': 'error', - '@typescript-eslint/no-unused-vars': 'error', - '@typescript-eslint/no-useless-constructor': 'error', - '@typescript-eslint/no-var-requires': 'error', - '@typescript-eslint/prefer-for-of': 'warn', - '@typescript-eslint/prefer-function-type': 'warn', - '@typescript-eslint/prefer-includes': 'error', - '@typescript-eslint/prefer-string-starts-ends-with': 'error', - '@typescript-eslint/promise-function-async': 'error', - '@typescript-eslint/require-array-sort-compare': 'error', - '@typescript-eslint/restrict-plus-operands': 'error', - '@typescript-eslint/space-before-function-paren': 'off', - '@typescript-eslint/unbound-method': 'error' - } - -overrides: - - files: ['**/*.js'] - parser: 'espree' - parserOptions: - ecmaVersion: 2023 - sourceType: 'module' - # Clear TypeScript project references for JavaScript files - project: null - rules: - # Disable TypeScript-specific rules for JavaScript files - '@typescript-eslint/explicit-function-return-type': 'off' - '@typescript-eslint/no-explicit-any': 'off' - '@typescript-eslint/explicit-member-accessibility': 'off' - '@typescript-eslint/await-thenable': 'off' - '@typescript-eslint/no-for-in-array': 'off' - '@typescript-eslint/no-unnecessary-qualifier': 'off' - '@typescript-eslint/no-unnecessary-type-assertion': 'off' - '@typescript-eslint/prefer-includes': 'off' - '@typescript-eslint/prefer-string-starts-ends-with': 'off' - '@typescript-eslint/promise-function-async': 'off' - '@typescript-eslint/require-array-sort-compare': 'off' - '@typescript-eslint/restrict-plus-operands': 'off' - '@typescript-eslint/unbound-method': 'off' From 8ec81985d732834cc0db8c4d54d620b108e598dd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:50:10 +0000 Subject: [PATCH 5/6] Add ESLint compat utilities for legacy plugins Co-authored-by: MishaKav <289035+MishaKav@users.noreply.github.com> --- eslint.config.js | 3 ++- package.json | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/eslint.config.js b/eslint.config.js index b357e5b5..3e55dad1 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -3,6 +3,7 @@ const tseslint = require('typescript-eslint') const jestPlugin = require('eslint-plugin-jest') const githubPlugin = require('eslint-plugin-github') const prettierPlugin = require('eslint-plugin-prettier') +const { fixupPluginRules } = require('@eslint/compat') module.exports = tseslint.config( // Ignore patterns @@ -32,7 +33,7 @@ module.exports = tseslint.config( }, plugins: { jest: jestPlugin, - github: githubPlugin, + github: fixupPluginRules(githubPlugin), prettier: prettierPlugin }, rules: { diff --git a/package.json b/package.json index 88f686e3..5ccecf83 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,8 @@ "@linearb/gitstream-core": "2.1.215" }, "devDependencies": { + "@eslint/compat": "^1.2.3", + "@eslint/js": "^9.39.1", "@jest/globals": "^30.2.0", "@types/jest": "^30.0.0", "@types/node": "^24.10.0", From 38e8da729269592d2fe71ae800a9c3917bed0bc3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:52:12 +0000 Subject: [PATCH 6/6] Fix Jest globals and clean up duplicate languageOptions Co-authored-by: MishaKav <289035+MishaKav@users.noreply.github.com> --- eslint.config.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/eslint.config.js b/eslint.config.js index 3e55dad1..3ad1e6ad 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -29,6 +29,9 @@ module.exports = tseslint.config( parserOptions: { projectService: true, tsconfigRootDir: __dirname + }, + globals: { + ...jestPlugin.environments.globals.globals } }, plugins: { @@ -92,7 +95,11 @@ module.exports = tseslint.config( 'import/no-namespace': 'off', // Jest plugin rules - ...jestPlugin.configs.recommended.rules + 'jest/no-disabled-tests': 'warn', + 'jest/no-focused-tests': 'error', + 'jest/no-identical-title': 'error', + 'jest/prefer-to-have-length': 'warn', + 'jest/valid-expect': 'error' } },