mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 08:02:32 +00:00
chore(lint): add anti-slop oxlint plugin (pinned, all rules off) (#20726)
* chore(lint): add anti-slop oxlint plugin (all rules off) Vendors dmmulroy/anti-slop (MIT) plus no-call-only-assertions and no-pass-through-type-alias from maharshi365/deslop (MIT). Every rule starts "off"; each follow-up PR fixes one rule's violations and flips it to "error". * fix(lint): actually exclude the vendored plugin from the anti-slop audit oxlint does not honour ignorePatterns supplied via --config, so the config/oxlint-plugins/anti-slop/** entry never matched and the vendored rule source was being linted as first-party code (505 violations). Move the exclusion to the --ignore-pattern CLI flag in audit:anti-slop, which does work, and drop the entry that gave a false sense of coverage. Keeping vendored source unlinted matters because anti-slop is updated by three-way merge against the upstream snapshot; reformatting it locally would conflict on every update. * chore(lint): pin anti-slop instead of vendoring it; drop deslop Replaces the ~5k vendored lines with a git-pinned devDependency: oxlint-plugin-anti-slop: github:dmmulroy/anti-slop#c44ef22 anti-slop ships raw .ts with no build step, and Node refuses to type-strip anything under node_modules (ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING), so oxlint cannot load it from there -- which is why upstream says to vendor it. A postinstall step copies the pinned package's source to .anti-slop-plugin/ (gitignored), which Node will type-strip because it sits outside node_modules. Upgrading is now a SHA bump rather than a re-vendor and three-way merge. Verified byte-identical rule output to the vendored copy across all 16 rules that fire. Drops maharshi365/deslop and its two rules (no-call-only-assertions, no-pass-through-type-alias). It is not on npm either, so it would need a second git pin and copy step, and it is a 5-star single-maintainer repo that is itself a re-namespaced copy of anti-slop. One upstream is enough. * ci(lint): run audit:anti-slop in PR CI config/scripts/pr-workflow-lint-parity.test.mjs requires every step in `pnpm lint` to have a matching step in .github/workflows/pr.yml; adding audit:anti-slop to lint without the workflow step failed that ratchet. Also makes audit:anti-slop sync the plugin itself before linting. The generated .anti-slop-plugin/ directory is gitignored and otherwise only created by postinstall, so a cached install that skips postinstall would leave oxlint unable to load the plugin.
This commit is contained in:
@@ -133,6 +133,9 @@ jobs:
|
||||
- name: Lint
|
||||
run: pnpm exec oxlint --format github
|
||||
|
||||
- name: Reject low-evidence patterns
|
||||
run: pnpm run audit:anti-slop
|
||||
|
||||
- name: Enforce focused code-quality plugins
|
||||
run: pnpm run audit:code-quality:native
|
||||
|
||||
|
||||
@@ -181,3 +181,6 @@ tests/e2e/.cross-version-checkouts/
|
||||
# IS committed). Also keeps oxfmt/oxlint, which honor this file, from walking
|
||||
# vendored gems.
|
||||
/mobile/vendor/
|
||||
|
||||
# Generated by config/scripts/sync-anti-slop-plugin.mjs from the pinned oxlint-plugin-anti-slop
|
||||
.anti-slop-plugin/
|
||||
|
||||
+5
-1
@@ -4,5 +4,9 @@
|
||||
"semi": false,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "none",
|
||||
"ignorePatterns": ["cloud/**", ".github/actions/cloud-sql-rollout-lease/**"]
|
||||
"ignorePatterns": [
|
||||
"cloud/**",
|
||||
".github/actions/cloud-sql-rollout-lease/**",
|
||||
".anti-slop-plugin/**"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"$schema": "../node_modules/oxlint/configuration_schema.json",
|
||||
"plugins": [],
|
||||
"jsPlugins": [
|
||||
{
|
||||
"name": "anti-slop",
|
||||
"specifier": "../.anti-slop-plugin/index.ts"
|
||||
}
|
||||
],
|
||||
"categories": {
|
||||
"correctness": "off",
|
||||
"suspicious": "off",
|
||||
"pedantic": "off",
|
||||
"perf": "off",
|
||||
"style": "off",
|
||||
"restriction": "off",
|
||||
"nursery": "off"
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"**/node_modules",
|
||||
"**/dist",
|
||||
"**/out",
|
||||
"cloud/**",
|
||||
"src/shared/rpc-contract/rpc-params-catalog.generated.ts",
|
||||
"tests/e2e/.cross-version-checkouts"
|
||||
],
|
||||
"rules": {
|
||||
"anti-slop/no-array-filter-map": "off",
|
||||
"anti-slop/no-chained-type-assertions": "off",
|
||||
"anti-slop/no-conditional-empty-object-spread": "off",
|
||||
"anti-slop/no-known-value-widening": "off",
|
||||
"anti-slop/no-module-mocking": "off",
|
||||
"anti-slop/no-object-parameters": "off",
|
||||
"anti-slop/no-reduce-accumulator-copy": "off",
|
||||
"anti-slop/no-reflect-apply": "off",
|
||||
"anti-slop/no-reflect-get": "off",
|
||||
"anti-slop/no-runtime-typeof": "off",
|
||||
"anti-slop/no-shape-in-symbol-names": "off",
|
||||
"anti-slop/no-unknown-parameters": "off",
|
||||
"anti-slop/no-unknown-returns": "off",
|
||||
"anti-slop/no-unknown-type-aliases": "off",
|
||||
"anti-slop/no-unsafe-dictionary-type": "off",
|
||||
"anti-slop/no-widen-then-assert": "off",
|
||||
"anti-slop/require-readable-spacing": "off",
|
||||
"anti-slop/require-safety-comment-for-type-assertion": "off"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/*.test.{ts,tsx}",
|
||||
"**/*.spec.{ts,tsx}",
|
||||
"tests/**/*.{ts,tsx}",
|
||||
"**/__mocks__/**"
|
||||
],
|
||||
"rules": {
|
||||
"anti-slop/no-module-mocking": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// anti-slop ships raw .ts with no build step, and Node refuses to type-strip anything
|
||||
// under node_modules (ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING), so oxlint cannot load
|
||||
// it from there. Copy the pinned package's source out to a gitignored dir it can load.
|
||||
import { cpSync, mkdirSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
|
||||
const repoRoot = resolve(import.meta.dirname, '../..')
|
||||
const source = resolve(repoRoot, 'node_modules/oxlint-plugin-anti-slop/src')
|
||||
const target = resolve(repoRoot, '.anti-slop-plugin')
|
||||
|
||||
rmSync(target, { recursive: true, force: true })
|
||||
mkdirSync(target, { recursive: true })
|
||||
cpSync(source, target, { recursive: true })
|
||||
// Effect rules are opt-in upstream and this repo does not use Effect; tests would be linted.
|
||||
rmSync(resolve(target, 'effect'), { recursive: true, force: true })
|
||||
cpSync(
|
||||
resolve(repoRoot, 'node_modules/oxlint-plugin-anti-slop/LICENSE'),
|
||||
resolve(target, 'LICENSE')
|
||||
)
|
||||
writeFileSync(resolve(target, 'package.json'), '{ "type": "module" }\n')
|
||||
+7
-3
@@ -14,7 +14,7 @@
|
||||
"audit:perf": "oxlint --config config/oxlint-performance-audit.json --format json src",
|
||||
"test:perf:contracts": "vitest run --config config/vitest.performance.config.ts",
|
||||
"format": "oxfmt --write .",
|
||||
"lint": "oxlint && pnpm run audit:code-quality:native && pnpm run audit:code-quality:type-aware && pnpm run check:reliability-gates && pnpm run check:dead-classes && pnpm run check:max-lines-ratchet && pnpm run check:ts-nocheck-ratchet && pnpm run check:runtime-electron-ratchet && pnpm run check:readme-local-links && pnpm run verify:rpc-params-catalog && pnpm run verify:bundled-skill-guides && pnpm run verify:skill-bundle-manifest && pnpm run verify:localization-catalog && pnpm run verify:localization-runtime-catalog && pnpm run verify:localization-extraction && pnpm run verify:localization-coverage",
|
||||
"lint": "oxlint && pnpm run audit:anti-slop && pnpm run audit:code-quality:native && pnpm run audit:code-quality:type-aware && pnpm run check:reliability-gates && pnpm run check:dead-classes && pnpm run check:max-lines-ratchet && pnpm run check:ts-nocheck-ratchet && pnpm run check:runtime-electron-ratchet && pnpm run check:readme-local-links && pnpm run verify:rpc-params-catalog && pnpm run verify:bundled-skill-guides && pnpm run verify:skill-bundle-manifest && pnpm run verify:localization-catalog && pnpm run verify:localization-runtime-catalog && pnpm run verify:localization-extraction && pnpm run verify:localization-coverage",
|
||||
"audit:code-quality": "pnpm run audit:code-quality:native && pnpm run audit:code-quality:type-aware && pnpm run audit:react-doctor",
|
||||
"audit:code-quality:native": "oxlint --config config/oxlint-code-quality-native-plugins.json src config tests mobile --deny-warnings",
|
||||
"audit:code-quality:type-aware": "oxlint --type-aware --config config/oxlint-code-quality-type-aware.json src config tests --deny-warnings",
|
||||
@@ -97,7 +97,7 @@
|
||||
"build": "pnpm run build:desktop && pnpm run build:native",
|
||||
"build:release": "pnpm run build:relay && pnpm run build:native && pnpm run verify:computer-native && pnpm run build:cli && pnpm run build:electron-vite && pnpm run verify:built-skills-cli && pnpm run build:web-from-renderer",
|
||||
"build:release:parallel": "pnpm run build:relay && pnpm run build:native && pnpm run verify:computer-native && pnpm run build:cli && pnpm run build:electron-vite:parallel && pnpm run verify:built-skills-cli && pnpm run build:web-from-renderer",
|
||||
"postinstall": "node config/scripts/rebuild-native-deps.mjs",
|
||||
"postinstall": "node config/scripts/rebuild-native-deps.mjs && node config/scripts/sync-anti-slop-plugin.mjs",
|
||||
"rebuild:electron": "node config/scripts/rebuild-native-deps.mjs",
|
||||
"reclaim:electron-dists": "node config/scripts/reclaim-electron-dists.mjs",
|
||||
"reclaim:dev-bundles": "node config/scripts/reclaim-dev-electron-bundles.mjs",
|
||||
@@ -164,7 +164,9 @@
|
||||
"test:e2e:remote-bulk-open-freeze": "pnpm run ensure:electron-runtime && pnpm exec playwright test tests/e2e/remote-session-bulk-open-freeze-repro.spec.ts --config tests/playwright.config.ts --project electron-headless --workers=1",
|
||||
"test:e2e:ssh-docker-bulk-open-freeze": "node config/scripts/run-ssh-docker-bulk-open-freeze-e2e.mjs",
|
||||
"repro:live-remote-bulk-open-freeze": "node config/scripts/live-remote-bulk-open-freeze-repro.mjs",
|
||||
"repro:live-remote-realistic-freeze": "node config/scripts/live-remote-realistic-freeze-repro.mjs"
|
||||
"repro:live-remote-realistic-freeze": "node config/scripts/live-remote-realistic-freeze-repro.mjs",
|
||||
"audit:anti-slop": "node config/scripts/sync-anti-slop-plugin.mjs && oxlint --config config/oxlint-anti-slop.json src config tests mobile --deny-warnings",
|
||||
"sync:anti-slop-plugin": "node config/scripts/sync-anti-slop-plugin.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/claude-agent-sdk": "0.3.251",
|
||||
@@ -199,6 +201,7 @@
|
||||
"@electron-toolkit/tsconfig": "^2.0.0",
|
||||
"@electron/rebuild": "^4.2.0",
|
||||
"@monaco-editor/react": "^4.7.0",
|
||||
"@oxlint/plugins": "1.80.0",
|
||||
"@playwright/test": "^1.59.1",
|
||||
"@sanity/diff-match-patch": "^3.2.0",
|
||||
"@shadcn/lint": "^0.1.0",
|
||||
@@ -265,6 +268,7 @@
|
||||
"monaco-editor": "^0.55.1",
|
||||
"oxfmt": "^0.65.0",
|
||||
"oxlint": "^1.80.0",
|
||||
"oxlint-plugin-anti-slop": "github:dmmulroy/anti-slop#c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b",
|
||||
"oxlint-plugin-react-doctor": "0.9.1",
|
||||
"oxlint-tsgolint": "7.0.2001",
|
||||
"pdfjs-dist": "^6.3.289",
|
||||
|
||||
Generated
+26
@@ -213,6 +213,9 @@ importers:
|
||||
'@monaco-editor/react':
|
||||
specifier: ^4.7.0
|
||||
version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)
|
||||
'@oxlint/plugins':
|
||||
specifier: 1.80.0
|
||||
version: 1.80.0
|
||||
'@playwright/test':
|
||||
specifier: ^1.59.1
|
||||
version: 1.59.1
|
||||
@@ -411,6 +414,9 @@ importers:
|
||||
oxlint:
|
||||
specifier: ^1.80.0
|
||||
version: 1.80.0(oxlint-tsgolint@7.0.2001)
|
||||
oxlint-plugin-anti-slop:
|
||||
specifier: github:dmmulroy/anti-slop#c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b
|
||||
version: https://codeload.github.com/dmmulroy/anti-slop/tar.gz/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b
|
||||
oxlint-plugin-react-doctor:
|
||||
specifier: 0.9.1
|
||||
version: 0.9.1
|
||||
@@ -1940,6 +1946,14 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@oxlint/plugins@1.78.0':
|
||||
resolution: {integrity: sha512-Ypt8KeRYw+4jUtlPirfcHWMrn5ms12VrrFPD+Mds477/7tJxG1Kcz2Yrg2nVcTQEUx/GdlhS+BUg1kmxNm04Ug==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
||||
'@oxlint/plugins@1.80.0':
|
||||
resolution: {integrity: sha512-QRgH1XqQEYNHa4f1vvPQ5fAdNdncHGIUG1ZWLlGIZHky3qwCEeAKYitZNbZMtaXtAQAAFFTOwqUfzESvimqZNA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
|
||||
'@parcel/watcher-android-arm64@2.5.6':
|
||||
resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
@@ -6059,6 +6073,10 @@ packages:
|
||||
vite-plus:
|
||||
optional: true
|
||||
|
||||
oxlint-plugin-anti-slop@https://codeload.github.com/dmmulroy/anti-slop/tar.gz/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b:
|
||||
resolution: {gitHosted: true, integrity: sha512-Vj/M0k5Bt1Q2pGdfXZ24wGXycBcvFHwJ/pjHIFl1hV8soaZKHl1lba5UXlQFY5xgwQ5TNfEWiKfsEt0yyRyVUg==, tarball: https://codeload.github.com/dmmulroy/anti-slop/tar.gz/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b}
|
||||
version: 0.1.2
|
||||
|
||||
oxlint-plugin-react-doctor@0.9.1:
|
||||
resolution: {integrity: sha512-yCW8USbiuszbVsUMN4fL1iU7mRu3Ae3w96+k/xqCyWvW6bF6DzCMtLy5N/w6WLRX78iQsWxVqW/SEgzRBXLfsA==}
|
||||
engines: {node: ^20.19.0 || >=22.13.0}
|
||||
@@ -8605,6 +8623,10 @@ snapshots:
|
||||
'@oxlint/binding-win32-x64-msvc@1.80.0':
|
||||
optional: true
|
||||
|
||||
'@oxlint/plugins@1.78.0': {}
|
||||
|
||||
'@oxlint/plugins@1.80.0': {}
|
||||
|
||||
'@parcel/watcher-android-arm64@2.5.6':
|
||||
optional: true
|
||||
|
||||
@@ -13162,6 +13184,10 @@ snapshots:
|
||||
'@oxfmt/binding-win32-ia32-msvc': 0.65.0
|
||||
'@oxfmt/binding-win32-x64-msvc': 0.65.0
|
||||
|
||||
oxlint-plugin-anti-slop@https://codeload.github.com/dmmulroy/anti-slop/tar.gz/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b:
|
||||
dependencies:
|
||||
'@oxlint/plugins': 1.78.0
|
||||
|
||||
oxlint-plugin-react-doctor@0.9.1:
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 8.60.0
|
||||
|
||||
Reference in New Issue
Block a user