Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 0 additions & 128 deletions .github/copilot-instructions.md

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ lib-cov
*.tsbuildinfo

**/.vitepress/cache

!tests/fixtures/**/node_modules/
53 changes: 53 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# AGENTS

This repository publishes an ESLint plugin that formats files through oxfmt.

## Start Here

- Project overview and user-facing behavior: [README.md](README.md)
- Runtime entrypoint: [src/index.ts](src/index.ts)
- Main rule implementation: [src/rules/oxfmt.ts](src/rules/oxfmt.ts)
- Worker bridge to oxfmt: [workers/oxfmt.mjs](workers/oxfmt.mjs)
- Preset configs: [src/configs.ts](src/configs.ts)
- Rule schema: [src/schema.ts](src/schema.ts)

## Environment

- Package manager: pnpm
- Node: `^20.19.0 || >=22.12.0`
- Module system: ESM (`"type": "module"`)

## Core Commands

- Install deps: `pnpm install`
- Test: `pnpm test`
- Lint: `pnpm run lint`
- Typecheck: `pnpm run typecheck`
- Schema parity check: `pnpm run check:schema`
- Build: `pnpm run build`
- Full release gate: `pnpm run release:check`

## Editing Guardrails

- Do not hand-edit [dts/rule-options.d.ts](dts/rule-options.d.ts). It is generated by [scripts/updateRuleOptions.ts](scripts/updateRuleOptions.ts).
- If rule options or recommended config change, run `pnpm run update:rule-options` and include the regenerated d.ts output.
- If [src/schema.ts](src/schema.ts) changes, run `pnpm run check:schema` to keep parity with upstream oxfmt schema.
- Keep config/ignore behavior aligned with CLI parity tests in [tests/cli-parity.test.ts](tests/cli-parity.test.ts).

## Behavior That Is Easy To Break

- In [workers/oxfmt.mjs](workers/oxfmt.mjs), when `useConfig` is true, `overrides` come from loaded config; rule-level `overrides` are ignored by design.
- Rule-level `ignorePatterns` can override config-level ignore behavior in specific paths; verify with config-loading and parity fixtures in [tests/fixtures](tests/fixtures).
- In [src/rules/oxfmt.ts](src/rules/oxfmt.ts), processor-extracted virtual files are intentionally skipped to avoid fix ping-pong.

## Test Targets By Change Type

- Rule logic/reporting changes: [tests/rules/oxfmt.test.ts](tests/rules/oxfmt.test.ts), [tests/rules/error-reporting.test.ts](tests/rules/error-reporting.test.ts)
- Config resolution or ignore behavior: [tests/eslint-plugin.test.ts](tests/eslint-plugin.test.ts), [tests/cli-parity.test.ts](tests/cli-parity.test.ts), [tests/configs.test.ts](tests/configs.test.ts)
- Schema changes: [tests/schema-parity.test.ts](tests/schema-parity.test.ts) plus `pnpm run check:schema`

## Preferred Agent Workflow

1. Read [README.md](README.md) for expected external behavior.
2. Make minimal, focused edits in [src](src) or [workers](workers).
3. Run targeted tests first, then run `pnpm run release:check` before finalizing substantial changes.
50 changes: 44 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ export default [
]
```

For CLI-like ignore/config behavior, use `cliParity`:

```js
// eslint.config.mjs
import pluginOxfmt from 'eslint-plugin-oxfmt'

