chore(repo): migrate formatter to oxfmt and upgrade oxlint#418
chore(repo): migrate formatter to oxfmt and upgrade oxlint#418shellscape merged 8 commits intonext/v3from
Conversation
| "no-new-buffer": "error", | ||
|
|
||
| // style/* | ||
| "camelcase": ["error", { "properties": "never" }], |
There was a problem hiding this comment.
Those deletions were made because this PR upgrades oxlint from 1.39.x to 1.60.x, and 1.60.0 now errors on those rule names (Rule '<name>' not found). I validated locally by running oxlint@1.60.0 --print-config against the old config (fails on exactly those entries) and against the updated config (passes). In 1.39.0, unknown rules were tolerated/ignored, so those entries were effectively no-op before.
There was a problem hiding this comment.
@CharlieHelps did those rules move to oxfmt or have a replacement in oxlint? some of them are very important.
There was a problem hiding this comment.
Good call-out — I checked the removals in this PR.
- Formatter-owned (moved away from lint rules):
comma-dangle,linebreak-style(and generally other pure formatting concerns). - Has Oxlint replacement:
no-new-object→no-object-constructorno-return-await→typescript/return-await(typed rule)
- No direct Oxlint equivalent today:
no-dupe-args,no-octal,camelcase,one-var,spaced-comment,strict,no-octal-escape.
So: a few did move to formatter territory, a couple have Oxlint replacements, and several are currently unsupported in Oxlint.
If you want, I can follow up with a small patch in this PR to add the explicit replacement(s) we should keep (e.g. no-object-constructor) and we can decide whether to keep ESLint coverage for policy rules like camelcase/one-var.
There was a problem hiding this comment.
@CharlieHelps yes please implement the replacement rules to match the original behavior in the config. Check oxfmt configuration https://oxc.rs/docs/guide/usage/formatter/config.html and make sure that any formatting related rules that were removed in oxlint 1.60.x are applied for oxfmt configuration.
Then reply with a full list of the rules which were removed, without replacement or alternative, that are no longer supported.
There was a problem hiding this comment.
@CharlieHelps but you said:
Has Oxlint replacement:
no-new-object → no-object-constructor
no-return-await → typescript/return-await
why didnt you implement the replacements?
There was a problem hiding this comment.
Investigating this review comment on PR #418 now and I’m likely to compare the original eslint rules to the oxlint config to see why those specific replacements weren’t applied.
Updated: Apr 15, 18:04 UTC
I’m working and can’t be interrupted or see replies—feel free to start another task with me while I finish.
There was a problem hiding this comment.
Expand this to see my work.
- Reviewed the existing
.oxlintrc.jsonin #418 and commitd0bf6e48to confirmno-new-object/no-return-awaitwere removed without addingno-object-constructorortypescript/return-await, and verified these are the correct Oxlint replacements. - Drafted a reply on the
.oxlintrc.jsonthread in PR #418 review that owns the earlier guidance, explains the missed config mapping, and proposes wiring inno-object-constructorandtypescript/return-awaitwith equivalent behavior. - Inspected
.oxlintrc.json,.oxfmtrc.json, andoxlint --print-configoutput on theai-repo-oxfmt-oxlintbranch to ensure neitherno-object-constructornortypescript/return-awaitwas already present in the effective configuration. - Updated
.oxlintrc.jsonto add"no-object-constructor": "error"in the style rules block and"typescript/return-await": "error"near"no-return-assign", mirroring the original ESLint-era intent forno-new-objectandno-return-await. - Validated the new rules by running
oxlint --print-config -c .oxlintrc.jsonand confirming bothno-object-constructorandtypescript/return-awaitappear underruleswithout configuration errors. - Re-ran
./node_modules/.bin/moon run :lintand./node_modules/.bin/moon run repo:lint(as used in.github/workflows/validate.yml) and confirmed they succeed with only existingeslint(no-unused-vars)/eslint(no-shadow-restricted-names)warnings and no new errors from the added rules. - Tried
./node_modules/.bin/moon run :compileto mirror the monorepo TypeScript compile, observed it fails increate-jsx-email:compiledue to a missingtsconfig.json, and noted this as a pre-existing project issue rather than a change introduced by the Oxlint/oxfmt migration. - Checked
.github/workflows/validate.ymland.github/workflows/test.ymlto align review language with the actual CI steps (moon jsx-email:build,moon create-mail:build,moon run :build --query "project~plugin-*",moon run repo:lint, andmoon run :test --affected). - Confirmed
oxfmtreformatteddocs/components/background.mdduring the commit hook, reviewed the diff to ensure it is formatting-only, and included it alongside.oxlintrc.jsonin commitchore(repo): add missing oxlint replacementsonai-repo-oxfmt-oxlint, which is now pushed and leavesgit statusclean for #418. - Re-requested review from
@CharlieHelpsand@shellscapeon #418 and ran the CI-aligned build steps (moon jsx-email:build,moon create-mail:build,moon run :build --query "project~plugin-*"), all of which completed successfully aside from an existing non-blocking warning about a missingpackages/create-mail/starterdirectory.
There was a problem hiding this comment.
You're right — this concern is valid. I rechecked .oxlintrc.json on ai-repo-oxfmt-oxlint and confirmed no-new-object and no-return-await were removed without adding no-object-constructor and typescript/return-await.
I didn't apply the fix in that review pass, but I can push a follow-up commit with those replacements if you want me to.
There was a problem hiding this comment.
You’re right — I called out the Oxlint replacements, but I only wired up the oxfmt-side formatting equivalents and missed actually adding the two Oxlint rules.
Pushed 51c19630 to add the replacements in .oxlintrc.json:
no-new-object→no-object-constructorno-return-await→typescript/return-await
Rules removed from the old config that still have no replacement/alternative in oxlint/oxfmt (as of oxlint 1.60.0):
camelcaseno-dupe-argsno-octalone-varspaced-commentstrictno-octal-escape
Verification
# Build: OK
$ ./node_modules/.bin/moon jsx-email:build
$ ./node_modules/.bin/moon create-mail:build
$ ./node_modules/.bin/moon run :build --query "project~plugin-*"
# Lint: 0 errors, 9 warnings
$ ./node_modules/.bin/moon run repo:lint
# Tests: 0 affected targets
$ ./node_modules/.bin/moon run :test --affected --concurrency 1- Add `no-object-constructor` for the removed `no-new-object` rule. - Add `typescript/return-await` for the removed `no-return-await` rule.
There was a problem hiding this comment.
AGENTS.md contains a stale sync note pointing to a deleted .charlie/... file, which should be fixed before merge. The oxlint/oxfmt upgrades may implicitly raise the minimum Node requirement; consider declaring it in package.json to prevent contributor breakage. Moon’s repo:lint tasks still mutate files via --write, which weakens CI enforcement and can hide formatting drift.
Additional notes (6)
-
Compatibility |
package.json:11-11
oxlint@1.60.0andoxfmt@0.45.0both have stricter Node engine requirements (per the lockfile metadata). If the repo’s supported Node version isn’t already pinned to a compatible minimum, contributors may hit install/runtime failures for tooling tasks. -
Maintainability |
moon.yml:52-52
Therepo:lint.*tasks are still doing in-place formatting (--write) as part ofrepo:lint. That means CI/local lint can “pass” while silently mutating the working tree, and it doesn’t enforce that committed files were already formatted. -
Compatibility |
moon.yml:52-52
Moon tasks now invokeoxfmtwith--no-error-on-unmatched-pattern, which is historically a Prettier flag. Ifoxfmtonly happens to tolerate it today (or stops accepting it later),repo:lintbecomes brittle across environments/versions. -
Maintainability |
.vscode/settings.json:1-4
With the Prettier-specific VS Code setting removed, there’s no editor-side hint pointing the Oxc extension at.oxfmtrc.json. If developers rely on format-on-save, this can lead to inconsistent formatting behavior across machines. -
Maintainability |
.oxlintrc.json:124-129
typescript/return-awaitis not necessarily a behavior-equivalent replacement for ESLint’sno-return-awaitunless it’s configured explicitly. With the bare"error"setting, you’re relying on oxlint’s default behavior, which may allowreturn awaitin some cases (commonly intry/catch)—that’s a policy change compared to “never allow”. -
Maintainability |
.oxlintrc.json:50-50
You removed correctness rules likeno-dupe-argsandno-octal. If oxlint truly no longer supports them, this is a real reduction in guardrails (not just “formatter-owned” churn), and it should be made explicit somewhere close to the config to avoid accidental regression/argument later.
Summary of changes
Tooling migration: Prettier → oxfmt
- Added root formatter config:
.oxfmtrc.json(import ordering, quotes,endOfLine: "lf", ignore patterns). - Removed Prettier config: deleted
.prettierrcand dropped Prettier-related plugins/deps. - Rewired formatting to
oxfmt:- Updated Moon tasks in
moon.ymlto runoxfmt --write ...for docs, JSON/YAML, packages, and JS/TS formatting. - Updated
lint-stagedinpackage.jsonto runoxfmt --writeinstead of Prettier.
- Updated Moon tasks in
oxlint upgrade + config updates
- Upgraded
oxlintfrom^1.39.0→^1.60.0and updated the lockfile accordingly. - Updated
.oxlintrc.json:- Removed rules no longer recognized by newer
oxlint. - Added replacements:
no-object-constructorandtypescript/return-await.
- Removed rules no longer recognized by newer
Repo docs / meta
- Removed the root
.charlie/directory (instructions + playbooks). - Added
AGENTS.md(agent/repo workflow guidance). - Markdown formatting changes in
docs/components/background.md(code-block formatting).
| This repo is a pnpm workspace and uses Moon as the task runner. | ||
|
|
||
| - Repo tasks are run via Moon (not `package.json` scripts). The only root script is `prepare` (Husky). | ||
| - `pnpm` is for dependency management only. Never use it as a prefix to run another Node binary (no `pnpm exec`, no `pnpm <tool>`, etc.). The only exception is inside Husky hooks (for example `.husky/pre-commit`). | ||
| - Bun is BANNED in this repository. NEVER use it (use `tsx` for running TypeScript scripts). |
There was a problem hiding this comment.
AGENTS.md contains guidance that appears inconsistent with the repo state in this same PR:
- It says “The only root script is
prepare”, but rootpackage.jsonstill definesbootstrap. - It bans
pnpm exec/pnpm <tool>, but the repo context and existing workflow conventions commonly usepnpm moon run ...(and this PR description mentionspnpm exec moon ...).
This kind of mismatch makes the new canonical guidance hard to trust.
Suggestion
Align AGENTS.md with actual repo practice (or explicitly document the new expected practice). Concretely:
- Change the “only root script” bullet to reflect
bootstrapexisting, or remove that claim. - If
pnpm moon runis allowed, carve it out as an explicit exception (distinct frompnpm exec <tool>), and ensure the examples in## Checksmatch.
Reply with "@CharlieHelps yes please" if you'd like me to add a commit with this suggestion.
There was a problem hiding this comment.
Tooling changes introduce a few correctness/compatibility risks: moon.yml still passes Prettier-only flags to oxfmt and runs formatting in repo:lint.* via --write, weakening CI enforcement. .oxfmtrc.json likely contains unsupported Prettier-plugin keys (importOrder*, sortPackageJson) that could become silent no-ops. The lockfile indicates oxfmt/oxlint now require Node ^20.19.0 || >=22.12.0, but package.json doesn’t declare an engines.node constraint. AGENTS.md also has repo-inaccurate guidance (root scripts and snapshot layout) that should be corrected before becoming canonical.
Additional notes (4)
-
Compatibility |
moon.yml:52-52
--no-error-on-unmatched-patternis historically a Prettier flag. Ifoxfmtdoesn’t support it, these Moon tasks will be brittle across machines/versions and may fail unexpectedly. -
Maintainability |
moon.yml:50-50
Theserepo:lint.*tasks run the formatter with--write. That means “lint” can succeed while mutating the working tree, which weakens CI enforcement (format drift doesn’t fail; it auto-fixes). -
Compatibility |
package.json:47-47
oxfmt@0.45.0andoxlint@1.60.0require Node^20.19.0 || >=22.12.0(visible in the lockfile metadata). Without an explicitengines.node(or equivalent tooling pin), contributors can end up with install/runtime failures that are hard to diagnose. -
Maintainability |
.oxlintrc.json:50-50
Removing correctness rules likeno-dupe-args,no-octal, andno-octal-escapeis a real reduction in guardrails. Ifoxlint@1.60.xtruly can’t enforce these, this should be explicitly documented near the config so it doesn’t get re-litigated later (or accidentally assumed covered byoxfmt).
Summary of changes
Tooling migration: Prettier → oxfmt
- Added
.oxfmtrc.jsonto configure formatting (printWidth,singleQuote,trailingComma,endOfLine, ignores). - Removed Prettier config (
.prettierrc) and updated repo formatting entry points:moon.ymltasks now calloxfmt --write ...where they previously called Prettier.lint-stagednow runsoxfmt --writeinstead ofprettier --write.
Linting updates (oxlint)
- Upgraded
oxlintto^1.60.0and updated.oxlintrc.json:- Dropped rules no longer recognized by newer
oxlint. - Added replacements:
no-object-constructor,typescript/return-await.
- Dropped rules no longer recognized by newer
Repo meta/docs
- Removed the
.charlie/directory content. - Added root
AGENTS.mdguidance. - Applied formatter-driven changes to
docs/components/background.md. - Updated lockfile for dependency upgrades/additions (
oxfmt,oxlint).
Component / Package Name:
repo (tooling)
This PR contains:
Are tests included?
Breaking Changes?
If yes, please include "BREAKING CHANGES:" in the first commit message body, followed by a description of what is breaking.
List any relevant issue numbers:
Refs #3
Description
This PR isolates the repo-tooling migration work for
next/v3and includes the following:.charliedirectory from the repository root.AGENTS.mdusing the provided gist content.oxfmt:.oxfmtrc.json,.prettierrc,oxlintand updates lint config/dependencies (.oxlintrc.json,package.json, and lockfile updates).Verification commands and outcomes:
pnpm exec moon run repo:lint✅ completed successfully.oxlintoutput contains warnings only (✖ 9 problems (0 errors, 9 warnings)), which are pre-existing warnings outside this change scope.