Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly upgrades Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces comprehensive support for JavaScript-based configuration files (rslint.config.{ts|mts|js|mjs}), aligning with ESLint's flat config style. The changes involve significant refactoring on both the Go and JavaScript sides to handle config loading, merging, and rule resolution. The Go binary now accepts configuration via stdin, enabling the JavaScript frontend to preprocess and serialize config files. The cmd/rslint package has been updated to include a new --config-stdin flag and logic to parse the incoming JSON payload. The internal/config package sees major architectural changes with the introduction of MergedConfig, GetConfigForFile, and refined rule resolution helpers (GetPluginRules, GetCoreRules), replacing older, less flexible methods. The ParserOptions.ProjectService field has been updated to use a pointer to a boolean (*bool) to correctly distinguish between unset and explicitly false values, which is a good practice for optional boolean fields in Go structs that are unmarshaled from JSON. New test files (internal/config/init_test.go and internal/config/merge_test.go) have been added to thoroughly cover the new initialization and config merging logic, which is excellent for maintaining code quality. Additionally, the packages/rslint directory now includes the necessary JavaScript files (cli.ts, config-loader.ts, define-config.ts, and preset configs) to implement the client-side config loading and interaction with the Go binary. The deprecation warning for rslint.json/jsonc files is a thoughtful addition for user migration. Overall, the changes are well-structured, thoroughly tested, and effectively implement the new feature as described in the pull request.
49cd3ae to
2b98a70
Compare
4ec13ee to
7d4e998
Compare
ced00b7 to
571fbbd
Compare
571fbbd to
e0baba6
Compare
Summary
Add support for
rslint.config.{ts|mts|js|mjs}using ESLint flat config style.rslint.json/jsoncremains backward-compatible but deprecated.Usage
Quick start
# Generate a default JS config in the current directory npx rslint --initThis creates a config file with a recommended preset. The file extension depends on the project setup (following the ESLint convention):
tsconfig.json→rslint.config.ts"type": "module"inpackage.json→rslint.config.js(ESM syntax)rslint.config.mjs(ESM syntax,.mjsensures Node treats it as ESM)Available presets
js.configs.recommendedeslint:recommended(JS files only)ts.configs.recommended@typescript-eslint/recommended+ eslint:recommended override layer (TS files only)reactPlugin.configs.recommendedeslint-plugin-reactrecommended (JSX/TSX files)importPlugin.configs.recommendedeslint-plugin-importrecommendedEach preset lists all official rules — implemented ones are active, unimplemented ones are commented out for visibility.
Config file priority
rslint.config.js>.mjs>.ts>.mts>rslint.json>rslint.jsoncUse
--config <path>to specify a custom config file path.TypeScript config files
.ts/.mtsconfig files are supported via:import()on Node.js ≥ 22.6 (detected viaprocess.features.typescript)jitifallback (install as dev dependency:npm install -D jiti)Architecture
JS handles config loading, Go handles rule execution — both share identical rule resolution logic.
--config-stdinnormalizeJSONConfiginjects core/plugin rules at load time, soGetConfigForFileprocesses both config types identicallyConfig merging (ESLint flat config semantics)
rules/settings: shallow merge, later entries overridelanguageOptions: deep merge (parserOptionsfields merged independently;ProjectServiceuses*boolto distinguish unset from explicit false)ignoresacts as a global ignoreGetConfigForFilereturns nil)Monorepo per-file config resolution (LSP)
VS Code extension discovers all
rslint.config.{js,mjs,ts,mts}files in the workspace viaworkspace.findFilesand sends the full set to the LSP server viarslint/configUpdatenotification. Config files are loaded in parallel viaPromise.allSettled— a broken config in one sub-package does not prevent other configs from loading. Config keys use URI strings (file:///...) throughout, matching LSP protocol convention — this eliminates cross-platform path separator issues by design. Therslint/configUpdatehandler is registered as a blocking method to ensure config updates are serialized on the dispatch loop, preventing data races with concurrent diagnostics.When linting a file,
getConfigForURIwalks up the URI hierarchy from the file's directory to find the nearest JS/TS config (ESLint v10 flat config behavior), returning both the config entries and the config's own directory ascwdfor glob matching. This ensures monorepo sub-package patterns likefiles: ['src/**/*.ts']resolve relative to the sub-package root, not the workspace root. If no JS config matches, it falls back to the JSON config withs.cwd(workspace root) ascwd.uriToPathcorrectly handles Windows drive letter URIs (file:///C:/Users/...→C:/Users/...) to ensure the returnedcwduses a DOS root consistent withos.Getwd(), avoiding root-type mismatches intspath.ConvertToRelativePath.The
handleConfigUpdatehandler distinguishes nil payloads (malformed — preserves existing configs) from explicitly empty configs arrays (legitimate "all configs deleted" — clears state).CLI error handling
loadConfigFileandnormalizeConfigfailures are caught independently with user-friendly error messages (e.g.,"Error: failed to load config ...","Error: invalid config ..."), rather than exposing raw stack traces.Pure JS project support
parserOptions.projectis specified, auto-detecttsconfig.jsonin cwdallowJs: truefor JS-only projectsparserOptions.project(session discovers tsconfig files independently via projectService)Config export structure
Config presets are exported as named exports from the main entry point:
TS config loading strategy
import()(Node 22.6+, detected viaprocess.features.typescript), fall back to jiti (optional peer dep)jitiis initialized withpath.dirname(configPath)as base to ensure relative imports in config files resolve correctlyScope of Changes
--config-stdinflag with 50MB size guard, unifiedGetConfigForFile(filePath, cwd)merge logic with explicit config directory,normalizeJSONConfigfor JSON default rules,--initgenerates.js/.mjsbased onpackage.json"type"field (ESLint convention), deprecation warning for JSON config, pure JS project tsconfig fallback,isFileMatched/isFileIgnoredtakecwdparameter,RegisterAllRuleswrapped withsync.Onceto fix concurrent map writes,textDocument/codeActionadded to blocking methods to prevent data race ons.diagnosticscli.ts(config discovery +node:utilparseArgs with--config=valueand--separator support + stdin pipe + user-friendly error handling for config load/validation failures),config-loader.ts(load/normalize withfiles/ignorestype validation, jiti uses config file directory as base),define-config.ts, preset configs (ts.configs.recommended,js.configs.recommended,reactPlugin.configs.recommended,importPlugin.configs.recommended) aligned with official eslint/typescript-eslint presets (added missingno-withoff in TS overrides, commented unimplemented rules:no-new-symbol,no-unassigned-vars,preserve-caught-error)handleConfigUpdatenotification handler with multi-config support (URI-keyedjsConfigsmap), registered as blocking method for concurrency safety, nil vs empty payload guard,getConfigForURIreturns(config, cwd)tuple — walks URI hierarchy for nearest config and returns per-config directory as cwd for correct glob matching,uriToPathhandles Windows drive letter URIs (file:///C:/...→C:/...),uriDirnamehelper for platform-independent URI manipulation,reloadConfigno longer validates tsConfigs (session handles discovery), clears JSON config path to prevent watcher overrideloadAndSendConfigdiscovers all JS configs viaworkspace.findFiles, loads in parallel viaPromise.allSettled(one broken config doesn't block others), sends as URI-keyed array, ESM cache busting for hot reload (.js/.mjsdirectly,.ts/.mtswith native import fallback to jiti),configWatcherfor**/rslint.config.{ts,mts,js,mjs}handleConfigUpdateincluding malformed/nil payload tests,getConfigForURIwith monorepo multi-package (4 packages), 3-level nesting, Windows URI + cwd assertion,uriToPathcross-platform (Unix/Windows drive letter/UNC/edge cases),uriDirnameedge cases,isFileIgnored/isFileMatchedwith cwd parameter,GetConfigForFilecwd-based matching and ignores including Windows paths (forward-slash cwd, backslash cwd, monorepo sub-package),--initwith type:module/.mjs/.ts variants,reloadConfigaccepts config without tsconfigs,isBlockingMethodunit test (includingcodeAction) + dispatch loop serialization test forrslint/configUpdate,RegisterAllRulesconcurrent safety test with-racenormalizeConfigvalidation,loadConfigFilewith Promise export,defineConfigidentity check, config presets importability and structure--configflag (equals/space format), flag passthrough (--fix/--quiet/--format),--initgeneration (.ts/esm .js/non-esm .mjs/no-pkg .mjs), JS-over-JSON priority, global ignores, rules off,src/**/*.tspattern matching with correct cwd, user-friendly error for syntax errors and non-array configssrc/**/*.tspattern, sub-package config change, sub-package config deletion fallback, root config change, broken config resilience — valid configs still work alongside broken sibling, broken package falls back to root, corrupted config at runtime doesn't break other configs, dynamic sub-package config creation with fallback on delete, root config deletion isolation — sub-packages with own config unaffected), no-config fallback, full config lifecycle (no config → JSON created → JS override → JS deleted → JSON restored → JSON deleted)Known Limitations
rslint/configUpdatenotification)js.configs.recommendedfor pure JS projects generates a temporary tsconfig; users with complex setups should provide their ownChecklist