export default [
{
...pluginOxfmt.configs.cliParity,
files: ['**/*.{js,ts,mjs,cjs,jsx,tsx,json,jsonc,yaml,yml}'],
},
]
```

### Custom Configuration

You can customize the formatting options by configuring the rule:
Expand Down Expand Up @@ -157,10 +171,14 @@ All options are optional and default to sensible values.

### Plugin Options

| Option | Type | Default | Description |
| ------------ | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `useConfig` | `boolean` | `true` | Load `.oxfmtrc.json`, `.oxfmtrc.jsonc`, or `oxfmt.config.ts` via `load-oxfmt-config` (with `.editorconfig` merge support). Set to `false` to rely only on inline options. |
| `configPath` | `string` | — | Custom path to an oxfmt config file. Resolved from ESLint `cwd` when set. |
| Option | Type | Default | Description |
| ---------------------------- | -------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `useConfig` | `boolean` | `true` | Load `.oxfmtrc.json`, `.oxfmtrc.jsonc`, or `oxfmt.config.*` via `load-oxfmt-config`. Set to `false` to rely only on inline options. |
| `configPath` | `string` | — | Custom path to an oxfmt config file. Resolved from ESLint `cwd` when set. |
| `ignorePath` | `string \| string[]` | — | Ignore file path(s) for CLI-style ignore resolution (same role as CLI `--ignore-path`). |
| `withNodeModules` | `boolean` | `false` | Include files under `node_modules` during ignore checks. |
| `disableNestedConfig` | `boolean` | `false` | Disable nested config discovery and resolve config from `cwd` / `configPath` only. |
| `respectOxfmtDefaultIgnores` | `boolean` | `true` | Respect oxfmt default ignores (`.gitignore`, `.prettierignore`, default ignored directories, default ignored lockfiles). |

> Note: `cwd` is taken from ESLint automatically; you usually do not need to set it manually.
> `.editorconfig` merge behavior follows oxfmt's documented strategy: https://oxc.rs/docs/guide/usage/formatter/config#editorconfig
Expand All @@ -173,8 +191,9 @@ When `useConfig` is `true`, the plugin loads config using `load-oxfmt-config`.
- `.editorconfig` support: nearest `.editorconfig` (including section overrides) is merged into the final options
- `configPath` overrides discovery and directly targets the specified config file
- ESLint rule options generally take highest priority because inline rule options are merged after loaded config.
- When `useConfig` is `true`, rule-level `overrides` are ignored. Only `overrides` loaded from the resolved oxfmt config file are applied.
- Rule-level `ignorePatterns` still override config-derived `ignorePatterns` when provided.
- Rule-level `ignorePatterns` are resolved relative to ESLint `cwd`; config-level `ignorePatterns` are resolved relative to the resolved config file directory.
- When `useConfig` is `true`, config `overrides` are applied first and rule-level `overrides` are appended after them (later entries win on conflicts).
- When `useConfig` is `false`, config discovery and config `ignorePatterns` are skipped, while global ignores still apply when `respectOxfmtDefaultIgnores` is enabled.

For detailed behavior, see:

Expand Down Expand Up @@ -381,12 +400,31 @@ This plugin provides a single rule that formats your code using oxfmt.
- Fixable: Yes (automatically applies formatting)
- Type: Layout

## CLI parity mode

`oxfmt/cli-parity` tries to match `oxfmt` CLI behavior for files processed by ESLint.

It respects:

- `.oxfmtrc.json`
- `.oxfmtrc.jsonc`
- `oxfmt.config.*`
- `.editorconfig`
- `ignorePatterns`
- `.gitignore`
- `.prettierignore`
- default ignored directories
- default ignored lockfiles

Note: ESLint still controls file discovery. Files excluded by ESLint will never reach this rule.

## Integration

### Parser Compatibility

- `recommended`: forces `eslint-parser-plain` for matched files
- `recommendedWithoutParser`: parser-agnostic (safe to compose with language-specific parsers)
- `cliParity`: parser-agnostic preset tuned for CLI-like config/ignore behavior

When composing shareable configs, prefer `recommendedWithoutParser` if parser ownership belongs to another preset.

Expand Down
8 changes: 8 additions & 0 deletions dts/rule-options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,16 @@ export type OxfmtOxfmt = []|[{

configPath?: string

disableNestedConfig?: boolean

ignorePath?: (string | string[])

respectOxfmtDefaultIgnores?: boolean

useConfig?: boolean

withNodeModules?: boolean

overrides?: {

excludeFiles?: string[]
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "eslint-plugin-oxfmt",
"type": "module",
"version": "0.5.1",
"packageManager": "pnpm@10.33.2",
"packageManager": "pnpm@10.33.4",
"description": "An ESLint plugin for formatting code with oxfmt.",
"keywords": [
"eslint",
Expand Down Expand Up @@ -65,17 +65,17 @@
},
"dependencies": {
"generate-differences": "^0.1.1",
"load-oxfmt-config": "^0.4.1",
"load-oxfmt-config": "^0.7.0",
"picomatch": "^4.0.4",
"synckit": "^0.11.12"
},
"devDependencies": {
"@ntnyq/eslint-config": "^6.1.1",
"@ntnyq/eslint-config": "^6.1.3",
"@types/json-schema": "^7.0.15",
"@types/node": "^25.6.0",
"@typescript/native-preview": "^7.0.0-dev.20260429.1",
"bumpp": "^11.0.1",
"eslint": "^10.2.1",
"@typescript/native-preview": "^7.0.0-dev.20260507.1",
"bumpp": "^11.1.0",
"eslint": "^10.3.0",
"eslint-parser-plain": "^0.1.1",
"eslint-plugin-oxfmt": "workspace:*",
"eslint-typegen": "^2.3.1",
Expand All @@ -84,7 +84,7 @@
"jsonc-eslint-parser": "^3.1.0",
"nano-staged": "^1.0.2",
"npm-run-all2": "^8.0.4",
"oxfmt": "^0.47.0",
"oxfmt": "^0.48.0",
"show-invisibles": "^0.0.2",
"tinyglobby": "^0.2.16",
"tsdown": "^0.21.10",
Expand Down
Loading
Loading