{ "$schema": "./node_modules/oxlint/configuration_schema.json", "options": { "typeAware": false }, "ignorePatterns": [".dev/**"], "plugins": ["react", "react-perf", "unicorn", "typescript", "oxc", "import", "promise"], "categories": { "correctness": "error", "suspicious": "error", "perf": "error" }, "rules": { "react/react-in-jsx-scope": "off", "no-await-in-loop": "off", "no-unused-expressions": "error", "no-useless-catch": "error", "preserve-caught-error": "error", "require-await": "off", "no-async-promise-executor": "error", "no-useless-escape": "error", "no-empty-pattern": "error", "no-self-assign": "error", "no-shadow": "error", "unicorn/consistent-function-scoping": "off", "unicorn/no-array-sort": "off", "unicorn/no-useless-spread": "error", "unicorn/no-useless-fallback-in-spread": "error", "unicorn/no-new-array": "error", "unicorn/no-empty-file": "error", "promise/always-return": "error", "promise/no-multiple-resolved": "error", "react/no-array-index-key": "error", "react/jsx-no-useless-fragment": "error", "react/jsx-no-constructed-context-values": "error", "react/no-unescaped-entities": "error", "react/button-has-type": "error", "react/jsx-max-depth": ["error", { "max": 6 }], "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "error", "react-perf/jsx-no-new-array-as-prop": "error", "react-perf/jsx-no-new-function-as-prop": "error", "react-perf/jsx-no-new-object-as-prop": "error", "react-perf/jsx-no-jsx-as-prop": "error", "oxc/no-map-spread": "error", "oxc/no-async-endpoint-handlers": "error", "oxc/only-used-in-recursion": "error", "typescript/no-explicit-any": "error", "typescript/prefer-as-const": "error", "typescript/no-this-alias": "error", "typescript/no-unnecessary-type-assertion": "error", "typescript/consistent-type-definitions": ["error", "interface"], "import/no-unassigned-import": [ "error", { "allow": [ "**/*.css", "**/expo-router/entry", "**/event-target-polyfill", "**/dotenv/config", "**/react-native", "**/@/styles/unistyles", "**/src/styles/unistyles", "**/@/test/window-local-storage" ] } ], "no-nested-ternary": "error", "no-unneeded-ternary": "error", "complexity": ["error", { "max": 20 }], "max-depth": ["error", { "max": 4 }], "max-nested-callbacks": ["error", { "max": 3 }] }, "overrides": [ { "files": ["packages/app/src/**/*.{ts,tsx}"], "rules": { "no-restricted-imports": [ "error", { "paths": [ { "name": "@tanstack/react-query", "importNames": ["useQuery", "useInfiniteQuery", "useQueries"], "message": "App reads must go through useReplicaQuery/useFetchQuery from @/data/query. Grandfathered files may only leave the override burn-down list." }, { "name": "react-native-unistyles", "importNames": ["useUnistyles"], "message": "useUnistyles is banned by docs/unistyles.md. Grandfathered files may only leave the override burn-down list." } ] } ] } }, { "files": [ "packages/app/src/data/**/*.{ts,tsx}", "packages/app/src/**/*.test.{ts,tsx}", "packages/app/src/**/*.spec.{ts,tsx}" ], "rules": { "no-restricted-imports": [ "error", { "paths": [ { "name": "react-native-unistyles", "importNames": ["useUnistyles"], "message": "useUnistyles is banned by docs/unistyles.md. Grandfathered files may only leave the override burn-down list." } ] } ] } }, // Raw query burn-down: 35 files total; the 29 files below still enforce the useUnistyles ban. { "files": [ "packages/app/src/assistant-file-links/use-file-link.ts", "packages/app/src/components/message.tsx", "packages/app/src/components/worktree-setup-callout-source.tsx", "packages/app/src/desktop/hooks/use-daemon-status.ts", "packages/app/src/desktop/hooks/use-install-status.ts", "packages/app/src/desktop/settings/desktop-settings.ts", "packages/app/src/git/pull-request-panel/use-data.ts", "packages/app/src/git/use-github-search-query.ts", "packages/app/src/git/use-pr-status-query.ts", "packages/app/src/git/use-status-query.ts", "packages/app/src/hooks/use-archive-agent.ts", "packages/app/src/hooks/use-agent-autocomplete.ts", "packages/app/src/hooks/use-agent-commands-query.ts", "packages/app/src/hooks/use-agent-history.ts", "packages/app/src/hooks/use-branch-switcher.ts", "packages/app/src/hooks/use-changes-preferences/index.ts", "packages/app/src/hooks/use-draft-agent-features.ts", "packages/app/src/hooks/use-form-preferences.ts", "packages/app/src/hooks/use-is-local-daemon.ts", "packages/app/src/hooks/use-keyboard-shortcut-overrides.ts", "packages/app/src/hooks/use-preferred-editor.ts", "packages/app/src/hooks/use-project-icon-query.ts", "packages/app/src/hooks/use-settings/index.ts", "packages/app/src/panels/terminal-panel.tsx", "packages/app/src/projects/project-icons.ts", "packages/app/src/provider-usage/use-provider-usage.ts", "packages/app/src/screens/project-settings-screen.tsx", "packages/app/src/screens/workspace/use-workspace-checkout-status.ts", "packages/app/src/workspace/desktop-open-targets.ts" ], "rules": { "no-restricted-imports": [ "error", { "paths": [ { "name": "react-native-unistyles", "importNames": ["useUnistyles"], "message": "useUnistyles is banned by docs/unistyles.md. Grandfathered files may only leave the override burn-down list." } ] } ] } }, // useUnistyles burn-down: 74 files total; the 68 files below still enforce the raw-query ban. { "files": [ "packages/app/src/app/_layout.tsx", "packages/app/src/app/pair-scan.tsx", "packages/app/src/components/adaptive-modal-sheet.tsx", "packages/app/src/components/add-host-method-modal.tsx", "packages/app/src/components/add-host-modal.tsx", "packages/app/src/components/agent-list.tsx", "packages/app/src/components/agent-status-dot.tsx", "packages/app/src/components/attachment-lightbox.tsx", "packages/app/src/components/browser-pane.electron.tsx", "packages/app/src/components/browser-pane.tsx", "packages/app/src/components/browser-pane.web.tsx", "packages/app/src/components/command-center.tsx", "packages/app/src/components/context-window-meter.tsx", "packages/app/src/components/dictation-controls.tsx", "packages/app/src/components/download-toast.tsx", "packages/app/src/components/draggable-list.native.tsx", "packages/app/src/components/explorer-sidebar.tsx", "packages/app/src/components/headers/back-header.tsx", "packages/app/src/components/headers/menu-header.tsx", "packages/app/src/components/headers/screen-header.tsx", "packages/app/src/components/host-status-dot.tsx", "packages/app/src/components/hosts/host-picker.tsx", "packages/app/src/components/icons/paseo-logo.tsx", "packages/app/src/components/left-sidebar.tsx", "packages/app/src/components/pair-link-modal.tsx", "packages/app/src/components/plan-card.tsx", "packages/app/src/components/provider-diagnostic-sheet.tsx", "packages/app/src/components/question-form-card.tsx", "packages/app/src/components/quitting-overlay.tsx", "packages/app/src/components/realtime-voice-overlay.tsx", "packages/app/src/components/resize-handle.tsx", "packages/app/src/components/rewind/rewind-menu.tsx", "packages/app/src/components/settings-textarea.tsx", "packages/app/src/components/sidebar-callout.tsx", "packages/app/src/components/split-container.tsx", "packages/app/src/components/split-drop-zone.tsx", "packages/app/src/components/terminal-pane.tsx", "packages/app/src/components/toast-host.tsx", "packages/app/src/components/tool-call-sheet.tsx", "packages/app/src/components/ui/alert.tsx", "packages/app/src/components/ui/autocomplete.tsx", "packages/app/src/components/ui/combobox.tsx", "packages/app/src/components/ui/context-menu.tsx", "packages/app/src/components/ui/dropdown-menu.tsx", "packages/app/src/components/ui/external-link.tsx", "packages/app/src/components/volume-meter.tsx", "packages/app/src/components/web-desktop-scrollbar.tsx", "packages/app/src/components/welcome-screen.tsx", "packages/app/src/composer/agent-controls/index.tsx", "packages/app/src/composer/agent-controls/mode-control.tsx", "packages/app/src/constants/layout.ts", "packages/app/src/desktop/components/desktop-permission-row.tsx", "packages/app/src/desktop/components/desktop-permissions-section.tsx", "packages/app/src/desktop/components/desktop-updates-section.tsx", "packages/app/src/desktop/components/integrations-section.tsx", "packages/app/src/desktop/updates/update-callout-source.tsx", "packages/app/src/git/actions-split-button.tsx", "packages/app/src/hooks/use-web-scrollbar-style.web.ts", "packages/app/src/hosts/host-chooser.tsx", "packages/app/src/screens/open-project-screen.tsx", "packages/app/src/screens/projects-screen.tsx", "packages/app/src/screens/sessions-screen.tsx", "packages/app/src/screens/settings-screen.tsx", "packages/app/src/screens/settings/host-page.tsx", "packages/app/src/screens/settings/providers-section.tsx", "packages/app/src/screens/settings/settings-group.tsx", "packages/app/src/screens/startup-splash-screen.tsx", "packages/app/src/screens/workspace/workspace-route-state-views.tsx" ], "rules": { "no-restricted-imports": [ "error", { "paths": [ { "name": "@tanstack/react-query", "importNames": ["useQuery", "useInfiniteQuery", "useQueries"], "message": "App reads must go through useReplicaQuery/useFetchQuery from @/data/query. Grandfathered files may only leave the override burn-down list." } ] } ] } }, // Both burn-downs: 6 overlapping files. They may only shrink out of this exemption. { "files": [ "packages/app/src/components/file-explorer-pane.tsx", "packages/app/src/components/file-pane.tsx", "packages/app/src/components/import-session-sheet.tsx", "packages/app/src/components/project-picker-modal.tsx", "packages/app/src/desktop/components/pair-device-section.tsx", "packages/app/src/screens/new-workspace-screen.tsx" ], "rules": { "no-restricted-imports": "off" } }, { "files": ["**/e2e/fixtures.ts"], "rules": { "no-empty-pattern": "off" } } ] }