chore: replace biome with oxc (oxfmt + oxlint)

- Remove @biomejs/biome from root and packages/expo-two-way-audio
- Delete biome.json
- Add .oxfmtrc.json (migrated from biome via oxfmt --migrate=biome)
- Add .oxlintrc.json with curated rule set: react, react-perf,
  react-hooks, typescript, unicorn, oxc, import, promise
  - Rules target functional gotchas, untyped code, perf issues,
    deep JSX, nested ternaries, complexity, unused code
  - Noisy stylistic rules explicitly disabled
- Add npm scripts: lint, lint:fix (oxfmt replaces format/format:check)
- Update CI to run oxfmt --check

Lint is wired up but not enforced — all rules at warn. Baseline:
6040 warnings, 0 errors.
This commit is contained in:
Mohamed Boudra
2026-04-23 21:44:56 +07:00
parent ce4b0d54c7
commit 9c88850de0
7 changed files with 904 additions and 433 deletions

View File

@@ -15,14 +15,14 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm install
- name: Check formatting
run: npx biome format .
run: npx oxfmt --check .
typecheck:
runs-on: ubuntu-latest
@@ -31,8 +31,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm install
@@ -58,8 +58,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
node-version: "20"
cache: "npm"
- name: Fetch origin/main (worktree tests)
run: git fetch --no-tags origin main:refs/remotes/origin/main
@@ -88,8 +88,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm install
@@ -126,8 +126,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm install
@@ -148,8 +148,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm install
@@ -191,8 +191,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm install
@@ -210,8 +210,8 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
node-version: "20"
cache: "npm"
- name: Install dependencies
run: npm install
@@ -225,6 +225,6 @@ jobs:
- name: Run CLI tests
run: npm run test --workspace=@getpaseo/cli
env:
PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD: '0'
PASEO_DICTATION_ENABLED: '0'
PASEO_VOICE_MODE_ENABLED: '0'
PASEO_LOCAL_SPEECH_AUTO_DOWNLOAD: "0"
PASEO_DICTATION_ENABLED: "0"
PASEO_VOICE_MODE_ENABLED: "0"

15
.oxfmtrc.json Normal file
View File

@@ -0,0 +1,15 @@
{
"$schema": "./node_modules/oxfmt/configuration_schema.json",
"useTabs": false,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": false,
"jsxSingleQuote": false,
"quoteProps": "as-needed",
"trailingComma": "all",
"semi": true,
"arrowParens": "always",
"bracketSameLine": false,
"bracketSpacing": true,
"ignorePatterns": ["*.lock"]
}

72
.oxlintrc.json Normal file
View File

@@ -0,0 +1,72 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": [
"react",
"react-perf",
"unicorn",
"typescript",
"oxc",
"import",
"promise"
],
"categories": {
"correctness": "warn",
"suspicious": "warn",
"perf": "warn"
},
"rules": {
"react/react-in-jsx-scope": "off",
"no-unused-expressions": "warn",
"no-useless-catch": "warn",
"preserve-caught-error": "warn",
"require-await": "warn",
"no-async-promise-executor": "warn",
"no-useless-escape": "warn",
"no-empty-pattern": "warn",
"no-self-assign": "warn",
"no-shadow": "warn",
"no-use-before-define": ["warn", { "functions": false, "classes": false, "variables": true }],
"require-await": "off",
"unicorn/consistent-function-scoping": "off",
"unicorn/no-array-sort": "off",
"unicorn/no-useless-spread": "warn",
"unicorn/no-useless-fallback-in-spread": "warn",
"unicorn/no-new-array": "warn",
"unicorn/no-empty-file": "warn",
"promise/always-return": "warn",
"promise/no-multiple-resolved": "warn",
"react/no-array-index-key": "warn",
"react/jsx-no-useless-fragment": "warn",
"react/jsx-no-constructed-context-values": "warn",
"react/no-unescaped-entities": "warn",
"react/button-has-type": "warn",
"react/jsx-max-depth": ["warn", { "max": 6 }],
"react-hooks/rules-of-hooks": "warn",
"react-hooks/exhaustive-deps": "warn",
"react-perf/jsx-no-new-array-as-prop": "warn",
"react-perf/jsx-no-new-function-as-prop": "warn",
"react-perf/jsx-no-new-object-as-prop": "warn",
"react-perf/jsx-no-jsx-as-prop": "warn",
"oxc/no-map-spread": "warn",
"oxc/no-async-endpoint-handlers": "warn",
"oxc/only-used-in-recursion": "warn",
"typescript/no-explicit-any": "warn",
"typescript/prefer-as-const": "warn",
"typescript/no-this-alias": "warn",
"no-nested-ternary": "warn",
"no-unneeded-ternary": "warn",
"complexity": ["warn", { "max": 20 }],
"max-depth": ["warn", { "max": 4 }],
"max-nested-callbacks": ["warn", { "max": 3 }]
}
}

View File

@@ -1,32 +0,0 @@
{
"$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"includes": ["**", "!*.lock"]
},
"formatter": {
"indentStyle": "space",
"indentWidth": 2,
"lineWidth": 100
},
"javascript": {
"formatter": {
"quoteStyle": "double",
"trailingCommas": "all",
"semicolons": "always"
}
},
"css": {
"parser": {
"cssModules": true,
"tailwindDirectives": true
}
},
"linter": {
"enabled": false
}
}

