Repository: un-ts/eslint-import-context
Pull request #2: feat: first blood, should just work
Author: login: JounQin
Labels: name: feature
description: New feature
Created: 2025-05-24T15:31:40Z | Merged: 2025-05-24T15:57:41Z


<!-- ELLIPSIS_HIDDEN -->


> [!IMPORTANT]
> Introduces ESLint context management utilities, rebrands project, updates CI, and adds tests.
> 
>   - **New Features**:
>     - Added `setRuleContext` and `useRuleContext` in `src/index.ts` for ESLint rule context management.
>     - Introduced `getTsconfigWithContext` in `src/utils.ts` to resolve TypeScript configurations.
>   - **Refactor**:
>     - Rebranded project from "lib-boilerplate" to "eslint-import-context" in `package.json`, `README.md`, and `vercel.json`.
>   - **CI/CD**:
>     - Updated Node.js versions in `ci.yml` to include version 24.
>     - Modified `pkg-pr-new.yml` to adjust publishing commands.
>   - **Tests**:
>     - Added `context.spec.ts` and `utils.spec.ts` for testing context management and TypeScript config resolution.
>   - **Documentation**:
>     - Updated `README.md` to reflect new project name and usage instructions.
> 
> <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=un-ts%2Feslint-import-context&utm_source=github&utm_medium=referral)<sup> for 229c0912e8b2bbaebc9d5ff743139d4d4a3d0f3a. You can [customize](https://app.ellipsis.dev/un-ts/settings/summaries) this summary. It will automatically update as commits are pushed.</sup>

----


<!-- ELLIPSIS_HIDDEN -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced context management utilities for ESLint rule development, including functions to set and retrieve rule context.
  - Added utility to resolve and cache TypeScript configuration files (`tsconfig.json`) based on ESLint context.

- **Bug Fixes**
  - None.

- **Documentation**
  - Updated README and project references to reflect the new project name "eslint-import-context".
  - Simplified the changelog.

- **Refactor**
  - Rebranded the project from "lib-boilerplate" to "eslint-import-context" across all configuration and metadata files.

- **Tests**
  - Added tests for context management and TypeScript configuration resolution.
  - Introduced new test utilities and fixtures.

- **Chores**
  - Updated CI workflows to support Node.js 24 and adjusted publishing commands.
  - Increased size-limit threshold and updated monitored files.
  - Updated aliases and configuration for build and deployment tools.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/.changeset/config.json b/.changeset/config.json
index 50ee5ae..8213a43 100644
--- a/.changeset/config.json
+++ b/.changeset/config.json
@@ -3,7 +3,7 @@
   "changelog": [
     "@changesets/changelog-github",
     {
-      "repo": "un-ts/lib-boilerplate"
+      "repo": "un-ts/eslint-import-context"
     }
   ],
   "commit": false,
diff --git a/.changeset/yellow-ducks-fold.md b/.changeset/yellow-ducks-fold.md
new file mode 100644
index 0000000..4954c73
--- /dev/null
+++ b/.changeset/yellow-ducks-fold.md
@@ -0,0 +1,5 @@
+---
+"eslint-import-context": minor
+---
+
+feat: first blood, should just work
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 771fb38..c546c8f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -17,6 +17,7 @@ jobs:
           - 18
           - 20
           - 22
+          - 24
         os:
           - macos-latest
           - windows-latest
diff --git a/.github/workflows/pkg-pr-new.yml b/.github/workflows/pkg-pr-new.yml
index f615b16..b3e4974 100644
--- a/.github/workflows/pkg-pr-new.yml
+++ b/.github/workflows/pkg-pr-new.yml
@@ -28,4 +28,4 @@ jobs:
         run: yarn build
 
       - name: Publish
-        run: yarn dlx pkg-pr-new publish --compact
+        run: yarn dlx pkg-pr-new publish # --compact
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index f1deaed..4a0f11f 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -37,8 +37,8 @@ jobs:
       - name: Create Release Pull Request or Publish to npm
         uses: changesets/action@v1
         with:
-          commit: 'chore: release lib-boilerplate'
-          title: 'chore: release lib-boilerplate'
+          commit: 'chore: release eslint-import-context'
+          title: 'chore: release eslint-import-context'
           version: yarn run version
           publish: yarn release
         env:
diff --git a/.size-limit.json b/.size-limit.json
index f45325b..e6595dc 100644
--- a/.size-limit.json
+++ b/.size-limit.json
@@ -1,6 +1,6 @@
 [
   {
-    "path": "./lib/index.js",
-    "limit": "50B"
+    "path": "./src/index.ts",
+    "limit": "200B"
   }
 ]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7911edc..420e6f2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1 @@
 # Change Log
-
-## 0.0.1
-
-### Patch Changes
-
-- [#83](https://github.com/un-ts/lib-boilerplate/pull/83) [`34771e4`](https://github.com/un-ts/lib-boilerplate/commit/34771e46fbf5de4c0448d5e9017c10704aef9cd1) Thanks [@JounQin](https://github.com/JounQin)! - chore: migrate to premove and tsdown
diff --git a/README.md b/README.md
index 83c65ef..c7afb78 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@
-# lib-boilerplate
+# eslint-import-context
 
-[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/un-ts/lib-boilerplate/ci.yml?branch=main)](https://github.com/un-ts/lib-boilerplate/actions/workflows/ci.yml?query=branch%3Amain)
-[![Codecov](https://img.shields.io/codecov/c/github/un-ts/lib-boilerplate.svg)](https://codecov.io/gh/un-ts/lib-boilerplate)
-[![type-coverage](https://img.shields.io/badge/dynamic/json.svg?label=type-coverage&prefix=%E2%89%A5&suffix=%&query=$.typeCoverage.atLeast&uri=https%3A%2F%2Fraw.githubusercontent.com%2Fun-ts%2Flib-boilerplate%2Fmain%2Fpackage.json)](https://github.com/plantain-00/type-coverage)
-[![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/un-ts/lib-boilerplate)](https://coderabbit.ai)
-[![npm](https://img.shields.io/npm/v/lib-boilerplate.svg)](https://www.npmjs.com/package/lib-boilerplate)
-[![GitHub Release](https://img.shields.io/github/release/un-ts/lib-boilerplate)](https://github.com/un-ts/lib-boilerplate/releases)
+[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/un-ts/eslint-import-context/ci.yml?branch=main)](https://github.com/un-ts/eslint-import-context/actions/workflows/ci.yml?query=branch%3Amain)
+[![Codecov](https://img.shields.io/codecov/c/github/un-ts/eslint-import-context.svg)](https://codecov.io/gh/un-ts/eslint-import-context)
+[![type-coverage](https://img.shields.io/badge/dynamic/json.svg?label=type-coverage&prefix=%E2%89%A5&suffix=%&query=$.typeCoverage.atLeast&uri=https%3A%2F%2Fraw.githubusercontent.com%2Fun-ts%2Feslint-import-context%2Fmain%2Fpackage.json)](https://github.com/plantain-00/type-coverage)
+[![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/un-ts/eslint-import-context)](https://coderabbit.ai)
+[![npm](https://img.shields.io/npm/v/eslint-import-context.svg)](https://www.npmjs.com/package/eslint-import-context)
+[![GitHub Release](https://img.shields.io/github/release/un-ts/eslint-import-context)](https://github.com/un-ts/eslint-import-context/releases)
 
 [![Conventional Commits](https://img.shields.io/badge/conventional%20commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
 [![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com)
@@ -32,24 +32,26 @@ A simple library boilerplate.
 
 ```sh
 # pnpm
-pnpm add lib-boilerplate
+pnpm add eslint-import-context
 
 # yarn
-yarn add lib-boilerplate
+yarn add eslint-import-context
 
 # npm
-npm i lib-boilerplate
+npm i eslint-import-context
 
 # bun
-bun add lib-boilerplate
+bun add eslint-import-context
 ```
 
 ### API
 
 ```js
-import echo from 'lib-boilerplate'
+import { useRuleContext, getTsconfigWithContext } from 'eslint-import-context'
 
-echo()
+const ruleContext = useRuleContext()
+
+const tsconfig = getTsconfigWithContext(ruleContext)
 ```
 
 ## Sponsors and Backers
diff --git a/package.json b/package.json
index c80d984..c7fa7d3 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
 {
-  "name": "lib-boilerplate",
+  "name": "eslint-import-context",
   "version": "0.0.0",
   "type": "module",
-  "description": "A simple library boilerplate.",
-  "repository": "git+https://github.com/un-ts/lib-boilerplate.git",
+  "description": "Provide context info for eslint-plugin-import-x, so no extra arguments need to be added.",
+  "repository": "git+https://github.com/un-ts/eslint-import-context.git",
   "author": "JounQin <admin@1stg.me> (https://www.1stG.me)",
-  "funding": "https://opencollective.com/unts",
+  "funding": "https://opencollective.com/eslint-import-context",
   "license": "MIT",
   "packageManager": "yarn@4.9.1",
   "engines": {
@@ -62,7 +62,6 @@
     "@eslint-react/eslint-plugin": "^1.49.0",
     "@mdx-js/rollup": "^3.1.0",
     "@shikijs/rehype": "^3.4.2",
-    "@size-limit/preset-small-lib": "^11.2.0",
     "@types/mdx": "^2.0.13",
     "@types/node": "^22.15.21",
     "@types/react": "^19.1.5",
@@ -87,6 +86,7 @@
     "remark-gfm": "^4.0.1",
     "simple-git-hooks": "^2.13.0",
     "size-limit": "^11.2.0",
+    "size-limit-preset-node-lib": "^0.4.0",
     "stylelint": "^16.19.1",
     "tsdown": "^0.12.2",
     "type-coverage": "^2.29.7",
diff --git a/src/index.ts b/src/index.ts
index 13ae205..79faf83 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,3 +1,19 @@
-export default function echo() {
-  return 'Hello World!'
+import type { ChildContext, RuleContext } from './types.js'
+
+export type * from './types.js'
+export * from './utils.js'
+
+let ruleContext: ChildContext | RuleContext | undefined
+
+export const setRuleContext = <T = void>(
+  nextRuleContext: ChildContext | RuleContext,
+  callback: () => T,
+) => {
+  const currentValue = ruleContext
+  ruleContext = nextRuleContext
+  const result = callback()
+  ruleContext = currentValue
+  return result
 }
+
+export const useRuleContext = () => ruleContext
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 0000000..b73e2a2
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,158 @@
+import type { TSESLint } from '@typescript-eslint/utils'
+import type { KebabCase, LiteralUnion } from 'type-fest'
+import type { NapiResolveOptions } from 'unrs-resolver'
+
+import type { PluginName } from './utils.js'
+
+export type FileExtension = `.${string}`
+
+export type DocStyle = 'jsdoc' | 'tomdoc'
+
+export interface ResultNotFound {
+  found: false
+  // eslint-disable-next-line sonarjs/no-redundant-optional
+  path?: undefined
+}
+
+export interface ResultFound {
+  found: true
+  path: string | null
+}
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export type NewResolverResolve = (
+  modulePath: string,
+  sourceFile: string,
+) => ResolvedResult
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export interface NewResolver {
+  interfaceVersion: 3
+  /** Optional name for the resolver, this is used in logs/debug output */
+  name?: string
+  resolve: NewResolverResolve
+}
+
+export type Resolver = LegacyResolver | NewResolver
+
+export type ResolvedResult = ResultFound | ResultNotFound
+
+export interface NodeResolverOptions {
+  extensions?: readonly string[]
+  moduleDirectory?: string[]
+  paths?: string[]
+}
+
+export interface WebpackResolverOptions {
+  config?: string | { resolve: NapiResolveOptions }
+  'config-index'?: number
+  env?: Record<string, unknown>
+  argv?: Record<string, unknown>
+}
+
+export interface TsResolverOptions extends NapiResolveOptions {
+  alwaysTryTypes?: boolean
+  project?: string[] | string
+  extensions?: string[]
+}
+
+export type LegacyResolverName = LiteralUnion<
+  'node' | 'typescript' | 'webpack',
+  string
+>
+
+export type LegacyResolverResolveImport<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => string | undefined
+
+export type LegacyResolverResolve<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => ResolvedResult
+
+export interface LegacyResolver<T = unknown, U = T> {
+  interfaceVersion?: 1 | 2
+  resolve: LegacyResolverResolve<T>
+  resolveImport: LegacyResolverResolveImport<U>
+}
+
+export interface LegacyResolverObject {
+  // node, typescript, webpack...
+  name: LegacyResolverName
+
+  // Enabled by default
+  enable?: boolean
+
+  // Options passed to the resolver
+  options?:
+    | NodeResolverOptions
+    | TsResolverOptions
+    | WebpackResolverOptions
+    // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+    | {}
+
+  // Any object satisfied Resolver type
+  resolver: LegacyResolver
+}
+
+export interface LegacyResolverRecord {
+  [resolve: string]: unknown
+  node?: NodeResolverOptions | boolean
+  typescript?: TsResolverOptions | boolean
+  webpack?: WebpackResolverOptions
+}
+
+export type LegacyImportResolver =
+  | LegacyResolverName
+  | LegacyResolverName[]
+  | LegacyResolverObject
+  | LegacyResolverObject[]
+  | LegacyResolverRecord
+  | LegacyResolverRecord[]
+
+export interface ImportSettings {
+  cache?: {
+    lifetime?: number | '∞' | 'Infinity'
+  }
+  coreModules?: string[]
+  docstyle?: DocStyle[]
+  extensions?: readonly FileExtension[]
+  externalModuleFolders?: string[]
+  ignore?: string[]
+  internalRegex?: string
+  parsers?: Record<string, readonly FileExtension[]>
+  resolve?: NodeResolverOptions
+  resolver?: LegacyImportResolver
+  'resolver-legacy'?: LegacyImportResolver
+  'resolver-next'?: NewResolver | NewResolver[]
+}
+
+export type WithPluginName<T extends object | string> = T extends string
+  ? `${PluginName}/${KebabCase<T>}`
+  : {
+      [K in keyof T as WithPluginName<`${KebabCase<K & string>}`>]: T[K]
+    }
+
+export type PluginSettings = WithPluginName<ImportSettings>
+
+export interface RuleContext<
+  TMessageIds extends string = string,
+  TOptions extends readonly unknown[] = readonly unknown[],
+> extends Omit<TSESLint.RuleContext<TMessageIds, TOptions>, 'settings'> {
+  settings: PluginSettings
+}
+
+export interface ChildContext {
+  cacheKey: string
+  settings: PluginSettings
+  parserPath?: string | null
+  parserOptions?: TSESLint.ParserOptions
+  languageOptions?: TSESLint.FlatConfig.LanguageOptions
+  path: string
+  cwd: string
+  filename: string
+  physicalFilename: string
+}
diff --git a/src/utils.ts b/src/utils.ts
new file mode 100644
index 0000000..3f18c85
--- /dev/null
+++ b/src/utils.ts
@@ -0,0 +1,51 @@
+import path from 'node:path'
+
+import { getTsconfig } from 'get-tsconfig'
+import type { TsConfigJsonResolved, TsConfigResult } from 'get-tsconfig'
+import { stableHash } from 'stable-hash'
+
+import type { ChildContext, RuleContext } from './types.js'
+
+export const pluginName = 'import-x'
+
+export type PluginName = typeof pluginName
+
+const tsconfigCache = new Map<string, TsConfigJsonResolved | null | undefined>()
+
+// eslint-disable-next-line sonarjs/cognitive-complexity
+export function getTsconfigWithContext(context: ChildContext | RuleContext) {
+  const parserOptions =
+    context.languageOptions?.parserOptions || context.parserOptions
+  let tsconfigRootDir = parserOptions?.tsconfigRootDir
+  const project = parserOptions?.project
+  const cacheKey = stableHash([tsconfigRootDir, project])
+  let tsconfig: TsConfigJsonResolved | null | undefined
+  if (tsconfigCache.has(cacheKey)) {
+    tsconfig = tsconfigCache.get(cacheKey)
+  } else {
+    tsconfigRootDir =
+      tsconfigRootDir ||
+      // eslint-disable-line sonarjs/todo-tag -- TODO: uncomment in next major
+      // || context.cwd
+      process.cwd()
+    let tsconfigResult: TsConfigResult | null | undefined
+    if (project) {
+      const projects = Array.isArray(project) ? project : [project]
+      for (const project of projects) {
+        tsconfigResult = getTsconfig(
+          project === true
+            ? context.physicalFilename
+            : path.resolve(tsconfigRootDir, project),
+        )
+        if (tsconfigResult) {
+          break
+        }
+      }
+    } else {
+      tsconfigResult = getTsconfig(tsconfigRootDir)
+    }
+    tsconfig = tsconfigResult?.config
+    tsconfigCache.set(cacheKey, tsconfig)
+  }
+  return tsconfig
+}
diff --git a/test/basic.spec.ts b/test/basic.spec.ts
deleted file mode 100644
index 482d0dc..0000000
--- a/test/basic.spec.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import echo from 'lib-boilerplate'
-
-test('it should just work', () => {
-  expect(echo()).toBe('Hello World!')
-})
diff --git a/test/context.spec.ts b/test/context.spec.ts
new file mode 100644
index 0000000..bd944dd
--- /dev/null
+++ b/test/context.spec.ts
@@ -0,0 +1,17 @@
+import { testContext } from './utils.js'
+
+import { setRuleContext, useRuleContext } from 'eslint-import-context'
+
+describe('context', () => {
+  it('should just work', () => {
+    expect(useRuleContext()).toBeUndefined()
+
+    const context = testContext()
+    const result = setRuleContext(context, () => {
+      expect(useRuleContext()).toBe(context)
+      return 'test'
+    })
+    expect(result).toBe('test')
+    expect(useRuleContext()).toBeUndefined()
+  })
+})
diff --git a/test/fixtures/tsconfig.json b/test/fixtures/tsconfig.json
new file mode 100644
index 0000000..898bb8b
--- /dev/null
+++ b/test/fixtures/tsconfig.json
@@ -0,0 +1,7 @@
+{
+  "extends": "@1stg/tsconfig/node",
+  "compilerOptions": {
+    "allowJs": true,
+    "verbatimModuleSyntax": false
+  }
+}
diff --git a/test/utils.spec.ts b/test/utils.spec.ts
new file mode 100644
index 0000000..c19577a
--- /dev/null
+++ b/test/utils.spec.ts
@@ -0,0 +1,130 @@
+import path from 'node:path'
+
+import { type Mock } from '@vitest/spy'
+import * as getTsconfig from 'get-tsconfig'
+
+import {
+  FIXTURES_PATH,
+  TEST_FILENAME,
+  testContext,
+  testFilePath,
+} from './utils.js'
+
+import type {
+  getTsconfigWithContext as getTsconfigWithContext_,
+  RuleContext,
+} from 'eslint-import-context'
+
+vi.mock('get-tsconfig', { spy: true })
+
+const fakeContext = {
+  ...testContext(),
+  parserPath: '@babel/eslint-parser',
+}
+
+const createContext = (
+  parserOptions: RuleContext['languageOptions']['parserOptions'] = {},
+): RuleContext => ({
+  ...testContext(),
+  parserOptions,
+})
+
+const tsconfigRootDir = '/custom/root/dir'
+
+describe('getTsconfigWithContext', () => {
+  let spied: Mock
+
+  let getTsconfigWithContext: typeof getTsconfigWithContext_
+
+  const mockTsConfig: getTsconfig.TsConfigJsonResolved = {
+    compilerOptions: { esModuleInterop: true },
+  }
+
+  beforeEach(async () => {
+    vi.resetModules()
+    spied = vi.mocked(getTsconfig.getTsconfig).mockReturnValue({
+      path: testFilePath('tsconfig.json'),
+      config: mockTsConfig,
+    })
+    ;({ getTsconfigWithContext } = await import('eslint-import-context'))
+  })
+
+  afterAll(() => {
+    spied.mockRestore()
+  })
+
+  test('caches and returns the result for the same context', () => {
+    // First call should use getTsconfig
+    const result1 = getTsconfigWithContext(fakeContext)
+    expect(spied).toHaveBeenCalledTimes(1)
+    expect(result1).toBe(mockTsConfig)
+
+    // Second call should use the cache
+    const result2 = getTsconfigWithContext(fakeContext)
+    expect(spied).toHaveBeenCalledTimes(1) // Still 1
+    expect(result2).toBe(mockTsConfig)
+  })
+
+  // eslint-disable-line sonarjs/todo-tag -- TODO: enable in next major
+  test.skip('falls back to `context.cwd` when tsconfigRootDir is not provided', () => {
+    getTsconfigWithContext(fakeContext)
+    expect(spied).toHaveBeenCalledWith(FIXTURES_PATH)
+  })
+
+  test('uses tsconfigRootDir when provided', () => {
+    getTsconfigWithContext(createContext({ tsconfigRootDir }))
+    expect(spied).toHaveBeenCalledWith(tsconfigRootDir)
+  })
+
+  test('resolves single project string path', () => {
+    const project = 'tsconfig.custom.json'
+    getTsconfigWithContext(createContext({ tsconfigRootDir, project }))
+    expect(spied).toHaveBeenCalledWith(path.resolve(tsconfigRootDir, project))
+  })
+
+  test('uses physicalFilename when project is true', () => {
+    const context = createContext({ project: true })
+    getTsconfigWithContext(context)
+    expect(spied).toHaveBeenCalledWith(TEST_FILENAME)
+  })
+
+  // eslint-disable-line sonarjs/fixme-tag -- FIXME: not sure why it's not working as expected
+  test.skip('tries multiple projects until finding a valid one', () => {
+    const projects = ['invalid.json', 'also-invalid.json', 'valid.json']
+    const context = createContext({
+      tsconfigRootDir,
+      project: projects,
+    })
+
+    // Mock first two calls to return null (not found)
+    spied
+      .mockReturnValueOnce(null)
+      .mockReturnValueOnce(null)
+      .mockReturnValueOnce({ config: mockTsConfig })
+
+    const result = getTsconfigWithContext(context)
+
+    // Should have tried all three paths
+    expect(spied).toHaveBeenNthCalledWith(
+      1,
+      path.resolve(tsconfigRootDir, projects[0]),
+    )
+    expect(spied).toHaveBeenNthCalledWith(
+      2,
+      path.resolve(tsconfigRootDir, projects[1]),
+    )
+    expect(spied).toHaveBeenNthCalledWith(
+      3,
+      path.resolve(tsconfigRootDir, projects[2]),
+    )
+
+    expect(result).toBe(mockTsConfig)
+  })
+
+  test('returns undefined when no tsconfig is found', () => {
+    // Mock getTsconfig to return null (not found)
+    spied.mockReturnValue(null)
+    const result = getTsconfigWithContext(fakeContext)
+    expect(result).toBeUndefined()
+  })
+})
diff --git a/test/utils.ts b/test/utils.ts
new file mode 100644
index 0000000..009a1c6
--- /dev/null
+++ b/test/utils.ts
@@ -0,0 +1,19 @@
+import path from 'node:path'
+
+import type { PluginSettings, RuleContext } from 'eslint-import-context'
+
+export const FIXTURES_PATH = path.resolve('test/fixtures')
+
+export function testFilePath(relativePath = 'foo.js') {
+  return path.resolve(FIXTURES_PATH, relativePath)
+}
+
+export const TEST_FILENAME = testFilePath()
+
+export function testContext(settings?: PluginSettings) {
+  return {
+    cwd: FIXTURES_PATH,
+    physicalFilename: TEST_FILENAME,
+    settings: settings || {},
+  } as RuleContext
+}
diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json
index a75d8f1..cd96993 100644
--- a/tsconfig.eslint.json
+++ b/tsconfig.eslint.json
@@ -3,7 +3,7 @@
   "extends": "./tsconfig.json",
   "compilerOptions": {
     "paths": {
-      "lib-boilerplate": ["./src/index.ts"]
+      "eslint-import-context": ["./src/index.ts"]
     }
   }
 }
diff --git a/vercel.json b/vercel.json
index 47d9a4f..4365c64 100644
--- a/vercel.json
+++ b/vercel.json
@@ -1,7 +1,7 @@
 {
   "version": 2,
   "alias": [
-    "lib-boilerplate.vercel.app"
+    "eslint-import-context.vercel.app"
   ],
   "github": {
     "silent": true
diff --git a/vitest.config.ts b/vitest.config.ts
index 0a194ff..33826c3 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -3,7 +3,8 @@ import { defineConfig } from 'vitest/config'
 export default defineConfig({
   resolve: {
     alias: {
-      'lib-boilerplate': new URL('src/index.ts', import.meta.url).pathname,
+      'eslint-import-context': new URL('src/index.ts', import.meta.url)
+        .pathname,
     },
   },
   test: {
diff --git a/yarn.lock b/yarn.lock
index 49b2fa6..e3821b0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4163,19 +4163,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@size-limit/esbuild@npm:11.2.0":
-  version: 11.2.0
-  resolution: "@size-limit/esbuild@npm:11.2.0"
-  dependencies:
-    esbuild: "npm:^0.25.0"
-    nanoid: "npm:^5.1.0"
-  peerDependencies:
-    size-limit: 11.2.0
-  checksum: 10c0/8740fd6f86d0be14bd7492781a9611f12fdbeafefa590ed485ce4f1768b521da8847c5ab314253bd0bb6decb50b5b5fe8f3cba7adc5cc9e55ebccbad6a161df3
-  languageName: node
-  linkType: hard
-
-"@size-limit/file@npm:11.2.0":
+"@size-limit/file@npm:^11.2.0":
   version: 11.2.0
   resolution: "@size-limit/file@npm:11.2.0"
   peerDependencies:
@@ -4184,19 +4172,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@size-limit/preset-small-lib@npm:^11.2.0":
-  version: 11.2.0
-  resolution: "@size-limit/preset-small-lib@npm:11.2.0"
-  dependencies:
-    "@size-limit/esbuild": "npm:11.2.0"
-    "@size-limit/file": "npm:11.2.0"
-    size-limit: "npm:11.2.0"
-  peerDependencies:
-    size-limit: 11.2.0
-  checksum: 10c0/3b1f55fde435794d83245687bc4e2e6996ddb178c774af62b57754e9b7d6ea1db3ef041f0706bd1ffb45da2fa52eba50594ce92ab312637e4198ee06274de673
-  languageName: node
-  linkType: hard
-
 "@swc/core-darwin-arm64@npm:1.11.29":
   version: 1.11.29
   resolution: "@swc/core-darwin-arm64@npm:1.11.29"
@@ -7509,6 +7484,55 @@ __metadata:
   languageName: node
   linkType: hard
 
+"eslint-import-context@workspace:.":
+  version: 0.0.0-use.local
+  resolution: "eslint-import-context@workspace:."
+  dependencies:
+    "@1stg/browserslist-config": "npm:^2.1.4"
+    "@1stg/common-config": "npm:^14.0.0"
+    "@1stg/postcss-config": "npm:^6.0.6"
+    "@1stg/stylelint-config": "npm:^6.0.5"
+    "@changesets/changelog-github": "npm:^0.5.1"
+    "@changesets/cli": "npm:^2.29.4"
+    "@commitlint/cli": "npm:^19.8.1"
+    "@eslint-react/eslint-plugin": "npm:^1.49.0"
+    "@mdx-js/rollup": "npm:^3.1.0"
+    "@shikijs/rehype": "npm:^3.4.2"
+    "@types/mdx": "npm:^2.0.13"
+    "@types/node": "npm:^22.15.21"
+    "@types/react": "npm:^19.1.5"
+    "@types/react-dom": "npm:^19.1.5"
+    "@types/web": "npm:^0.0.235"
+    "@vercel/analytics": "npm:^1.5.0"
+    "@vitejs/plugin-react-swc": "npm:^3.9.0"
+    "@vitest/coverage-v8": "npm:^3.1.4"
+    "@vitest/eslint-plugin": "npm:^1.2.0"
+    clean-pkg-json: "npm:^1.3.0"
+    eslint: "npm:^9.27.0"
+    eslint-plugin-react-hooks: "npm:^5.2.0"
+    github-markdown-css: "npm:^5.8.1"
+    nano-staged: "npm:^0.8.0"
+    npm-run-all2: "npm:^8.0.3"
+    premove: "npm:^4.0.0"
+    prettier: "npm:^3.5.3"
+    react: "npm:^19.1.0"
+    react-dom: "npm:^19.1.0"
+    react-router-dom: "npm:^7.6.0"
+    rehype-slug: "npm:^6.0.0"
+    remark-gfm: "npm:^4.0.1"
+    simple-git-hooks: "npm:^2.13.0"
+    size-limit: "npm:^11.2.0"
+    size-limit-preset-node-lib: "npm:^0.4.0"
+    stylelint: "npm:^16.19.1"
+    tsdown: "npm:^0.12.2"
+    type-coverage: "npm:^2.29.7"
+    typescript: "npm:^5.8.3"
+    vite: "npm:^6.3.5"
+    vitest: "npm:^3.1.4"
+    yarn-berry-deduplicate: "npm:^6.1.3"
+  languageName: unknown
+  linkType: soft
+
 "eslint-import-resolver-node@npm:^0.3.9":
   version: 0.3.9
   resolution: "eslint-import-resolver-node@npm:0.3.9"
@@ -10196,55 +10220,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"lib-boilerplate@workspace:.":
-  version: 0.0.0-use.local
-  resolution: "lib-boilerplate@workspace:."
-  dependencies:
-    "@1stg/browserslist-config": "npm:^2.1.4"
-    "@1stg/common-config": "npm:^14.0.0"
-    "@1stg/postcss-config": "npm:^6.0.6"
-    "@1stg/stylelint-config": "npm:^6.0.5"
-    "@changesets/changelog-github": "npm:^0.5.1"
-    "@changesets/cli": "npm:^2.29.4"
-    "@commitlint/cli": "npm:^19.8.1"
-    "@eslint-react/eslint-plugin": "npm:^1.49.0"
-    "@mdx-js/rollup": "npm:^3.1.0"
-    "@shikijs/rehype": "npm:^3.4.2"
-    "@size-limit/preset-small-lib": "npm:^11.2.0"
-    "@types/mdx": "npm:^2.0.13"
-    "@types/node": "npm:^22.15.21"
-    "@types/react": "npm:^19.1.5"
-    "@types/react-dom": "npm:^19.1.5"
-    "@types/web": "npm:^0.0.235"
-    "@vercel/analytics": "npm:^1.5.0"
-    "@vitejs/plugin-react-swc": "npm:^3.9.0"
-    "@vitest/coverage-v8": "npm:^3.1.4"
-    "@vitest/eslint-plugin": "npm:^1.2.0"
-    clean-pkg-json: "npm:^1.3.0"
-    eslint: "npm:^9.27.0"
-    eslint-plugin-react-hooks: "npm:^5.2.0"
-    github-markdown-css: "npm:^5.8.1"
-    nano-staged: "npm:^0.8.0"
-    npm-run-all2: "npm:^8.0.3"
-    premove: "npm:^4.0.0"
-    prettier: "npm:^3.5.3"
-    react: "npm:^19.1.0"
-    react-dom: "npm:^19.1.0"
-    react-router-dom: "npm:^7.6.0"
-    rehype-slug: "npm:^6.0.0"
-    remark-gfm: "npm:^4.0.1"
-    simple-git-hooks: "npm:^2.13.0"
-    size-limit: "npm:^11.2.0"
-    stylelint: "npm:^16.19.1"
-    tsdown: "npm:^0.12.2"
-    type-coverage: "npm:^2.29.7"
-    typescript: "npm:^5.8.3"
-    vite: "npm:^6.3.5"
-    vitest: "npm:^3.1.4"
-    yarn-berry-deduplicate: "npm:^6.1.3"
-  languageName: unknown
-  linkType: soft
-
 "lilconfig@npm:^3.1.3":
   version: 3.1.3
   resolution: "lilconfig@npm:3.1.3"
@@ -11706,7 +11681,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"nanoid@npm:^5.1.0":
+"nanoid@npm:^5.1.5":
   version: 5.1.5
   resolution: "nanoid@npm:5.1.5"
   bin:
@@ -15389,7 +15364,31 @@ __metadata:
   languageName: node
   linkType: hard
 
-"size-limit@npm:11.2.0, size-limit@npm:^11.2.0":
+"size-limit-node-esbuild@npm:^0.4.0":
+  version: 0.4.0
+  resolution: "size-limit-node-esbuild@npm:0.4.0"
+  dependencies:
+    nanoid: "npm:^5.1.5"
+    size-limit: "npm:^11.2.0"
+    tslib: "npm:^2.8.1"
+  checksum: 10c0/48d5619db81dc0dc6f999c2c725fece528efd6d127c8c9385ca01dcafce6713e209c09186a9e878b8a0f027de29a9651510b6129ad70d12082517b17c162a138
+  languageName: node
+  linkType: hard
+
+"size-limit-preset-node-lib@npm:^0.4.0":
+  version: 0.4.0
+  resolution: "size-limit-preset-node-lib@npm:0.4.0"
+  dependencies:
+    "@size-limit/file": "npm:^11.2.0"
+    size-limit-node-esbuild: "npm:^0.4.0"
+    tslib: "npm:^2.8.1"
+  peerDependencies:
+    size-limit: ^11.0.0
+  checksum: 10c0/bce77f07cbe51220284dc9ad8caf9c56e3315a18d7fa1def9efca63e4118965c53d9a9c9c53c26c6860bbfb89ce2f5193b8d82c0461558080f9ce97705c53f18
+  languageName: node
+  linkType: hard
+
+"size-limit@npm:^11.2.0":
   version: 11.2.0
   resolution: "size-limit@npm:11.2.0"
   dependencies:


Reviews:
user: login: ellipsis-dev[bot]
body: > [!CAUTION]
> **Changes requested  :x:**
> <details>
> <summary>Reviewed everything up to cf70455efe097163cb67a4556d26984a78e6f8fd in <ellipsistime>2 minutes and 4 seconds</ellipsistime>. Click for details.</summary> 
> 
> - Reviewed `602` lines of code in `16` files
> - Skipped `3` files when reviewing.
> - Skipped posting `7` draft comments. View those below.
> - Modify your [settings](https://app.ellipsis.dev/un-ts/settings/code-review) and [rules](https://app.ellipsis.dev/un-ts/code-review/rules) to customize what types of comments Ellipsis leaves. And don't forget to react with :+1: or :-1: to teach Ellipsis.
> 
> <details>
> <summary>1. <code>.github/workflows/ci.yml:20</code></summary>
> 
> - **Draft comment:** 
> Added Node.js 24 to matrix. Verify that all dependencies and environments support Node.js 24.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>2. <code>.github/workflows/pkg-pr-new.yml:31</code></summary>
> 
> - **Draft comment:** 
> The '--compact' flag is commented out. Confirm this is intentional and document the reason if so.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>3. <code>README.md:50</code></summary>
> 
> - **Draft comment:** 
> The API example still uses a default export 'echo', but src/index.ts no longer exports it. Update the documentation to reflect the new API (e.g. setRuleContext, useRuleContext).
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% While the comment suggests there's a mismatch between the docs and actual exports, I don't have access to src/index.ts to verify this claim. The package rename suggests this might be more than just a rename, but I can't be certain without seeing the source code. The comment seems plausible but requires more context to verify. I don't have access to the source code to verify if the exports actually changed. The comment could be wrong about the actual exports. Since I can't verify the actual exports, and understanding this requires seeing other files, I should err on the side of removing the comment per the rules. Remove the comment since verifying it requires context from other files that we don't have access to.
> 
> 
> </details>
> 
> <details>
> <summary>4. <code>src/utils.ts:27</code></summary>
> 
> - **Draft comment:** 
> The fallback for tsconfigRootDir uses process.cwd() instead of context.cwd (commented out). Confirm if this is the desired behavior.
> - **Reason this comment was not posted:**
> Comment looked like it was already resolved.
> 
> 
> </details>
> 
> <details>
> <summary>5. <code>package.json:8</code></summary>
> 
> - **Draft comment:** 
> Typo in funding URL: 'eslint-import-contex' should likely be 'eslint-import-context'.
> - **Reason this comment was not posted:**
> Marked as duplicate.
> 
> 
> </details>
> 
> <details>
> <summary>6. <code>src/index.ts:3</code></summary>
> 
> - **Draft comment:** 
> It appears that `export type * from './types.js'` is not valid TypeScript syntax. Did you mean to export specific types (e.g., `export type { MyType } from './types.js'`), or just use `export * from './types.js'` to export both types and values?
> - **Reason this comment was not posted:**
> Marked as duplicate.
> 
> 
> </details>
> 
> <details>
> <summary>7. <code>src/types.ts:97</code></summary>
> 
> - **Draft comment:** 
> Typo in comment: "Any object satisfied Resolver type" should be updated to "Any object that satisfies the Resolver type" for clarity.
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While the comment is technically correct about the grammar, this is a very minor issue. The meaning is still clear despite the grammatical error. The rules state not to make comments that are obvious or unimportant. A small grammatical fix in a comment doesn't affect functionality and isn't worth a PR comment. The grammar error could potentially cause confusion for non-native English speakers. Documentation clarity is important for maintainability. While documentation clarity is important, this particular grammar error is minor enough that it doesn't significantly impact understanding. The meaning remains clear even with the slight grammatical issue. Delete this comment as it's too minor of an issue to warrant a PR comment. It violates the rule about not making obvious or unimportant comments.
> 
> 
> </details>
> 
> 
> Workflow ID: <workflowid>`wflow_bD8yQl9BnYyIi7yl`</workflowid>
> </details>
> 
> <sup>You can customize </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=un-ts%2Feslint-import-context&utm_source=github&utm_medium=referral)<sup> by changing your [verbosity settings](https://app.ellipsis.dev/un-ts/settings/code-review), reacting with :+1: or :-1:, [replying to comments](https://docs.ellipsis.dev/features/code-review#teaching-ellipsis), or adding [code review rules](https://app.ellipsis.dev/un-ts/code-review/rules).</sup>
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:33:48Z
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR renames the library from **lib-boilerplate** to **eslint-import-context**, implements new context utilities for ESLint rules, and updates all related configs, tests, and documentation.

- Rename package, aliases, and tooling from _lib-boilerplate_ to _eslint-import-context_
- Add `getTsconfigWithContext`, `setRuleContext`, and `useRuleContext` utilities with accompanying tests
- Update CI workflows, Vercel config, tsconfig paths, and README badges/install instructions

### Reviewed Changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.

<details>
<summary>Show a summary per file</summary>

| File                                | Description                                           |
| ----------------------------------- | ----------------------------------------------------- |
| vitest.config.ts                    | Updated module alias to `eslint-import-context`       |
| vercel.json                         | Changed deployment alias                              |
| tsconfig.eslint.json                | Updated path mapping                                  |
| test/utils.ts                       | Added helper to build test contexts                   |
| test/utils.spec.ts                  | Added tests for `getTsconfigWithContext`              |
| test/context.spec.ts                | Added tests for `setRuleContext`/`useRuleContext`     |
| test/basic.spec.ts                  | Removed legacy boilerplate test                       |
| src/utils.ts                        | Implemented `getTsconfigWithContext` and caching      |
| src/index.ts                        | Introduced `setRuleContext` and `useRuleContext` APIs |
| package.json                        | Renamed package and updated metadata                  |
| README.md                           | Updated project name, badges, install commands        |
| CHANGELOG.md                        | Cleared old changelog entries                         |
| .github/workflows/*.yml             | Updated workflows and release PR metadata             |
| .changeset/config.json              | Updated repo path in changeset config                 |
</details>



<details>
<summary>Comments suppressed due to low confidence (2)</summary>

**test/utils.spec.ts:69**
* The fallback to `context.cwd` is currently skipped in tests. Consider enabling or implementing this test to ensure that behavior is validated once re-enabled.
```
test.skip('falls back to `context.cwd` when tsconfigRootDir is not provided', () => {
```
**src/index.ts:3**
* The syntax `export type * from './types.js'` is invalid. Consider using `export * from './types.js'` for values or `export type { ChildContext, RuleContext } from './types.js'` to re-export only types.
```
export type * from './types.js'
```
</details>


state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:33:51Z
user: login: ellipsis-dev[bot]
body: > [!CAUTION]
> **Changes requested  :x:**
> <details>
> <summary>Reviewed 899d299eaa56ebceb1d891e7a91f4bb919c004a5 in <ellipsistime>2 minutes and 14 seconds</ellipsistime>. Click for details.</summary> 
> 
> - Reviewed `640` lines of code in `18` files
> - Skipped `3` files when reviewing.
> - Skipped posting `13` draft comments. View those below.
> - Modify your [settings](https://app.ellipsis.dev/un-ts/settings/code-review) and [rules](https://app.ellipsis.dev/un-ts/code-review/rules) to customize what types of comments Ellipsis leaves. And don't forget to react with :+1: or :-1: to teach Ellipsis.
> 
> <details>
> <summary>1. <code>.changeset/yellow-ducks-fold.md:5</code></summary>
> 
> - **Draft comment:** 
> Consider providing a more descriptive changelog message for clarity.
> - **Reason this comment was not posted:**
> Comment did not seem useful. Confidence is useful = `0%` <= threshold `50%` This comment is asking the PR author to update the changelog message, which is similar to asking to update the PR description. It doesn't provide a specific code suggestion or point out a potential issue in the code itself.
> 
> 
> </details>
> 
> <details>
> <summary>2. <code>.github/workflows/ci.yml:20</code></summary>
> 
> - **Draft comment:** 
> Node.js 24 has been added to the CI matrix; please verify that all tests run successfully on Node.js v24.
> - **Reason this comment was not posted:**
> Comment did not seem useful. Confidence is useful = `0%` <= threshold `50%` This comment is asking the PR author to verify that tests run successfully on a new Node.js version. This falls under asking the author to ensure behavior is intended or tested, which is against the rules.
> 
> 
> </details>
> 
> <details>
> <summary>3. <code>.github/workflows/pkg-pr-new.yml:31</code></summary>
> 
> - **Draft comment:** 
> Ensure removal of the '--compact' flag in the publish command is intentional.
> - **Reason this comment was not posted:**
> Comment looked like it was already resolved.
> 
> 
> </details>
> 
> <details>
> <summary>4. <code>.github/workflows/release.yml:40</code></summary>
> 
> - **Draft comment:** 
> Release commit message and title have been updated to reflect the new package name; double-check that these match your release strategy.
> - **Reason this comment was not posted:**
> Comment did not seem useful. Confidence is useful = `0%` <= threshold `50%` This comment is asking the PR author to double-check the release commit message and title, which violates the rule against asking the author to double-check things. It doesn't provide a specific suggestion or point out a specific issue.
> 
> 
> </details>
> 
> <details>
> <summary>5. <code>.size-limit.json:3</code></summary>
> 
> - **Draft comment:** 
> The size-limit configuration now points to './src/index.ts' with an increased limit (200B). Verify if this target is correct or if it should reference the built output in 'lib/'.
> - **Reason this comment was not posted:**
> Comment did not seem useful. Confidence is useful = `0%` <= threshold `50%` The comment is asking the PR author to verify if the size-limit configuration is correct. This falls under asking the author to confirm their intention, which is against the rules. Therefore, this comment should be removed.
> 
> 
> </details>
> 
> <details>
> <summary>6. <code>CHANGELOG.md:1</code></summary>
> 
> - **Draft comment:** 
> CHANGELOG.md is now almost empty; ensure that changelog entries are either generated automatically or maintained manually.
> - **Reason this comment was not posted:**
> Comment did not seem useful. Confidence is useful = `0%` <= threshold `50%` This comment is purely informative and suggests ensuring something without a specific actionable item. It doesn't provide a specific code suggestion or ask for a specific test to be written.
> 
> 
> </details>
> 
> <details>
> <summary>7. <code>README.md:16</code></summary>
> 
> - **Draft comment:** 
> The README description ('A simple library boilerplate.') is outdated compared to the package purpose. Consider updating it to reflect that this package provides context info for eslint-plugin-import-x.
> - **Reason this comment was not posted:**
> Comment was not on a location in the diff, so it can't be submitted as a review comment.
> 
> 
> </details>
> 
> <details>
> <summary>8. <code>package.json:1</code></summary>
> 
> - **Draft comment:** 
> package.json has been updated with the new project details. Verify that the 'main', 'types', and 'module' entries align with your build outputs, especially given the update in size-limit configuration.
> - **Reason this comment was not posted:**
> Comment did not seem useful. Confidence is useful = `0%` <= threshold `50%` The comment is asking the PR author to verify alignment between `package.json` entries and build outputs, which is a form of asking for confirmation. This violates the rule against asking the author to confirm or double-check things.
> 
> 
> </details>
> 
> <details>
> <summary>9. <code>src/index.ts:3</code></summary>
> 
> - **Draft comment:** 
> The syntax 'export type * from "./types.js"' is unusual and may not be supported. Consider using 'export * from "./types.js"' or explicitly listing the types to export.
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The syntax `export type *` is actually valid TypeScript syntax introduced in TypeScript 3.8 for type-only exports. It's different from `export *` as it only exports type declarations, which can help with tree-shaking. Given that line 1 uses `import type`, it seems the author is intentionally using type-only imports/exports consistently. The comment author might be right that this syntax is less common and could cause confusion. Some older TypeScript versions might not support it. The syntax is valid modern TypeScript and appears to be used intentionally as part of a consistent type-only import/export pattern in the code. The comment should be deleted because it suggests changing valid, intentional TypeScript syntax that serves a specific purpose (type-only exports).
> 
> 
> </details>
> 
> <details>
> <summary>10. <code>src/utils.ts:27</code></summary>
> 
> - **Draft comment:** 
> The fallback for 'tsconfigRootDir' uses 'process.cwd()' instead of 'context.cwd'. Confirm if this is the intended behavior, and consider uncommenting the fallback to 'context.cwd' in a future major release.
> - **Reason this comment was not posted:**
> Comment looked like it was already resolved.
> 
> 
> </details>
> 
> <details>
> <summary>11. <code>test/utils.spec.ts:68</code></summary>
> 
> - **Draft comment:** 
> Some tests are currently skipped. Consider resolving these issues or documenting the reasons for skipping to ensure full test coverage in the future.
> - **Reason this comment was not posted:**
> Comment did not seem useful. Confidence is useful = `40%` <= threshold `50%` The comment suggests resolving issues with skipped tests or documenting reasons for skipping. It indirectly asks the author to ensure full test coverage, which violates the rule against asking the author to ensure testing. However, it does provide a specific suggestion to document reasons for skipping, which could be useful.
> 
> 
> </details>
> 
> <details>
> <summary>12. <code>vercel.json:9</code></summary>
> 
> - **Draft comment:** 
> The rewrite rule sends all requests to 'index.html'. Verify that this configuration is appropriate for a library project and not a web application.
> - **Reason this comment was not posted:**
> Comment was not on a location in the diff, so it can't be submitted as a review comment.
> 
> 
> </details>
> 
> <details>
> <summary>13. <code>src/types.ts:97</code></summary>
> 
> - **Draft comment:** 
> Typographical suggestion: In the comment "Any object satisfied Resolver type", consider revising "satisfied" to "satisfies" (e.g. "Any object that satisfies the Resolver type") for clarity.
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While the grammar correction is technically accurate, comments about documentation and grammar tend to be low-value PR comments that distract from more important code review concerns. The meaning is still clear despite the minor grammatical error. This feels like nitpicking that doesn't meaningfully improve code quality. The grammar error could potentially confuse non-native English speakers. Clear documentation is important for code maintainability. While documentation clarity is important, this particular grammar error is minor enough that it doesn't significantly impact understanding. The comment's meaning remains clear even with the error. This comment should be removed as it focuses on a minor grammatical issue rather than substantive code concerns.
> 
> 
> </details>
> 
> 
> Workflow ID: <workflowid>`wflow_w8tDd7SQqcK2SZ01`</workflowid>
> </details>
> 
> <sup>You can customize </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=un-ts%2Feslint-import-context&utm_source=github&utm_medium=referral)<sup> by changing your [verbosity settings](https://app.ellipsis.dev/un-ts/settings/code-review), reacting with :+1: or :-1:, [replying to comments](https://docs.ellipsis.dev/features/code-review#teaching-ellipsis), or adding [code review rules](https://app.ellipsis.dev/un-ts/code-review/rules).</sup>
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:37:44Z
user: login: ellipsis-dev[bot]
body: > [!IMPORTANT]
> **Looks good to me!  :+1:**
> <details>
> <summary>Reviewed e1828be284f7bdd1f80d9c1ceb89dc32779c4748 in <ellipsistime>1 minute and 49 seconds</ellipsistime>. Click for details.</summary> 
> 
> - Reviewed `645` lines of code in `18` files
> - Skipped `3` files when reviewing.
> - Skipped posting `15` draft comments. View those below.
> - Modify your [settings](https://app.ellipsis.dev/un-ts/settings/code-review) and [rules](https://app.ellipsis.dev/un-ts/code-review/rules) to customize what types of comments Ellipsis leaves. And don't forget to react with :+1: or :-1: to teach Ellipsis.
> 
> <details>
> <summary>1. <code>.changeset/yellow-ducks-fold.md:5</code></summary>
> 
> - **Draft comment:** 
> Ensure the changeset message is descriptive and follows standard conventions.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>2. <code>.github/workflows/ci.yml:20</code></summary>
> 
> - **Draft comment:** 
> Added Node.js version 24; verify that your code and tests are compatible with Node 24.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>3. <code>.github/workflows/pkg-pr-new.yml:31</code></summary>
> 
> - **Draft comment:** 
> Removal of the '--compact' flag; confirm if this change is intentional.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>4. <code>.github/workflows/release.yml:40</code></summary>
> 
> - **Draft comment:** 
> Release job updated with the new package name. Ensure that the changelog and versioning processes are in sync.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>5. <code>.size-limit.json:3</code></summary>
> 
> - **Draft comment:** 
> Updated file path and size limit; verify that using './src/index.ts' with a 200B limit is appropriate.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>6. <code>CHANGELOG.md:1</code></summary>
> 
> - **Draft comment:** 
> Changelog has been cleared; ensure that future releases document their changes appropriately.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>7. <code>README.md:1</code></summary>
> 
> - **Draft comment:** 
> README updated to reflect the new package name and usage. Confirm that the API example matches the exported interface.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>8. <code>package.json:15</code></summary>
> 
> - **Draft comment:** 
> Verify that using '.d.cts' in the 'types' field is intentional and that all export fields align with the built files.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>9. <code>src/index.ts:3</code></summary>
> 
> - **Draft comment:** 
> The 'export type * from' syntax is unusual; consider using 'export * from' if you intend to re-export all types.
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The 'export type *' syntax is actually valid TypeScript and has a specific purpose - it only re-exports type definitions, not values. The 'export *' syntax would re-export both types and values. Since we're importing only types from types.js (note the 'import type'), the current syntax is likely intentional and correct. I could be wrong about the author's intention - maybe they do want to re-export values from types.js as well. The import type statement doesn't necessarily mean all exports are types. While true, the explicit use of 'import type' and 'export type' shows a clear pattern of type-only operations with types.js. The current syntax is valid and likely intentional. The comment should be deleted as it suggests changing intentional, valid TypeScript syntax that serves a specific purpose.
> 
> 
> </details>
> 
> <details>
> <summary>10. <code>test/utils.spec.ts:69</code></summary>
> 
> - **Draft comment:** 
> The test 'falls back to `context.cwd`' is skipped; please document why it is skipped and plan for its resolution.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>11. <code>test/utils.spec.ts:91</code></summary>
> 
> - **Draft comment:** 
> The test for resolving multiple projects is skipped; investigate the issue and enable the test once resolved.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>12. <code>vercel.json:9</code></summary>
> 
> - **Draft comment:** 
> Rewrites configuration directs all routes to index.html; confirm that this SPA routing fallback is intended.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>13. <code>vitest.config.ts:6</code></summary>
> 
> - **Draft comment:** 
> The alias for 'eslint-import-context' was updated; ensure that the module resolution works correctly in Vitest.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>14. <code>src/index.ts:3</code></summary>
> 
> - **Draft comment:** 
> Typo: The syntax 'export type * from './types.js'' appears incorrect. Consider removing the 'type' modifier or explicitly listing the types to export.
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The `export type *` syntax is actually valid TypeScript syntax introduced in TypeScript 3.8+ for re-exporting only the types from a module. Given that line 1 imports types and this seems to be a type-focused module, this syntax is likely intentional and correct. The comment is suggesting a change that would actually change the behavior by exporting values instead of just types. Could there be a reason why exporting both types and values would be better here? Maybe the types.js file contains both types and values that need to be exported? The explicit use of `import type` on line 1 strongly suggests this is intentionally a type-only module interface. If values were needed, they would likely be imported directly. The comment should be deleted because it incorrectly suggests changing valid TypeScript syntax that appears to be intentionally used for type-only exports.
> 
> 
> </details>
> 
> <details>
> <summary>15. <code>src/types.ts:97</code></summary>
> 
> - **Draft comment:** 
> Typo in comment: "Any object satisfied Resolver type" might be better phrased as "Any object satisfying the Resolver type".
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% While the grammatical correction is technically accurate, it's an extremely minor issue that doesn't affect code functionality or clarity. The existing comment is still perfectly understandable. The rules state we should not make purely informative comments or comments that are obvious/unimportant. This seems to fall into that category. The grammar error could potentially confuse non-native English speakers. Also, since this is a new file, maintaining high documentation quality from the start could be important. While documentation quality is important, this minor grammatical issue doesn't significantly impact understanding. The rules explicitly state not to make purely informative comments that don't require code changes. This comment should be deleted as it's a purely informative comment about a minor grammatical issue that doesn't impact code functionality or documentation clarity.
> 
> 
> </details>
> 
> 
> Workflow ID: <workflowid>`wflow_UwBdkVSTE9RgQprc`</workflowid>
> </details>
> 
> <sup>You can customize </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=un-ts%2Feslint-import-context&utm_source=github&utm_medium=referral)<sup> by changing your [verbosity settings](https://app.ellipsis.dev/un-ts/settings/code-review), reacting with :+1: or :-1:, [replying to comments](https://docs.ellipsis.dev/features/code-review#teaching-ellipsis), or adding [code review rules](https://app.ellipsis.dev/un-ts/code-review/rules).</sup>
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:40:07Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 4**

<details>
<summary>♻️ Duplicate comments (2)</summary><blockquote>

<details>
<summary>package.json (1)</summary><blockquote>

`8-8`: **LGTM! Funding URL appears correct.**

The funding URL has been updated and the typo mentioned in previous reviews appears to have been fixed - it correctly ends with "eslint-import-context".

</blockquote></details>
<details>
<summary>src/index.ts (1)</summary><blockquote>

`3-3`: **The export syntax is valid in modern TypeScript.**

The syntax `export type * from './types.js'` is valid TypeScript syntax introduced in TypeScript 4.9+. This re-exports only the types from the module, which is the intended behavior here.

The past review comments suggesting this syntax is invalid appear to be outdated. This syntax correctly re-exports only types, not runtime values.

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (8)</summary><blockquote>

<details>
<summary>tsconfig.eslint.json (1)</summary><blockquote>

`5-7`: **Consider wildcard path mapping**  
If your imports reference submodules (e.g., `eslint-import-context/utils`), you may want to add a wildcard mapping:  
```diff
 "paths": {
-  "eslint-import-context": ["./src/index.ts"]
+  "eslint-import-context": ["./src/index.ts"],
+  "eslint-import-context/*": ["./src/*"]
 }
```

</blockquote></details>
<details>
<summary>.github/workflows/pkg-pr-new.yml (1)</summary><blockquote>

`31-31`: **Remove commented-out flag for clarity**  
To avoid confusion, consider deleting the trailing `# --compact` comment since the flag is no longer used.

</blockquote></details>
<details>
<summary>README.md (1)</summary><blockquote>

`50-54`: **Consider enhancing the API example to showcase context management.**

While the current example demonstrates the utility functions, it doesn't fully showcase the context management capabilities that are central to this library. Consider adding an example that demonstrates `setRuleContext` usage:

```diff
```js
-import { useRuleContext, getTsconfigWithContext } from 'eslint-import-context'
+import { setRuleContext, useRuleContext, getTsconfigWithContext } from 'eslint-import-context'

-const ruleContext = useRuleContext()
-
-const tsconfig = getTsconfigWithContext(ruleContext)
+// Set context and execute within that scope
+const result = setRuleContext(myRuleContext, () => {
+  const ruleContext = useRuleContext()
+  const tsconfig = getTsconfigWithContext(ruleContext)
+  return tsconfig
+})
```

</blockquote></details>
<details>
<summary>test/utils.spec.ts (2)</summary><blockquote>

`69-72`: **Consider enabling or removing the skipped test.**

This test is skipped with a TODO comment about enabling in the next major version. Consider either:
1. Creating a tracking issue for this functionality
2. Removing the test if the feature won't be implemented
3. Adding more context about why it's disabled


Would you like me to create a tracking issue for this functionality or help clarify the implementation plan?

---

`92-122`: **Address the skipped test with FIXME comment.**

This test is skipped with a FIXME comment indicating uncertainty about why it's not working. This suggests a potential issue that should be investigated.


Would you like me to help investigate why this test isn't working as expected? This could indicate an issue with the multiple project path handling logic in `getTsconfigWithContext`.

</blockquote></details>
<details>
<summary>src/index.ts (1)</summary><blockquote>

`8-17`: **LGTM! Well-implemented temporary context pattern.**

The `setRuleContext` function properly implements the temporary context pattern with automatic cleanup. The use of a `try-finally` pattern could make this more robust in case the callback throws an error.


Consider adding error handling to ensure context is always restored:

```diff
export const setRuleContext = <T = void>(
  nextRuleContext: ChildContext | RuleContext,
  callback: () => T,
) => {
  const currentValue = ruleContext
  ruleContext = nextRuleContext
-  const result = callback()
-  ruleContext = currentValue
-  return result
+  try {
+    return callback()
+  } finally {
+    ruleContext = currentValue
+  }
}
```

</blockquote></details>
<details>
<summary>src/utils.ts (2)</summary><blockquote>

`26-30`: **Address the TODO comment for next major version.**

The commented code suggests using `context.cwd` instead of `process.cwd()` in the next major version. Consider documenting this breaking change or creating a tracking issue.



Would you like me to open an issue to track this breaking change for the next major version?

---

`15-16`: **Consider breaking down the complex function.**

The function has cognitive complexity disabled, indicating it might be too complex. Consider extracting helper functions for project resolution logic to improve readability and maintainability.



You could extract the project resolution logic into separate helper functions:
- `resolveWithProjects(projects, tsconfigRootDir, context)`
- `resolveWithoutProject(tsconfigRootDir)`

This would make the main function more focused on the caching logic.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 12541814a8a5baf8cac17f7fe95856be357a71b6 and e1828be284f7bdd1f80d9c1ceb89dc32779c4748.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `yarn.lock` is excluded by `!**/yarn.lock`, `!**/*.lock`

</details>

<details>
<summary>📒 Files selected for processing (20)</summary>

* `.changeset/config.json` (1 hunks)
* `.changeset/yellow-ducks-fold.md` (1 hunks)
* `.github/workflows/ci.yml` (1 hunks)
* `.github/workflows/pkg-pr-new.yml` (1 hunks)
* `.github/workflows/release.yml` (1 hunks)
* `.size-limit.json` (1 hunks)
* `CHANGELOG.md` (0 hunks)
* `README.md` (2 hunks)
* `package.json` (2 hunks)
* `src/index.ts` (1 hunks)
* `src/types.ts` (1 hunks)
* `src/utils.ts` (1 hunks)
* `test/basic.spec.ts` (0 hunks)
* `test/context.spec.ts` (1 hunks)
* `test/fixtures/tsconfig.json` (1 hunks)
* `test/utils.spec.ts` (1 hunks)
* `test/utils.ts` (1 hunks)
* `tsconfig.eslint.json` (1 hunks)
* `vercel.json` (1 hunks)
* `vitest.config.ts` (1 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (2)</summary>

* CHANGELOG.md
* test/basic.spec.ts

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (6)</summary>

<details>
<summary>test/context.spec.ts (2)</summary><blockquote>

<details>
<summary>src/index.ts (2)</summary>

* `useRuleContext` (19-19)
* `setRuleContext` (8-17)

</details>
<details>
<summary>test/utils.ts (1)</summary>

* `testContext` (13-19)

</details>

</blockquote></details>
<details>
<summary>test/utils.ts (1)</summary><blockquote>

<details>
<summary>src/types.ts (2)</summary>

* `PluginSettings` (139-139)
* `RuleContext` (141-146)

</details>

</blockquote></details>
<details>
<summary>test/utils.spec.ts (3)</summary><blockquote>

<details>
<summary>test/utils.ts (4)</summary>

* `testContext` (13-19)
* `testFilePath` (7-9)
* `FIXTURES_PATH` (5-5)
* `TEST_FILENAME` (11-11)

</details>
<details>
<summary>src/types.ts (1)</summary>

* `RuleContext` (141-146)

</details>
<details>
<summary>src/utils.ts (1)</summary>

* `getTsconfigWithContext` (16-51)

</details>

</blockquote></details>
<details>
<summary>src/index.ts (1)</summary><blockquote>

<details>
<summary>src/types.ts (2)</summary>

* `ChildContext` (148-158)
* `RuleContext` (141-146)

</details>

</blockquote></details>
<details>
<summary>src/utils.ts (1)</summary><blockquote>

<details>
<summary>src/types.ts (2)</summary>

* `ChildContext` (148-158)
* `RuleContext` (141-146)

</details>

</blockquote></details>
<details>
<summary>src/types.ts (1)</summary><blockquote>

<details>
<summary>src/utils.ts (1)</summary>

* `PluginName` (11-11)

</details>

</blockquote></details>

</details><details>
<summary>🪛 Biome (1.9.4)</summary>

<details>
<summary>src/types.ts</summary>

[error] 95-95: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

</details>

</details>

</details>

<details>
<summary>🔇 Additional comments (33)</summary><blockquote>

<details>
<summary>vercel.json (1)</summary>

`4-4`: **LGTM! Proper project rebranding alignment.**

The alias update correctly reflects the project rename from "lib-boilerplate" to "eslint-import-context" and aligns with the comprehensive rebranding effort across the codebase.

</details>
<details>
<summary>.changeset/config.json (1)</summary>

`6-6`: **LGTM! Changelog configuration updated correctly.**

The repository reference update ensures changelog generation targets the correct renamed repository, maintaining consistency with the project rebranding.

</details>
<details>
<summary>.changeset/yellow-ducks-fold.md (1)</summary>

`1-6`: **LGTM! Properly formatted changeset documentation.**

The changeset file correctly follows the standard format and appropriately documents the initial feature release for the eslint-import-context project.

</details>
<details>
<summary>src/types.ts (6)</summary>

`1-5`: **LGTM! Well-structured import statements.**

The type-only imports are properly declared and the dependencies are appropriate for the module's functionality.

---

`7-10`: **LGTM! Clean and well-defined basic types.**

The `FileExtension` template literal type with dot prefix and `DocStyle` literal union are appropriately defined for their use cases.

---

`11-38`: **LGTM! Excellent discriminated union pattern for resolver results.**

The `ResultFound`/`ResultNotFound` interfaces properly implement a discriminated union pattern with the `found` property, providing excellent type safety. The `NewResolver` interface is clean and well-designed for the version 3 API.

---

`116-139`: **LGTM! Comprehensive settings configuration with sophisticated type transformation.**

The `ImportSettings` interface provides excellent coverage of configuration options, and the `WithPluginName` generic type implements a sophisticated type transformation for plugin name prefixing with proper kebab-case conversion.

---

`141-158`: **LGTM! Well-designed context types extending ESLint's foundation.**

The `RuleContext` type properly extends ESLint's built-in context while customizing the settings property, and `ChildContext` provides comprehensive contextual information needed for rule execution. The type design maintains compatibility while adding plugin-specific functionality.

---

`1-158`: **Excellent comprehensive type definitions module.**

This file provides a well-structured and thorough set of type definitions that properly support both legacy and modern ESLint resolver patterns. The use of advanced TypeScript features like discriminated unions, template literal types, and complex generic transformations is appropriate and enhances type safety throughout the plugin.

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 Biome (1.9.4)</summary>

[error] 95-95: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

</details>

</details>

</details>
<details>
<summary>tsconfig.eslint.json (1)</summary>

`6-6`: **Confirm path alias update**  
The alias has been correctly updated from `"lib-boilerplate"` to `"eslint-import-context"` pointing to `./src/index.ts`.

</details>
<details>
<summary>.github/workflows/pkg-pr-new.yml (1)</summary>

`31-31`: **Approve removal of `--compact` flag**  
The `--compact` flag has been removed from the publish step as intended.

</details>
<details>
<summary>.size-limit.json (1)</summary>

`3-5`: **Size-limit configuration updated**  
Monitoring the source file `./src/index.ts` with an increased limit of `200B` aligns with the expanded functionality.

</details>
<details>
<summary>.github/workflows/release.yml (1)</summary>

`40-41`: **Update release commit and title**  
The commit and PR title strings have been updated to use `eslint-import-context`.

</details>
<details>
<summary>.github/workflows/ci.yml (1)</summary>

`20-20`: **Verify Node.js 24 compatibility**  
The CI matrix now includes Node.js 24; please confirm that all dependencies support it and that the lint/test steps pass on this version.

</details>
<details>
<summary>test/fixtures/tsconfig.json (1)</summary>

`1-7`: **LGTM! Well-structured test fixture.**

The TypeScript configuration is appropriate for a test fixture, with sensible options that enable JavaScript compilation and flexible module syntax for testing purposes.

</details>
<details>
<summary>vitest.config.ts (1)</summary>

`6-7`: **LGTM! Proper alias update for project rebranding.**

The alias configuration has been correctly updated to reflect the new project name, and the formatting improvement with line splitting enhances readability.

</details>
<details>
<summary>package.json (3)</summary>

`2-2`: **LGTM! Package name updated correctly.**

The package name has been properly updated to reflect the new project identity.

---

`5-6`: **LGTM! Metadata updated consistently.**

The description and repository URL have been properly updated to align with the new project name and purpose.

---

`89-89`: **LGTM! Development dependency updated appropriately.**

The change from `@size-limit/preset-small-lib` to `size-limit-preset-node-lib` aligns with the project's focus on Node.js library functionality.

</details>
<details>
<summary>test/context.spec.ts (2)</summary>

`1-3`: **LGTM! Proper test imports.**

The imports correctly reference the test utilities and the main module functions being tested.

---

`5-17`: **LGTM! Comprehensive context management test.**

This test thoroughly validates the context management functionality:

- ✅ Verifies initial undefined state
- ✅ Tests context setting and retrieval within callback scope  
- ✅ Confirms return value propagation from callback
- ✅ Ensures proper context cleanup after execution

The test structure follows best practices and provides complete coverage of the context management API.

</details>
<details>
<summary>README.md (2)</summary>

`1-8`: **LGTM! Comprehensive rebranding completed.**

All project references have been consistently updated from "lib-boilerplate" to "eslint-import-context" across the title and badges.

---

`35-44`: **LGTM! Installation commands properly updated.**

All package manager installation commands correctly reference the new package name.

</details>
<details>
<summary>test/utils.spec.ts (4)</summary>

`1-17`: **LGTM! Well-structured test imports and setup.**

The imports are properly organized and the type imports follow best practices.

---

`18-30`: **LGTM! Proper mocking and test context setup.**

The Vitest mocking setup and context creation helpers are well-implemented.

---

`56-66`: **LGTM! Excellent caching behavior verification.**

This test properly verifies that the function caches results for repeated calls with the same context, which is crucial for performance.

---

`124-129`: **LGTM! Proper handling of missing tsconfig.**

This test correctly verifies the undefined return value when no tsconfig is found.

</details>
<details>
<summary>test/utils.ts (1)</summary>

`1-19`: **LGTM! Clean and focused test utility module.**

The utility functions are well-designed with clear responsibilities:
- Path management with `FIXTURES_PATH` and `testFilePath`
- Mock context creation with appropriate defaults
- Proper TypeScript typing throughout

This provides a solid foundation for the test suite.

</details>
<details>
<summary>src/index.ts (2)</summary>

`6-6`: **LGTM! Proper module-scoped context variable.**

The module-scoped variable provides appropriate state management for the context utilities.

---

`19-19`: **LGTM! Simple and effective context accessor.**

The `useRuleContext` function provides clean access to the current context state.

</details>
<details>
<summary>src/utils.ts (3)</summary>

`1-7`: **LGTM! Clean and appropriate imports.**

The imports are well-organized and necessary for the functionality. Good use of type-only imports where appropriate.

---

`9-12`: **LGTM! Simple and clear constant definitions.**

The plugin name constant and its type definition are straightforward and follow good practices.

---

`13-13`: **LGTM! Efficient caching implementation.**

Using a Map for caching is appropriate here to avoid redundant file system operations for tsconfig resolution.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:45:17Z
user: login: JounQin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-24T15:47:43Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:48:35Z
user: login: JounQin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-24T15:52:37Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:53:00Z
user: login: JounQin
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-24T15:53:43Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:54:13Z
user: login: ellipsis-dev[bot]
body: > [!CAUTION]
> **Changes requested  :x:**
> <details>
> <summary>Reviewed 229c0912e8b2bbaebc9d5ff743139d4d4a3d0f3a in <ellipsistime>2 minutes and 3 seconds</ellipsistime>. Click for details.</summary> 
> 
> - Reviewed `645` lines of code in `18` files
> - Skipped `3` files when reviewing.
> - Skipped posting `10` draft comments. View those below.
> - Modify your [settings](https://app.ellipsis.dev/un-ts/settings/code-review) and [rules](https://app.ellipsis.dev/un-ts/code-review/rules) to customize what types of comments Ellipsis leaves. And don't forget to react with :+1: or :-1: to teach Ellipsis.
> 
> <details>
> <summary>1. <code>.changeset/yellow-ducks-fold.md:2</code></summary>
> 
> - **Draft comment:** 
> Consider removing the unnecessary quotes around the package name if not required by the changeset format.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>2. <code>.github/workflows/pkg-pr-new.yml:31</code></summary>
> 
> - **Draft comment:** 
> Remove the commented '--compact' flag if it’s no longer needed.
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% This is a valid point about code cleanliness - commented out code should generally be removed if it's no longer needed. However, the comment is quite minor and doesn't affect functionality. The author may have left it commented for a reason, such as documentation or future reference. The comment could be seen as too minor to warrant attention. Also, the author might want to keep the comment as documentation of available options. While minor, removing commented-out code is a good practice to keep files clean and prevent confusion. However, this falls into the category of being too obvious/unimportant to warrant a PR comment. This comment should be removed as it's too minor and obvious to warrant a PR comment. It violates the rule about not making obvious or unimportant comments.
> 
> 
> </details>
> 
> <details>
> <summary>3. <code>.github/workflows/release.yml:40</code></summary>
> 
> - **Draft comment:** 
> Ensure the updated commit and title messages consistently reflect 'eslint-import-context'.
> - **Reason this comment was not posted:**
> Confidence changes required: `10%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>4. <code>.size-limit.json:4</code></summary>
> 
> - **Draft comment:** 
> Verify that a size limit of '200B' is intentional—it seems very low.
> - **Reason this comment was not posted:**
> Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 10% vs. threshold = 50% The comment starts with "Verify that..." which is explicitly called out as not useful in our rules. The change actually INCREASED the size limit from 50B to 200B, showing intentional growth. The author clearly meant to make this change. We shouldn't ask them to verify their intentional changes. Maybe 200B is truly an unusually small limit that could cause problems, and we're missing important context about typical size limits. Even if 200B is small, the author deliberately increased it from 50B. If it's too small, they'll discover that naturally when the size check fails. We shouldn't speculate. Delete this comment. It asks for verification of an intentional change and violates our rule about not asking authors to confirm their intentions.
> 
> 
> </details>
> 
> <details>
> <summary>5. <code>CHANGELOG.md:2</code></summary>
> 
> - **Draft comment:** 
> The changelog is minimal; consider adding detailed version entries for clarity.
> - **Reason this comment was not posted:**
> Confidence changes required: `50%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>6. <code>README.md:16</code></summary>
> 
> - **Draft comment:** 
> Update the project description to reflect its purpose instead of labeling it as a boilerplate.
> - **Reason this comment was not posted:**
> Comment was not on a location in the diff, so it can't be submitted as a review comment.
> 
> 
> </details>
> 
> <details>
> <summary>7. <code>package.json:15</code></summary>
> 
> - **Draft comment:** 
> Confirm that the type declaration filenames (.cts vs .d.ts) are intentional for dual module support.
> - **Reason this comment was not posted:**
> Comment was not on a location in the diff, so it can't be submitted as a review comment.
> 
> 
> </details>
> 
> <details>
> <summary>8. <code>src/index.ts:3</code></summary>
> 
> - **Draft comment:** 
> Potential syntax issue: 'export type * from' may not be valid. Consider explicitly exporting types or using 'export * from'.
> - **Reason this comment was not posted:**
> Marked as duplicate.
> 
> 
> </details>
> 
> <details>
> <summary>9. <code>src/utils.ts:27</code></summary>
> 
> - **Draft comment:** 
> Consider using 'context.cwd' as a fallback for tsconfigRootDir once the API stabilizes (currently commented out).
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> <details>
> <summary>10. <code>test/utils.spec.ts:68</code></summary>
> 
> - **Draft comment:** 
> Review the skipped tests; either enable them or remove if they’re no longer relevant.
> - **Reason this comment was not posted:**
> Confidence changes required: `33%` <= threshold `50%` None
> 
> 
> </details>
> 
> 
> Workflow ID: <workflowid>`wflow_iasC8s8MohC8JWfO`</workflowid>
> </details>
> 
> <sup>You can customize </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=un-ts%2Feslint-import-context&utm_source=github&utm_medium=referral)<sup> by changing your [verbosity settings](https://app.ellipsis.dev/un-ts/settings/code-review), reacting with :+1: or :-1:, [replying to comments](https://docs.ellipsis.dev/features/code-review#teaching-ellipsis), or adding [code review rules](https://app.ellipsis.dev/un-ts/code-review/rules).</sup>
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-24T15:54:57Z

Review comments:
diff_hunk: @@ -1,11 +1,11 @@
 {
-  "name": "lib-boilerplate",
+  "name": "eslint-import-context",
   "version": "0.0.0",
   "type": "module",
-  "description": "A simple library boilerplate.",
-  "repository": "git+https://github.com/un-ts/lib-boilerplate.git",
+  "description": "Provide context info for eslint-plugin-import-x, so no extra arguments need to be added.",
+  "repository": "git+https://github.com/un-ts/eslint-import-context.git",
   "author": "JounQin <admin@1stg.me> (https://www.1stG.me)",
-  "funding": "https://opencollective.com/unts",
+  "funding": "https://opencollective.com/eslint-import-contex",
path: package.json
user: login: ellipsis-dev[bot]
body: Typo in funding URL: 'eslint-import-contex' appears to be missing the final 't'.
```suggestion
  "funding": "https://opencollective.com/eslint-import-context",
```

created_at: 2025-05-24T15:33:48Z
author_association: NONE
diff_hunk: @@ -1,3 +1,19 @@
-export default function echo() {
-  return 'Hello World!'
+import type { ChildContext, RuleContext } from './types.js'
+
+export type * from './types.js'
path: src/index.ts
user: login: ellipsis-dev[bot]
body: The syntax `export type * from "./types.js"` may be invalid. Consider using `export * from "./types.js"` or a valid type-only export syntax.

created_at: 2025-05-24T15:33:48Z
author_association: NONE
diff_hunk: @@ -1,11 +1,11 @@
 {
-  "name": "lib-boilerplate",
+  "name": "eslint-import-context",
   "version": "0.0.0",
   "type": "module",
-  "description": "A simple library boilerplate.",
-  "repository": "git+https://github.com/un-ts/lib-boilerplate.git",
+  "description": "Provide context info for eslint-plugin-import-x, so no extra arguments need to be added.",
+  "repository": "git+https://github.com/un-ts/eslint-import-context.git",
   "author": "JounQin <admin@1stg.me> (https://www.1stG.me)",
-  "funding": "https://opencollective.com/unts",
+  "funding": "https://opencollective.com/eslint-import-contex",
path: package.json
user: login: Copilot
body: There is a typo in the funding URL: `eslint-import-contex` should be `eslint-import-context`.
```suggestion
  "funding": "https://opencollective.com/eslint-import-context",
```
created_at: 2025-05-24T15:33:51Z
author_association: NONE
diff_hunk: @@ -32,22 +32,22 @@ A simple library boilerplate.
 
 ```sh
 # pnpm
-pnpm add lib-boilerplate
+pnpm add eslint-import-context
 
 # yarn
-yarn add lib-boilerplate
+yarn add eslint-import-context
 
 # npm
-npm i lib-boilerplate
+npm i eslint-import-context
 
 # bun
-bun add lib-boilerplate
+bun add eslint-import-context
 ```
 
 ### API
 
 ```js
-import echo from 'lib-boilerplate'
+import echo from 'eslint-import-context'
 
 echo()
path: README.md
user: login: Copilot
body: [nitpick] The example still references the removed `echo` export. Update the usage section to reflect the new API (`setRuleContext` and `useRuleContext`).
```suggestion
import { setRuleContext, useRuleContext } from 'eslint-import-context';

// Set the rule context
setRuleContext({
  key: 'value',
});

// Use the rule context
const context = useRuleContext();
console.log(context);
```
created_at: 2025-05-24T15:33:51Z
author_association: NONE
diff_hunk: @@ -1,3 +1,19 @@
-export default function echo() {
-  return 'Hello World!'
+import type { ChildContext, RuleContext } from './types.js'
+
+export type * from './types.js'
path: src/index.ts
user: login: ellipsis-dev[bot]
body: Line 3 appears to contain a typographical error in the export statement.

The statement `export type * from './types.js'` is not valid TypeScript syntax. If the intent is to re-export everything from the module, consider using `export * from './types.js'` instead.
```suggestion
export * from './types.js'
```

created_at: 2025-05-24T15:37:44Z
author_association: NONE
diff_hunk: @@ -0,0 +1,158 @@
+import type { TSESLint } from '@typescript-eslint/utils'
+import type { KebabCase, LiteralUnion } from 'type-fest'
+import type { NapiResolveOptions } from 'unrs-resolver'
+
+import type { PluginName } from './utils.js'
+
+export type FileExtension = `.${string}`
+
+export type DocStyle = 'jsdoc' | 'tomdoc'
+
+export interface ResultNotFound {
+  found: false
+  // eslint-disable-next-line sonarjs/no-redundant-optional
+  path?: undefined
+}
+
+export interface ResultFound {
+  found: true
+  path: string | null
+}
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export type NewResolverResolve = (
+  modulePath: string,
+  sourceFile: string,
+) => ResolvedResult
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export interface NewResolver {
+  interfaceVersion: 3
+  /** Optional name for the resolver, this is used in logs/debug output */
+  name?: string
+  resolve: NewResolverResolve
+}
+
+export type Resolver = LegacyResolver | NewResolver
+
+export type ResolvedResult = ResultFound | ResultNotFound
+
+export interface NodeResolverOptions {
+  extensions?: readonly string[]
+  moduleDirectory?: string[]
+  paths?: string[]
+}
+
+export interface WebpackResolverOptions {
+  config?: string | { resolve: NapiResolveOptions }
+  'config-index'?: number
+  env?: Record<string, unknown>
+  argv?: Record<string, unknown>
+}
+
+export interface TsResolverOptions extends NapiResolveOptions {
+  alwaysTryTypes?: boolean
+  project?: string[] | string
+  extensions?: string[]
+}
+
+export type LegacyResolverName = LiteralUnion<
+  'node' | 'typescript' | 'webpack',
+  string
+>
+
+export type LegacyResolverResolveImport<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => string | undefined
+
+export type LegacyResolverResolve<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => ResolvedResult
+
+export interface LegacyResolver<T = unknown, U = T> {
+  interfaceVersion?: 1 | 2
+  resolve: LegacyResolverResolve<T>
+  resolveImport: LegacyResolverResolveImport<U>
+}
+
+export interface LegacyResolverObject {
+  // node, typescript, webpack...
+  name: LegacyResolverName
+
+  // Enabled by default
+  enable?: boolean
+
+  // Options passed to the resolver
+  options?:
+    | NodeResolverOptions
+    | TsResolverOptions
+    | WebpackResolverOptions
+    // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+    | {}
+
path: src/types.ts
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Replace the banned `{}` type with a more specific type.**

The static analysis correctly flagged the use of `{}` as a type, which means "any non-nullable value" and should be avoided.



Apply this diff to use a more specific type:

```diff
  options?:
    | NodeResolverOptions
    | TsResolverOptions
    | WebpackResolverOptions
-    // eslint-disable-next-line @typescript-eslint/no-empty-object-type
-    | {}
+    | Record<string, unknown>
```

This provides better type safety while maintaining the flexibility to accept additional resolver options.


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
  options?:
    | NodeResolverOptions
    | TsResolverOptions
    | WebpackResolverOptions
    | Record<string, unknown>
```

</details>

<!-- suggestion_end -->

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 Biome (1.9.4)</summary>

[error] 95-95: Don't use '{}' as a type.

Prefer explicitly define the object shape. '{}' means "any non-nullable value".

(lint/complexity/noBannedTypes)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In src/types.ts around lines 90 to 96, replace the banned empty object type `{}`
with a more specific type that better represents additional resolver options.
Identify or define a suitable interface or type alias that captures the intended
shape or flexibility of these options, and use that instead of `{}` to improve
type safety while preserving flexibility.
```

</details>

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-05-24T15:45:16Z
author_association: NONE
diff_hunk: @@ -0,0 +1,51 @@
+import path from 'node:path'
+
+import { getTsconfig } from 'get-tsconfig'
+import type { TsConfigJsonResolved, TsConfigResult } from 'get-tsconfig'
+import { stableHash } from 'stable-hash'
+
+import type { ChildContext, RuleContext } from './types.js'
+
+export const pluginName = 'import-x'
+
+export type PluginName = typeof pluginName
+
+const tsconfigCache = new Map<string, TsConfigJsonResolved | null | undefined>()
+
+// eslint-disable-next-line sonarjs/cognitive-complexity
+export function getTsconfigWithContext(context: ChildContext | RuleContext) {
+  const parserOptions =
+    context.languageOptions?.parserOptions || context.parserOptions
+  let tsconfigRootDir = parserOptions?.tsconfigRootDir
+  const project = parserOptions?.project
+  const cacheKey = stableHash([tsconfigRootDir, project])
+  let tsConfig: TsConfigJsonResolved | null | undefined
+  if (tsconfigCache.has(cacheKey)) {
+    tsConfig = tsconfigCache.get(cacheKey)!
path: src/utils.ts
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Risky use of non-null assertion operator.**

The non-null assertion operator (`!`) is used when getting from cache, but the cache can contain `null` or `undefined` values. This could lead to runtime errors if the cached value is falsy.



```diff
-    tsConfig = tsconfigCache.get(cacheKey)!
+    tsConfig = tsconfigCache.get(cacheKey)
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
    tsConfig = tsconfigCache.get(cacheKey)
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In src/utils.ts at line 24, avoid using the non-null assertion operator when
retrieving tsConfig from tsconfigCache because the cache may contain null or
undefined values. Instead, add a check to verify that the retrieved value is not
null or undefined before using it, and handle the case where the value is
missing to prevent runtime errors.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commit 229c091
created_at: 2025-05-24T15:45:17Z
author_association: NONE
diff_hunk: @@ -0,0 +1,51 @@
+import path from 'node:path'
+
+import { getTsconfig } from 'get-tsconfig'
+import type { TsConfigJsonResolved, TsConfigResult } from 'get-tsconfig'
+import { stableHash } from 'stable-hash'
+
+import type { ChildContext, RuleContext } from './types.js'
+
+export const pluginName = 'import-x'
+
+export type PluginName = typeof pluginName
+
+const tsconfigCache = new Map<string, TsConfigJsonResolved | null | undefined>()
+
+// eslint-disable-next-line sonarjs/cognitive-complexity
+export function getTsconfigWithContext(context: ChildContext | RuleContext) {
+  const parserOptions =
+    context.languageOptions?.parserOptions || context.parserOptions
+  let tsconfigRootDir = parserOptions?.tsconfigRootDir
+  const project = parserOptions?.project
+  const cacheKey = stableHash([tsconfigRootDir, project])
+  let tsConfig: TsConfigJsonResolved | null | undefined
+  if (tsconfigCache.has(cacheKey)) {
+    tsConfig = tsconfigCache.get(cacheKey)!
+  } else {
+    tsconfigRootDir =
+      tsconfigRootDir ||
+      // eslint-disable-line sonarjs/todo-tag -- TODO: uncomment in next major
+      // || context.cwd
+      process.cwd()
+    let tsconfigResult: TsConfigResult | null | undefined
+    if (project) {
+      const projects = Array.isArray(project) ? project : [project]
+      for (const project of projects) {
+        tsconfigResult = getTsconfig(
+          project === true
+            ? context.physicalFilename
+            : path.resolve(tsconfigRootDir, project),
+        )
+        if (tsconfigResult) {
+          break
+        }
+      }
path: src/utils.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Variable shadowing creates confusion.**

The loop variable `project` shadows the outer `project` variable from line 20, making the code harder to read and potentially error-prone.



```diff
-      for (const project of projects) {
+      for (const projectPath of projects) {
         tsconfigResult = getTsconfig(
-          project === true
+          projectPath === true
             ? context.physicalFilename
-            : path.resolve(tsconfigRootDir, project),
+            : path.resolve(tsconfigRootDir, projectPath),
         )
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
      for (const projectPath of projects) {
        tsconfigResult = getTsconfig(
          projectPath === true
            ? context.physicalFilename
            : path.resolve(tsconfigRootDir, projectPath),
        )
        if (tsconfigResult) {
          break
        }
      }
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In src/utils.ts around lines 34 to 43, the loop variable named 'project' shadows
an outer variable with the same name declared around line 20, causing confusion.
Rename the loop variable to a distinct name, such as 'proj' or 'currentProject',
to avoid shadowing and improve code clarity. Update all references inside the
loop accordingly.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-24T15:45:17Z
author_association: NONE
diff_hunk: @@ -0,0 +1,51 @@
+import path from 'node:path'
+
+import { getTsconfig } from 'get-tsconfig'
+import type { TsConfigJsonResolved, TsConfigResult } from 'get-tsconfig'
+import { stableHash } from 'stable-hash'
+
+import type { ChildContext, RuleContext } from './types.js'
+
+export const pluginName = 'import-x'
+
+export type PluginName = typeof pluginName
+
+const tsconfigCache = new Map<string, TsConfigJsonResolved | null | undefined>()
+
+// eslint-disable-next-line sonarjs/cognitive-complexity
+export function getTsconfigWithContext(context: ChildContext | RuleContext) {
+  const parserOptions =
+    context.languageOptions?.parserOptions || context.parserOptions
+  let tsconfigRootDir = parserOptions?.tsconfigRootDir
+  const project = parserOptions?.project
+  const cacheKey = stableHash([tsconfigRootDir, project])
+  let tsConfig: TsConfigJsonResolved | null | undefined
+  if (tsconfigCache.has(cacheKey)) {
+    tsConfig = tsconfigCache.get(cacheKey)!
+  } else {
+    tsconfigRootDir =
+      tsconfigRootDir ||
+      // eslint-disable-line sonarjs/todo-tag -- TODO: uncomment in next major
+      // || context.cwd
+      process.cwd()
+    let tsconfigResult: TsConfigResult | null | undefined
+    if (project) {
+      const projects = Array.isArray(project) ? project : [project]
+      for (const project of projects) {
+        tsconfigResult = getTsconfig(
+          project === true
+            ? context.physicalFilename
+            : path.resolve(tsconfigRootDir, project),
+        )
+        if (tsconfigResult) {
+          break
+        }
+      }
+    } else {
+      tsconfigResult = getTsconfig(tsconfigRootDir)
+    }
+    tsConfig = tsconfigResult?.config
+    tsconfigCache.set(cacheKey, tsConfig)
+  }
+  return tsConfig
+}
path: src/utils.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Consider error handling for getTsconfig calls.**

The function doesn't handle potential errors from `getTsconfig()` calls. If the function throws (e.g., due to invalid file paths or permissions), it could crash the ESLint process.



Consider wrapping `getTsconfig` calls in try-catch blocks:

```diff
       for (const projectPath of projects) {
-        tsconfigResult = getTsconfig(
-          projectPath === true
-            ? context.physicalFilename
-            : path.resolve(tsconfigRootDir, projectPath),
-        )
+        try {
+          tsconfigResult = getTsconfig(
+            projectPath === true
+              ? context.physicalFilename
+              : path.resolve(tsconfigRootDir, projectPath),
+          )
+        } catch {
+          // Continue to next project if this one fails
+          continue
+        }
         if (tsconfigResult) {
           break
         }
       }
     } else {
-      tsconfigResult = getTsconfig(tsconfigRootDir)
+      try {
+        tsconfigResult = getTsconfig(tsconfigRootDir)
+      } catch {
+        // Set to null if resolution fails
+        tsconfigResult = null
+      }
     }
```


> Committable suggestion skipped: line range outside the PR's diff.

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In src/utils.ts between lines 15 and 51, the calls to getTsconfig are not
wrapped in error handling, which can cause the ESLint process to crash if
getTsconfig throws an error. To fix this, wrap each call to getTsconfig inside a
try-catch block, catching any errors and handling them gracefully (e.g., logging
or ignoring) to prevent the function from throwing and crashing the process.
```

</details>

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-05-24T15:45:17Z
author_association: NONE
diff_hunk: @@ -0,0 +1,158 @@
+import type { TSESLint } from '@typescript-eslint/utils'
+import type { KebabCase, LiteralUnion } from 'type-fest'
+import type { NapiResolveOptions } from 'unrs-resolver'
+
+import type { PluginName } from './utils.js'
+
+export type FileExtension = `.${string}`
+
+export type DocStyle = 'jsdoc' | 'tomdoc'
+
+export interface ResultNotFound {
+  found: false
+  // eslint-disable-next-line sonarjs/no-redundant-optional
+  path?: undefined
+}
+
+export interface ResultFound {
+  found: true
+  path: string | null
+}
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export type NewResolverResolve = (
+  modulePath: string,
+  sourceFile: string,
+) => ResolvedResult
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export interface NewResolver {
+  interfaceVersion: 3
+  /** Optional name for the resolver, this is used in logs/debug output */
+  name?: string
+  resolve: NewResolverResolve
+}
+
+export type Resolver = LegacyResolver | NewResolver
+
+export type ResolvedResult = ResultFound | ResultNotFound
+
+export interface NodeResolverOptions {
+  extensions?: readonly string[]
+  moduleDirectory?: string[]
+  paths?: string[]
+}
+
+export interface WebpackResolverOptions {
+  config?: string | { resolve: NapiResolveOptions }
+  'config-index'?: number
+  env?: Record<string, unknown>
+  argv?: Record<string, unknown>
+}
+
+export interface TsResolverOptions extends NapiResolveOptions {
+  alwaysTryTypes?: boolean
+  project?: string[] | string
+  extensions?: string[]
+}
+
+export type LegacyResolverName = LiteralUnion<
+  'node' | 'typescript' | 'webpack',
+  string
+>
+
+export type LegacyResolverResolveImport<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => string | undefined
+
+export type LegacyResolverResolve<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => ResolvedResult
+
+export interface LegacyResolver<T = unknown, U = T> {
+  interfaceVersion?: 1 | 2
+  resolve: LegacyResolverResolve<T>
+  resolveImport: LegacyResolverResolveImport<U>
+}
+
+export interface LegacyResolverObject {
+  // node, typescript, webpack...
+  name: LegacyResolverName
+
+  // Enabled by default
+  enable?: boolean
+
+  // Options passed to the resolver
+  options?:
+    | NodeResolverOptions
+    | TsResolverOptions
+    | WebpackResolverOptions
+    // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+    | {}
+
path: src/types.ts
user: login: JounQin
body: It's intended to support all other types like `true`
created_at: 2025-05-24T15:47:43Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,158 @@
+import type { TSESLint } from '@typescript-eslint/utils'
+import type { KebabCase, LiteralUnion } from 'type-fest'
+import type { NapiResolveOptions } from 'unrs-resolver'
+
+import type { PluginName } from './utils.js'
+
+export type FileExtension = `.${string}`
+
+export type DocStyle = 'jsdoc' | 'tomdoc'
+
+export interface ResultNotFound {
+  found: false
+  // eslint-disable-next-line sonarjs/no-redundant-optional
+  path?: undefined
+}
+
+export interface ResultFound {
+  found: true
+  path: string | null
+}
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export type NewResolverResolve = (
+  modulePath: string,
+  sourceFile: string,
+) => ResolvedResult
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export interface NewResolver {
+  interfaceVersion: 3
+  /** Optional name for the resolver, this is used in logs/debug output */
+  name?: string
+  resolve: NewResolverResolve
+}
+
+export type Resolver = LegacyResolver | NewResolver
+
+export type ResolvedResult = ResultFound | ResultNotFound
+
+export interface NodeResolverOptions {
+  extensions?: readonly string[]
+  moduleDirectory?: string[]
+  paths?: string[]
+}
+
+export interface WebpackResolverOptions {
+  config?: string | { resolve: NapiResolveOptions }
+  'config-index'?: number
+  env?: Record<string, unknown>
+  argv?: Record<string, unknown>
+}
+
+export interface TsResolverOptions extends NapiResolveOptions {
+  alwaysTryTypes?: boolean
+  project?: string[] | string
+  extensions?: string[]
+}
+
+export type LegacyResolverName = LiteralUnion<
+  'node' | 'typescript' | 'webpack',
+  string
+>
+
+export type LegacyResolverResolveImport<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => string | undefined
+
+export type LegacyResolverResolve<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => ResolvedResult
+
+export interface LegacyResolver<T = unknown, U = T> {
+  interfaceVersion?: 1 | 2
+  resolve: LegacyResolverResolve<T>
+  resolveImport: LegacyResolverResolveImport<U>
+}
+
+export interface LegacyResolverObject {
+  // node, typescript, webpack...
+  name: LegacyResolverName
+
+  // Enabled by default
+  enable?: boolean
+
+  // Options passed to the resolver
+  options?:
+    | NodeResolverOptions
+    | TsResolverOptions
+    | WebpackResolverOptions
+    // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+    | {}
+
path: src/types.ts
user: login: coderabbitai[bot]
body: @JounQin Thanks for the clarification! You're absolutely right - `Record<string, unknown>` would be too restrictive since it only accepts object types, but you need to support primitive types like `true` for resolver configuration flags.

The `{}` type is indeed appropriate here since it accepts all non-nullable values (objects, primitives, etc.), which aligns with the flexible nature of resolver options in the ESLint ecosystem.

If you ever wanted to be more explicit about accepting any type, you could consider `unknown`, but your current approach with the ESLint disable comment clearly documents the intention.

---

<details>
<summary>✏️ Learnings added</summary>

```
Learnt from: JounQin
PR: un-ts/eslint-import-context#2
File: src/types.ts:90-96
Timestamp: 2025-05-24T15:48:33.853Z
Learning: In ESLint resolver configurations, the `options` field for `LegacyResolverObject` in `src/types.ts` intentionally uses the `{}` type to support flexible resolver options including primitive types like boolean `true`, not just object-shaped values. This is why `Record<string, unknown>` would be too restrictive.
```

> Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).

</details>


<!-- <agentComponentType>chat-answer</agentComponentType> -->

<!-- <rawResChunk><answer>@JounQin Thanks for the clarification! You're absolutely right - `Record<string, unknown>` would be too restrictive since it only accepts object types, but you need to support primitive types like `true` for resolver configuration flags.

The `{}` type is indeed appropriate here since it accepts all non-nullable values (objects, primitives, etc.), which aligns with the flexible nature of resolver options in the ESLint ecosystem.

If you ever wanted to be more explicit about accepting any type, you could consider `unknown`, but your current approach with the ESLint disable comment clearly documents the intention.

---

<details>
<summary>✏️ Learnings added</summary>

```
Learnt from: JounQin
PR: un-ts/eslint-import-context#2
File: src/types.ts:90-96
Timestamp: 2025-05-24T15:48:33.853Z
Learning: In ESLint resolver configurations, the `options` field for `LegacyResolverObject` in `src/types.ts` intentionally uses the `{}` type to support flexible resolver options including primitive types like boolean `true`, not just object-shaped values. This is why `Record<string, unknown>` would be too restrictive.
```

> Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).

</details>

</answer></rawResChunk> -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-05-24T15:48:35Z
author_association: NONE
diff_hunk: @@ -0,0 +1,51 @@
+import path from 'node:path'
+
+import { getTsconfig } from 'get-tsconfig'
+import type { TsConfigJsonResolved, TsConfigResult } from 'get-tsconfig'
+import { stableHash } from 'stable-hash'
+
+import type { ChildContext, RuleContext } from './types.js'
+
+export const pluginName = 'import-x'
+
+export type PluginName = typeof pluginName
+
+const tsconfigCache = new Map<string, TsConfigJsonResolved | null | undefined>()
+
+// eslint-disable-next-line sonarjs/cognitive-complexity
+export function getTsconfigWithContext(context: ChildContext | RuleContext) {
+  const parserOptions =
+    context.languageOptions?.parserOptions || context.parserOptions
+  let tsconfigRootDir = parserOptions?.tsconfigRootDir
+  const project = parserOptions?.project
+  const cacheKey = stableHash([tsconfigRootDir, project])
+  let tsConfig: TsConfigJsonResolved | null | undefined
+  if (tsconfigCache.has(cacheKey)) {
+    tsConfig = tsconfigCache.get(cacheKey)!
+  } else {
+    tsconfigRootDir =
+      tsconfigRootDir ||
+      // eslint-disable-line sonarjs/todo-tag -- TODO: uncomment in next major
+      // || context.cwd
+      process.cwd()
+    let tsconfigResult: TsConfigResult | null | undefined
+    if (project) {
+      const projects = Array.isArray(project) ? project : [project]
+      for (const project of projects) {
+        tsconfigResult = getTsconfig(
+          project === true
+            ? context.physicalFilename
+            : path.resolve(tsconfigRootDir, project),
+        )
+        if (tsconfigResult) {
+          break
+        }
+      }
+    } else {
+      tsconfigResult = getTsconfig(tsconfigRootDir)
+    }
+    tsConfig = tsconfigResult?.config
+    tsconfigCache.set(cacheKey, tsConfig)
+  }
+  return tsConfig
+}
path: src/utils.ts
user: login: JounQin
body: We want to notice users their invalid configs.
created_at: 2025-05-24T15:52:37Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,51 @@
+import path from 'node:path'
+
+import { getTsconfig } from 'get-tsconfig'
+import type { TsConfigJsonResolved, TsConfigResult } from 'get-tsconfig'
+import { stableHash } from 'stable-hash'
+
+import type { ChildContext, RuleContext } from './types.js'
+
+export const pluginName = 'import-x'
+
+export type PluginName = typeof pluginName
+
+const tsconfigCache = new Map<string, TsConfigJsonResolved | null | undefined>()
+
+// eslint-disable-next-line sonarjs/cognitive-complexity
+export function getTsconfigWithContext(context: ChildContext | RuleContext) {
+  const parserOptions =
+    context.languageOptions?.parserOptions || context.parserOptions
+  let tsconfigRootDir = parserOptions?.tsconfigRootDir
+  const project = parserOptions?.project
+  const cacheKey = stableHash([tsconfigRootDir, project])
+  let tsConfig: TsConfigJsonResolved | null | undefined
+  if (tsconfigCache.has(cacheKey)) {
+    tsConfig = tsconfigCache.get(cacheKey)!
+  } else {
+    tsconfigRootDir =
+      tsconfigRootDir ||
+      // eslint-disable-line sonarjs/todo-tag -- TODO: uncomment in next major
+      // || context.cwd
+      process.cwd()
+    let tsconfigResult: TsConfigResult | null | undefined
+    if (project) {
+      const projects = Array.isArray(project) ? project : [project]
+      for (const project of projects) {
+        tsconfigResult = getTsconfig(
+          project === true
+            ? context.physicalFilename
+            : path.resolve(tsconfigRootDir, project),
+        )
+        if (tsconfigResult) {
+          break
+        }
+      }
+    } else {
+      tsconfigResult = getTsconfig(tsconfigRootDir)
+    }
+    tsConfig = tsconfigResult?.config
+    tsconfigCache.set(cacheKey, tsConfig)
+  }
+  return tsConfig
+}
path: src/utils.ts
user: login: coderabbitai[bot]
body: @JounQin, that makes perfect sense! For an ESLint plugin, it's better to fail fast and provide clear feedback about configuration issues rather than silently handling errors. Users should be notified when their TypeScript configurations are invalid so they can fix them properly.

Thank you for clarifying the intended behavior - letting `getTsconfig` throw errors ensures users get immediate feedback about misconfigured TypeScript projects.

---

<details>
<summary>✏️ Learnings added</summary>

```
Learnt from: JounQin
PR: un-ts/eslint-import-context#2
File: src/utils.ts:15-51
Timestamp: 2025-05-24T15:52:59.431Z
Learning: In the eslint-import-context project, getTsconfig calls should not be wrapped in try-catch blocks. The team prefers to let configuration errors bubble up to notify users about invalid TypeScript configurations rather than gracefully handling them silently.
```

> Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).

</details>


<!-- <agentComponentType>chat-answer</agentComponentType> -->

<!-- <rawResChunk><answer>@JounQin, that makes perfect sense! For an ESLint plugin, it's better to fail fast and provide clear feedback about configuration issues rather than silently handling errors. Users should be notified when their TypeScript configurations are invalid so they can fix them properly.

Thank you for clarifying the intended behavior - letting `getTsconfig` throw errors ensures users get immediate feedback about misconfigured TypeScript projects.

---

<details>
<summary>✏️ Learnings added</summary>

```
Learnt from: JounQin
PR: un-ts/eslint-import-context#2
File: src/utils.ts:15-51
Timestamp: 2025-05-24T15:52:59.431Z
Learning: In the eslint-import-context project, getTsconfig calls should not be wrapped in try-catch blocks. The team prefers to let configuration errors bubble up to notify users about invalid TypeScript configurations rather than gracefully handling them silently.
```

> Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).

</details>

</answer></rawResChunk> -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-05-24T15:53:00Z
author_association: NONE
diff_hunk: @@ -0,0 +1,158 @@
+import type { TSESLint } from '@typescript-eslint/utils'
+import type { KebabCase, LiteralUnion } from 'type-fest'
+import type { NapiResolveOptions } from 'unrs-resolver'
+
+import type { PluginName } from './utils.js'
+
+export type FileExtension = `.${string}`
+
+export type DocStyle = 'jsdoc' | 'tomdoc'
+
+export interface ResultNotFound {
+  found: false
+  // eslint-disable-next-line sonarjs/no-redundant-optional
+  path?: undefined
+}
+
+export interface ResultFound {
+  found: true
+  path: string | null
+}
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export type NewResolverResolve = (
+  modulePath: string,
+  sourceFile: string,
+) => ResolvedResult
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export interface NewResolver {
+  interfaceVersion: 3
+  /** Optional name for the resolver, this is used in logs/debug output */
+  name?: string
+  resolve: NewResolverResolve
+}
+
+export type Resolver = LegacyResolver | NewResolver
+
+export type ResolvedResult = ResultFound | ResultNotFound
+
+export interface NodeResolverOptions {
+  extensions?: readonly string[]
+  moduleDirectory?: string[]
+  paths?: string[]
+}
+
+export interface WebpackResolverOptions {
+  config?: string | { resolve: NapiResolveOptions }
+  'config-index'?: number
+  env?: Record<string, unknown>
+  argv?: Record<string, unknown>
+}
+
+export interface TsResolverOptions extends NapiResolveOptions {
+  alwaysTryTypes?: boolean
+  project?: string[] | string
+  extensions?: string[]
+}
+
+export type LegacyResolverName = LiteralUnion<
+  'node' | 'typescript' | 'webpack',
+  string
+>
+
+export type LegacyResolverResolveImport<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => string | undefined
+
+export type LegacyResolverResolve<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => ResolvedResult
+
+export interface LegacyResolver<T = unknown, U = T> {
+  interfaceVersion?: 1 | 2
+  resolve: LegacyResolverResolve<T>
+  resolveImport: LegacyResolverResolveImport<U>
+}
+
+export interface LegacyResolverObject {
+  // node, typescript, webpack...
+  name: LegacyResolverName
+
+  // Enabled by default
+  enable?: boolean
+
+  // Options passed to the resolver
+  options?:
+    | NodeResolverOptions
+    | TsResolverOptions
+    | WebpackResolverOptions
+    // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+    | {}
+
path: src/types.ts
user: login: JounQin
body: `unknown` would make the whole type `unknown`.
created_at: 2025-05-24T15:53:43Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,158 @@
+import type { TSESLint } from '@typescript-eslint/utils'
+import type { KebabCase, LiteralUnion } from 'type-fest'
+import type { NapiResolveOptions } from 'unrs-resolver'
+
+import type { PluginName } from './utils.js'
+
+export type FileExtension = `.${string}`
+
+export type DocStyle = 'jsdoc' | 'tomdoc'
+
+export interface ResultNotFound {
+  found: false
+  // eslint-disable-next-line sonarjs/no-redundant-optional
+  path?: undefined
+}
+
+export interface ResultFound {
+  found: true
+  path: string | null
+}
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export type NewResolverResolve = (
+  modulePath: string,
+  sourceFile: string,
+) => ResolvedResult
+
+// eslint-disable-line sonarjs/todo-tag -- TODO: remove prefix New in the next major version
+export interface NewResolver {
+  interfaceVersion: 3
+  /** Optional name for the resolver, this is used in logs/debug output */
+  name?: string
+  resolve: NewResolverResolve
+}
+
+export type Resolver = LegacyResolver | NewResolver
+
+export type ResolvedResult = ResultFound | ResultNotFound
+
+export interface NodeResolverOptions {
+  extensions?: readonly string[]
+  moduleDirectory?: string[]
+  paths?: string[]
+}
+
+export interface WebpackResolverOptions {
+  config?: string | { resolve: NapiResolveOptions }
+  'config-index'?: number
+  env?: Record<string, unknown>
+  argv?: Record<string, unknown>
+}
+
+export interface TsResolverOptions extends NapiResolveOptions {
+  alwaysTryTypes?: boolean
+  project?: string[] | string
+  extensions?: string[]
+}
+
+export type LegacyResolverName = LiteralUnion<
+  'node' | 'typescript' | 'webpack',
+  string
+>
+
+export type LegacyResolverResolveImport<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => string | undefined
+
+export type LegacyResolverResolve<T = unknown> = (
+  modulePath: string,
+  sourceFile: string,
+  config: T,
+) => ResolvedResult
+
+export interface LegacyResolver<T = unknown, U = T> {
+  interfaceVersion?: 1 | 2
+  resolve: LegacyResolverResolve<T>
+  resolveImport: LegacyResolverResolveImport<U>
+}
+
+export interface LegacyResolverObject {
+  // node, typescript, webpack...
+  name: LegacyResolverName
+
+  // Enabled by default
+  enable?: boolean
+
+  // Options passed to the resolver
+  options?:
+    | NodeResolverOptions
+    | TsResolverOptions
+    | WebpackResolverOptions
+    // eslint-disable-next-line @typescript-eslint/no-empty-object-type
+    | {}
+
path: src/types.ts
user: login: coderabbitai[bot]
body: @JounQin You're absolutely right! That's an excellent point about TypeScript's union type semantics. If I used `unknown` in that union, the entire type would indeed collapse to `unknown` because `unknown` is the top type - any value that could be `NodeResolverOptions`, `TsResolverOptions`, or `WebpackResolverOptions` is also `unknown`.

This would completely eliminate the type safety benefits of having those specific resolver option interfaces, which defeats the whole purpose. The `{}` type is the perfect choice here because it:

1. Accepts all non-nullable values (including primitives like `true`)
2. Preserves the union's specificity for the known resolver types
3. Doesn't cause the union to collapse like `unknown` would

Your original approach is definitely the right solution for this use case!

---

<details>
<summary>✏️ Learnings added</summary>

```
Learnt from: JounQin
PR: un-ts/eslint-import-context#2
File: src/types.ts:90-96
Timestamp: 2025-05-24T15:54:12.428Z
Learning: In TypeScript union types, using `unknown` would cause the entire union to collapse to `unknown` since it's the top type. For the `options` field in `LegacyResolverObject`, the `{}` type is preferred over `unknown` because it maintains type safety for specific resolver options while allowing primitive values like `true`, whereas `unknown` would eliminate all type checking benefits.
```

> Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).

</details>



---

<details>
<summary>🧠 Learnings used</summary>

```
Learnt from: JounQin
PR: un-ts/eslint-import-context#2
File: src/types.ts:90-96
Timestamp: 2025-05-24T15:48:33.853Z
Learning: In ESLint resolver configurations, the `options` field for `LegacyResolverObject` in `src/types.ts` intentionally uses the `{}` type to support flexible resolver options including primitive types like boolean `true`, not just object-shaped values. This is why `Record<string, unknown>` would be too restrictive.
```

</details>


<!-- <agentComponentType>chat-answer</agentComponentType> -->

<!-- <rawResChunk><answer>@JounQin You're absolutely right! That's an excellent point about TypeScript's union type semantics. If I used `unknown` in that union, the entire type would indeed collapse to `unknown` because `unknown` is the top type - any value that could be `NodeResolverOptions`, `TsResolverOptions`, or `WebpackResolverOptions` is also `unknown`.

This would completely eliminate the type safety benefits of having those specific resolver option interfaces, which defeats the whole purpose. The `{}` type is the perfect choice here because it:

1. Accepts all non-nullable values (including primitives like `true`)
2. Preserves the union's specificity for the known resolver types
3. Doesn't cause the union to collapse like `unknown` would

Your original approach is definitely the right solution for this use case!

---

<details>
<summary>✏️ Learnings added</summary>

```
Learnt from: JounQin
PR: un-ts/eslint-import-context#2
File: src/types.ts:90-96
Timestamp: 2025-05-24T15:54:12.428Z
Learning: In TypeScript union types, using `unknown` would cause the entire union to collapse to `unknown` since it's the top type. For the `options` field in `LegacyResolverObject`, the `{}` type is preferred over `unknown` because it maintains type safety for specific resolver options while allowing primitive values like `true`, whereas `unknown` would eliminate all type checking benefits.
```

> Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure [review instructions](https://docs.coderabbit.ai/guides/review-instructions). You can manage existing learnings in the [app](https://app.coderabbit.ai/learnings).

</details>



---

<details>
<summary>🧠 Learnings used</summary>

```
Learnt from: JounQin
PR: un-ts/eslint-import-context#2
File: src/types.ts:90-96
Timestamp: 2025-05-24T15:48:33.853Z
Learning: In ESLint resolver configurations, the `options` field for `LegacyResolverObject` in `src/types.ts` intentionally uses the `{}` type to support flexible resolver options including primitive types like boolean `true`, not just object-shaped values. This is why `Record<string, unknown>` would be too restrictive.
```

</details>

</answer></rawResChunk> -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-05-24T15:54:13Z
author_association: NONE
diff_hunk: @@ -1,3 +1,19 @@
-export default function echo() {
-  return 'Hello World!'
+import type { ChildContext, RuleContext } from './types.js'
+
+export type * from './types.js'
path: src/index.ts
user: login: ellipsis-dev[bot]
body: Typo found: The syntax `export type * from './types.js'` appears incorrect. Possibly you intended to use either `export * from './types.js'` for a full re-export, or `export type { ... } from './types.js'` if re-exporting types. Please review the intended syntax.
```suggestion
export * from './types.js'
```

created_at: 2025-05-24T15:54:57Z
author_association: NONE

PR comments:
user: login: changeset-bot[bot]
created_at: 2025-05-24T15:31:44Z
body: ###  🦋  Changeset detected

Latest commit: 229c0912e8b2bbaebc9d5ff743139d4d4a3d0f3a

**The changes in this PR will be included in the next version bump.**

<details><summary>This PR includes changesets to release 1 package</summary>

  | Name                  | Type  |
| --------------------- | ----- |
| eslint-import-context | Minor |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/un-ts/eslint-import-context/new/feat/work?filename=.changeset/rotten-toes-kick.md&value=---%0A%22eslint-import-context%22%3A%20patch%0A---%0A%0Afeat%3A%20first%20blood%2C%20should%20just%20work%0A)


author_association: NONE
user: login: coderabbitai[bot]
created_at: 2025-05-24T15:31:50Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: rate limited by coderabbit.ai -->

> [!WARNING]
> ## Rate limit exceeded
> 
> @JounQin has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait **8 minutes and 52 seconds** before requesting another review.
> 
> <details>
> <summary>⌛ How to resolve this issue?</summary>
> 
> After the wait time has elapsed, a review can be triggered using the `@coderabbitai review` command as a PR comment. Alternatively, push new commits to this PR.
> 
> We recommend that you space out your commits to avoid hitting the rate limit.
> 
> </details>
> 
> 
> <details>
> <summary>🚦 How do rate limits work?</summary>
> 
> CodeRabbit enforces hourly rate limits for each developer per organization.
> 
> Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.
> 
> Please see our [FAQ](https://docs.coderabbit.ai/faq) for further information.
> 
> </details>
> 
> <details>
> <summary>📥 Commits</summary>
> 
> Reviewing files that changed from the base of the PR and between e1828be284f7bdd1f80d9c1ceb89dc32779c4748 and 229c0912e8b2bbaebc9d5ff743139d4d4a3d0f3a.
> 
> </details>
> 
> <details>
> <summary>⛔ Files ignored due to path filters (1)</summary>
> 
> * `yarn.lock` is excluded by `!**/yarn.lock`, `!**/*.lock`
> 
> </details>
> 
> <details>
> <summary>📒 Files selected for processing (20)</summary>
> 
> * `.changeset/config.json` (1 hunks)
> * `.changeset/yellow-ducks-fold.md` (1 hunks)
> * `.github/workflows/ci.yml` (1 hunks)
> * `.github/workflows/pkg-pr-new.yml` (1 hunks)
> * `.github/workflows/release.yml` (1 hunks)
> * `.size-limit.json` (1 hunks)
> * `CHANGELOG.md` (0 hunks)
> * `README.md` (2 hunks)
> * `package.json` (2 hunks)
> * `src/index.ts` (1 hunks)
> * `src/types.ts` (1 hunks)
> * `src/utils.ts` (1 hunks)
> * `test/basic.spec.ts` (0 hunks)
> * `test/context.spec.ts` (1 hunks)
> * `test/fixtures/tsconfig.json` (1 hunks)
> * `test/utils.spec.ts` (1 hunks)
> * `test/utils.ts` (1 hunks)
> * `tsconfig.eslint.json` (1 hunks)
> * `vercel.json` (1 hunks)
> * `vitest.config.ts` (1 hunks)
> 
> </details>

<!-- end of auto-generated comment: rate limited by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

The project underwent a comprehensive rebranding from "lib-boilerplate" to "eslint-import-context," updating all references in configuration, documentation, and metadata. The core module was refactored to provide context management utilities for ESLint rule contexts, replacing the original simple export. New utility and type definition modules were introduced, and tests were updated to validate the new functionality.

## Changes

| File(s)                                                                                       | Change Summary                                                                                                   |
|----------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| `.changeset/config.json`, `.changeset/yellow-ducks-fold.md`                                  | Updated changeset config and added a new changeset for the initial feature.                                      |
| `.github/workflows/ci.yml`, `.github/workflows/pkg-pr-new.yml`, `.github/workflows/release.yml` | CI updated to add Node 24; removed `--compact` flag from publish; release workflow strings updated for new name.  |
| `.size-limit.json`                                                                           | Changed monitored file to TypeScript source and increased size limit.                                             |
| `CHANGELOG.md`                                                                               | Removed all version entries, leaving only the header.                                                            |
| `README.md`                                                                                  | Rebranded all references, badges, and usage examples to "eslint-import-context."                                 |
| `package.json`                                                                               | Renamed package, updated metadata, and changed size-limit preset dependency.                                     |
| `src/index.ts`                                                                               | Replaced default export with context management utilities and re-exports; removed `echo` function.               |
| `src/types.ts`                                                                               | Added comprehensive type definitions for context, resolvers, and settings.                                       |
| `src/utils.ts`                                                                               | Added utility for resolving tsconfig with context and plugin name constant.                                       |
| `test/basic.spec.ts`                                                                         | Removed the old test for the `echo` function.                                                                    |
| `test/context.spec.ts`, `test/utils.spec.ts`                                                 | Added tests for context management and tsconfig utility.                                                          |
| `test/fixtures/tsconfig.json`                                                                | Added fixture tsconfig for testing.                                                                              |
| `test/utils.ts`                                                                              | Added test utilities for context and file paths.                                                                 |
| `tsconfig.eslint.json`, `vercel.json`, `vitest.config.ts`                                    | Updated aliases and configuration to use the new project name.                                                   |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant Test as Test Suite
    participant Index as src/index.ts
    participant Utils as src/utils.ts
    participant Types as src/types.ts

    Test->>Index: setRuleContext(context, callback)
    Index->>Index: Set ruleContext to context
    Index->>Index: Execute callback()
    Index->>Index: Restore previous ruleContext
    Index->>Test: Return callback result

    Test->>Index: useRuleContext()
    Index->>Test: Return current ruleContext

    Test->>Utils: getTsconfigWithContext(context)
    Utils->>Utils: Check tsconfigCache
    alt Cache miss
        Utils->>Utils: Resolve tsconfig (using get-tsconfig)
        Utils->>Utils: Store in tsconfigCache
    end
    Utils->>Test: Return resolved tsconfig
```

## Poem

> In fields of code, a rabbit hops,  
> From boilerplate to context, the old name drops.  
> With types and utils, the groundwork’s laid,  
> For ESLint rules, context’s now portrayed.  
> Tests now bloom, tsconfigs found—  
> In this new warren, robust code abounds!  
> 🐇✨

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=un-ts/eslint-import-context&utm_content=2):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: codesandbox-ci[bot]
created_at: 2025-05-24T15:32:08Z
body: This pull request is automatically built and testable in [CodeSandbox](https://codesandbox.io).

  To see build info of the built libraries, click [here](https://ci.codesandbox.io/status/un-ts/eslint-import-context/pr/2/builds/619380) or the icon next to each commit SHA.
author_association: NONE
user: login: codecov[bot]
created_at: 2025-05-24T15:32:16Z
body: ## Welcome to [Codecov](https://codecov.io?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=un-ts) :tada:

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered :open_umbrella:
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-24T15:32:34Z
body: Deploy preview for _eslint-import-context_ ready!

✅ Preview
https://eslint-import-context-8t9yzp4qm-1stg.vercel.app

Built with commit 229c0912e8b2bbaebc9d5ff743139d4d4a3d0f3a.
This pull request is being automatically deployed with [vercel-action](https://github.com/marketplace/actions/vercel-action)
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-05-24T15:32:48Z
body: ### 📊 Package size report&nbsp;&nbsp;&nbsp;<kbd>507%↑</kbd>

| File                                                                                         |   Before |                        After |
| -------------------------------------------------------------------------------------------- | -------: | ---------------------------: |
| `lib/index.cjs`                                                                              |  `104 B` | <sup>33,900%↑</sup>`35.4 kB` |
| `lib/index.d.cts`                                                                            |   `99 B` |   <sup>4,760%↑</sup>`4.8 kB` |
| `lib/index.d.ts`                                                                             |   `40 B` |      <sup>778%↑</sup>`351 B` |
| `lib/index.js`                                                                               |   `95 B` |      <sup>266%↑</sup>`348 B` |
| `lib/index.js.map`                                                                           |  `163 B` |      <sup>156%↑</sup>`418 B` |
| `lib/types.d.ts`                                                                             |        — |                     `3.7 kB` |
| `lib/types.js`                                                                               |        — |                       `44 B` |
| `lib/types.js.map`                                                                           |        — |                      `102 B` |
| `lib/utils.d.ts`                                                                             |        — |                      `741 B` |
| `lib/utils.js`                                                                               |        — |                     `1.6 kB` |
| `lib/utils.js.map`                                                                           |        — |                     `1.4 kB` |
| [`package.json`](https://github.com/un-ts/eslint-import-context/blob/feat/work/package.json) | `3.3 kB` |       <sup>3%↑</sup>`3.4 kB` |
| [`README.md`](https://github.com/un-ts/eslint-import-context/blob/feat/work/README.md)       | `4.7 kB` |       <sup>5%↑</sup>`4.9 kB` |
| **Total** <sub>_(Includes all files)_</sub>                                                  | `9.6 kB` |    <sup>507%↑</sup>`58.3 kB` |
| **Tarball size**                                                                             | `3.6 kB` |    <sup>383%↑</sup>`17.3 kB` |

<details><summary>Unchanged files</summary>

| File                                                                               |     Size |
| ---------------------------------------------------------------------------------- | -------: |
| [`LICENSE`](https://github.com/un-ts/eslint-import-context/blob/feat/work/LICENSE) | `1.1 kB` |
</details>



<sub>🤖 This report was automatically generated by [pkg-size-action](https://github.com/pkg-size/action/)</sub>
author_association: CONTRIBUTOR
user: login: pkg-pr-new[bot]
created_at: 2025-05-24T15:33:04Z
body: 
[Open in StackBlitz](https://pkg.pr.new/template/9217dd23-965a-45d4-8cfb-dbe3cdaf6d2c)


```
npm i https://pkg.pr.new/un-ts/eslint-import-context@2
```


_commit: <a href="https://github.com/un-ts/eslint-import-context/runs/42833836800"><code>229c091</code></a>_

author_association: NONE
user: login: github-actions[bot]
created_at: 2025-05-24T15:36:33Z
body: ## size-limit report 📦 
| Path         | Size             |
| ------------ | ---------------- |
| lib/index.js | 0 B (-100% 🔽)   |
| src/index.ts | 184 B (+100% 🔺) |
author_association: CONTRIBUTOR