From a269ca683605d48ea32e3e8639d038d753329f53 Mon Sep 17 00:00:00 2001 From: "bert.hausmans" Date: Thu, 30 Apr 2026 00:07:15 +0200 Subject: [PATCH] chore(tooling): use ESLint as the sole formatter for TS/Vue files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disables Prettier in Cursor / VSCode. ESLint via dbaeumer.vscode-eslint becomes the default formatter for typescript / typescriptreact / javascript / vue files. Save-on-format runs eslint --fix on the file. Motivation: WS-3 session 1b-iii surfaced that Cursor's default formatter (Prettier) was rewriting files on save with a config that mismatched the Crewli ESLint rules (double quotes, semicolons), producing 164-line diffs on intended 5-line edits. The pattern was silently invisible because pnpm lint --fix would reverse Prettier's formatting on the next CI/dev pass — but the working tree noise made small edits unsafe. This commit: - Updates .vscode/settings.json: editor.defaultFormatter is now dbaeumer.vscode-eslint at both the global level and in the per- language blocks ([typescript], [typescriptreact], [javascript], [vue]). Adds eslint.format.enable, eslint.validate, and source.fixAll.eslint to codeActionsOnSave. Sets prettier.enable to false explicitly. Preserves pre-existing settings unchanged (PHP block, editor.tabSize, typescript.preferences, files.associations, search.exclude, eslint.workingDirectories). - Documents the choice in .cursorrules under a new ## Formatter section. The prior [vue] formatter was Vue.volar (not Prettier), but unifying the Vue formatter under ESLint matches the audit's "single source of truth" intent — Volar's formatter and ESLint's vue/* rules historically disagreed on template indentation, and Volar offers no advantage over ESLint for code formatting (we keep Volar as the language server for type-checking via the recommendation in .vscode/extensions.json). .gitignore did not need updating — .vscode/ was already not ignored and the existing settings.json was already tracked. No changes to package.json, pnpm-lock.yaml, .eslintrc.cjs, or any source files. Engineers using Cursor / VSCode need the dbaeumer.vscode-eslint extension installed (already present in .vscode/extensions.json's recommendations). Co-Authored-By: Claude Opus 4.7 --- .cursorrules | 10 ++++++ .vscode/settings.json | 76 +++++++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/.cursorrules b/.cursorrules index 2197aded..2fb568aa 100644 --- a/.cursorrules +++ b/.cursorrules @@ -24,3 +24,13 @@ PHP 8.2 + Laravel 12 | TypeScript + Vue 3 + Vuexy/Vuetify | Pinia + TanStack Que ## Tests - PHPUnit feature test per controller, minimum: 200 + 401 + 403 + +## Formatter + +ESLint is the ONLY formatter for TS/Vue/JS files in this repo. Prettier +is intentionally disabled — `pnpm lint:fix` (or save-on-format with +ESLint extension) is the single source of truth for formatting. + +Save-on-format requires the `dbaeumer.vscode-eslint` extension to be +installed and the editor's default formatter set to it (configured in +`.vscode/settings.json`). diff --git a/.vscode/settings.json b/.vscode/settings.json index a6934100..1e607b84 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,37 +1,57 @@ { "editor.formatOnSave": true, "editor.tabSize": 2, - - "[php]": { - "editor.defaultFormatter": "bmewburn.vscode-intelephense-client", - "editor.tabSize": 4 + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" }, - - "[vue]": { - "editor.defaultFormatter": "Vue.volar" - }, - - "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - }, - - "typescript.preferences.importModuleSpecifier": "relative", - "typescript.suggest.autoImports": true, - - "files.associations": { - "*.php": "php", - ".env*": "dotenv" - }, - - "search.exclude": { - "**/node_modules": true, - "**/vendor": true, - "**/dist": true - }, - + + "eslint.format.enable": true, + "eslint.validate": [ + "javascript", + "typescript", + "vue" + ], "eslint.workingDirectories": [ { "directory": "apps/admin", "changeProcessCWD": true }, { "directory": "apps/app", "changeProcessCWD": true }, { "directory": "apps/portal", "changeProcessCWD": true } - ] + ], + + "prettier.enable": false, + + "[php]": { + "editor.defaultFormatter": "bmewburn.vscode-intelephense-client", + "editor.tabSize": 4 + }, + + "[typescript]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + + "[typescriptreact]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + + "[javascript]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + + "[vue]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint" + }, + + "typescript.preferences.importModuleSpecifier": "relative", + "typescript.suggest.autoImports": true, + + "files.associations": { + "*.php": "php", + ".env*": "dotenv" + }, + + "search.exclude": { + "**/node_modules": true, + "**/vendor": true, + "**/dist": true + } }