1072
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,6 +2,25 @@
"name": "paseo",
"version": "0.1.62",
"private": true,
"description": "Paseo: voice-controlled development environment with OpenAI Realtime API",
"keywords": [
"development",
"mcp",
"openai",
"realtime",
"voice",
"voice-assistant"
],
"homepage": "https://paseo.sh",
"license": "AGPL-3.0-or-later",
"author": {
"name": "Mohamed Boudra",
"email": "hello@moboudra.com"
},
"repository": {
"type": "git",
"url": "https://github.com/getpaseo/paseo.git"
},
"workspaces": [
"packages/expo-two-way-audio",
"packages/highlight",
@@ -25,8 +44,10 @@
"typecheck": "npm run typecheck --workspaces --if-present",
"typecheck:daemon": "npm run typecheck --workspace=@getpaseo/relay && npm run typecheck --workspace=@getpaseo/server && npm run typecheck --workspace=@getpaseo/cli",
"test": "npm run test --workspaces --if-present",
"format": "biome format --write .",
"format:check": "biome format .",
"format": "oxfmt .",
"format:check": "oxfmt --check .",
"lint": "oxlint",
"lint:fix": "oxlint --fix",
"start": "npm run start --workspace=@getpaseo/server",
"android": "npm run android --workspace=@getpaseo/app",
"android:development": "npm run android:development --workspace=@getpaseo/app",
@@ -65,45 +86,27 @@
"release:minor": "npm run release:check && npm run version:all:minor && npm run release:publish && npm run release:push",
"release:major": "npm run release:check && npm run version:all:major && npm run release:publish && npm run release:push"
},
"devDependencies": {
"@biomejs/biome": "^2.4.8",
"concurrently": "^9.2.1",
"get-port-cli": "^3.0.0",
"knip": "^5.82.1",
"patch-package": "^8.0.1",
"react": "19.1.0",
"react-dom": "19.1.0",
"typescript": "^5.9.3"
},
"description": "Paseo: voice-controlled development environment with OpenAI Realtime API",
"homepage": "https://paseo.sh",
"keywords": [
"openai",
"realtime",
"voice",
"voice-assistant",
"development",
"mcp"
],
"author": {
"name": "Mohamed Boudra",
"email": "hello@moboudra.com"
},
"repository": {
"type": "git",
"url": "https://github.com/getpaseo/paseo.git"
},
"license": "AGPL-3.0-or-later",
"overrides": {
"lightningcss": "1.30.1",
"react": "19.1.0",
"react-dom": "19.1.0"
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.2.11",
"@modelcontextprotocol/sdk": "^1.27.1",
"expo": "~54.0.33",
"react": "19.1.0",
"react-native": "0.81.5"
},
"devDependencies": {
"concurrently": "^9.2.1",
"get-port-cli": "^3.0.0",
"knip": "^5.82.1",
"oxfmt": "0.46.0",
"oxlint": "1.61.0",
"patch-package": "^8.0.1",
"react": "19.1.0",
"react-dom": "19.1.0",
"typescript": "^5.9.3"
},
"overrides": {
"lightningcss": "1.30.1",
"react": "19.1.0",
"react-dom": "19.1.0"
}
}

View File

@@ -2,6 +2,19 @@
"name": "@getpaseo/expo-two-way-audio",
"version": "0.1.62",
"description": "Native module for two way audio streaming",
"keywords": [
"ExpoTwoWayAudio",
"expo",
"expo-two-way-audio",
"react-native"
],
"homepage": "https://github.com/boudra/expo-two-way-audio",
"bugs": {
"url": "https://github.com/speechmatics/expo-two-way-audio/issues"
},
"license": "MIT",
"author": "Speechmatics <devrel@speechmatics.com> (https://github.com/speechmatics)",
"repository": "https://github.com/boudra/expo-two-way-audio",
"main": "build/index.js",
"types": "build/index.d.ts",
"scripts": {
@@ -10,28 +23,14 @@
"dev": "expo-module build",
"lint": "expo-module lint",
"test": "expo-module test",
"format": "biome check .",
"format:fix": "biome check --write .",
"format": "oxfmt --check .",
"format:fix": "oxfmt .",
"typecheck": "tsc",
"expo-module": "expo-module",
"open:ios": "xed examples/basic-usage/ios",
"open:android": "open -a \"Android Studio\" examples/basic-usage/android"
},
"keywords": [
"react-native",
"expo",
"expo-two-way-audio",
"ExpoTwoWayAudio"
],
"repository": "https://github.com/boudra/expo-two-way-audio",
"bugs": {
"url": "https://github.com/speechmatics/expo-two-way-audio/issues"
},
"author": "Speechmatics <devrel@speechmatics.com> (https://github.com/speechmatics)",
"license": "MIT",
"homepage": "https://github.com/boudra/expo-two-way-audio",
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/react": "^18.0.25",
"expo-module-scripts": "^3.5.2",
"expo-modules-core": "^2.0.4"