chore(lint): upgrade oxlint to 1.71 + enable 7 new rules (autofixed backlog) (#6841)

* chore(lint): upgrade oxlint to 1.71 and enable 7 new rules

Upgrade oxlint 1.67.0 -> 1.71.0 (1.72 was blocked by the repo's 3-day
minimum-release-age supply-chain guard; nothing here needs it). The
bump is a no-op on the existing config.

Enable 3 error rules (backlog autofixed to zero in this commit) and
4 warn rules (surface signal without gating CI):

error (autofixed, behavior-preserving):
- unicorn/prefer-node-protocol        (~1531 sites: bare builtin -> node:)
- typescript/no-import-type-side-effects (~36: all-inline-type -> import type)
- unicorn/no-array-reverse            (19: copy-then-reverse -> toReversed)

warn (real signal, current fires are test-only/correct):
- unicorn/no-array-fill-with-reference-type  (aliasing footgun guard)
- typescript/no-unsafe-function-type         (bans bare Function type)
- unicorn/prefer-array-flat-map              (map().flat() -> flatMap())
- unicorn/prefer-regexp-test                 (.match() in bool ctx -> .test())

mobile/.oxlintrc.json extends root, so it inherits all 7; the autofix
ran from root and covered mobile/ too.

Verification (all green): oxlint 0 errors (root+mobile+aux configs),
oxfmt clean, typecheck (node+cli+web), vitest 22795 passed / 0 failed,
builds (electron-vite + web + cli) succeed. node: rewrites confirmed to
skip embedded SSH/CLI string payloads (AST-only); all toReversed sites
verified to operate on fresh copies or write-once locals.

* chore(lint): bump mobile oxlint to 1.71 so inherited rules parse

mobile/ is a standalone pnpm project pinning its own oxlint@1.67, which
lacks unicorn/no-array-fill-with-reference-type (needs >=1.70). Since
mobile/.oxlintrc.json extends the root config, mobile CI's 'cd mobile &&
oxlint' failed to parse the new rule. Bump mobile to match root (1.71).

Verified in mobile/: oxlint 0 errors, oxfmt --check clean, tsc --noEmit
pass, vitest 978 passed / 0 failed.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Neil
2026-06-29 22:38:29 -07:00
committed by GitHub
co-authored by Orca
parent 0476109e2c
commit 46646d7ff1
636 changed files with 1815 additions and 1785 deletions
+7
View File
@@ -36,8 +36,10 @@
"typescript/consistent-type-definitions": ["error", "type"],
"typescript/consistent-type-imports": "error",
"typescript/no-explicit-any": ["error", { "ignoreRestArgs": true }],
"typescript/no-import-type-side-effects": "error",
"typescript/no-unnecessary-boolean-literal-compare": "error",
"typescript/no-unnecessary-template-expression": "error",
"typescript/no-unsafe-function-type": "warn",
"typescript/prefer-function-type": "error",
"typescript/prefer-includes": "error",
"typescript/prefer-optional-chain": "error",
@@ -51,14 +53,19 @@
"prefer-template": "error",
"unicorn/consistent-empty-array-spread": "error",
"unicorn/error-message": "error",
"unicorn/no-array-fill-with-reference-type": "warn",
"unicorn/no-array-reverse": "error",
"unicorn/no-instanceof-builtins": "error",
"unicorn/no-useless-promise-resolve-reject": "error",
"unicorn/prefer-array-flat-map": "warn",
"unicorn/prefer-at": "error",
"unicorn/prefer-date-now": "error",
"unicorn/prefer-includes": "error",
"unicorn/prefer-math-min-max": "error",
"unicorn/prefer-negative-index": "error",
"unicorn/prefer-node-protocol": "error",
"unicorn/prefer-object-from-entries": "error",
"unicorn/prefer-regexp-test": "warn",
"unicorn/prefer-ternary": "error",
"unicorn/throw-new-error": "error"
},
+4 -4
View File
@@ -9,10 +9,10 @@
* gracefully degraded.
*/
import { build } from 'esbuild'
import { createHash } from 'crypto'
import { mkdirSync, readFileSync, writeFileSync } from 'fs'
import { join, dirname } from 'path'
import { fileURLToPath } from 'url'
import { createHash } from 'node:crypto'
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
const __dirname = dirname(fileURLToPath(import.meta.url))
// Why: the script lives under config/scripts, so go two levels up to reach the repo root.
+1 -1
View File
@@ -23,7 +23,7 @@
* node config/scripts/terminal-e2e-helpers.mjs --port 9444 --command 'echo hello'
*/
import { execFileSync } from 'child_process'
import { execFileSync } from 'node:child_process'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
+2 -2
View File
@@ -1,5 +1,5 @@
import { readFile } from 'fs/promises'
import { resolve } from 'path'
import { readFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const indexPath = resolve('out/web/web-index.html')
const html = await readFile(indexPath, 'utf8')
+1 -1
View File
@@ -1,4 +1,4 @@
import { resolve } from 'path'
import { resolve } from 'node:path'
import { defineConfig } from 'vitest/config'
const windowsTestWorkerOptions = process.platform === 'win32' ? { maxWorkers: 4 } : {}
+1 -1
View File
@@ -1,4 +1,4 @@
import { resolve } from 'path'
import { resolve } from 'node:path'
import { defineConfig } from 'electron-vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
@@ -83,10 +83,10 @@ import {
triggerError,
triggerEdgeBump
} from '../../../../src/platform/haptics'
import {
type TerminalKeyboardAvoidanceMetrics,
type TerminalModes,
type TerminalWebViewHandle
import type {
TerminalKeyboardAvoidanceMetrics,
TerminalModes,
TerminalWebViewHandle
} from '../../../../src/terminal/TerminalWebView'
import { isTerminalOscLinkRanges } from '../../../../src/terminal/terminal-osc-link-ranges'
import { useTerminalViewportRefit } from '../../../../src/terminal/terminal-viewport-refit'
+1 -1
View File
@@ -63,7 +63,7 @@
"@types/ws": "^8.18.1",
"expo-module-scripts": "^55.0.2",
"oxfmt": "^0.52.0",
"oxlint": "^1.67.0",
"oxlint": "^1.71.0",
"tsx": "^4.22.4",
"typescript": "^5.9.3",
"vite": "^8.0.16",
@@ -1,4 +1,4 @@
import { type PermissionResponse } from 'expo-modules-core'
import type { PermissionResponse } from 'expo-modules-core'
import ExpoTwoWayAudioModule from './ExpoTwoWayAudioModule'
export async function initialize() {
+81 -81
View File
@@ -145,8 +145,8 @@ importers:
specifier: ^0.52.0
version: 0.52.0
oxlint:
specifier: ^1.67.0
version: 1.67.0
specifier: ^1.71.0
version: 1.71.0
tsx:
specifier: ^4.22.4
version: 4.22.4
@@ -1791,116 +1791,116 @@ packages:
cpu: [x64]
os: [win32]
'@oxlint/binding-android-arm-eabi@1.67.0':
resolution: {integrity: sha512-VrSi571rDv1N8HaEDM+DEX8nmT0y9jJo8tzzW13vsOWTx59xQczCIJx68n2zWOXRT5YKZsOZXp4qkHN/10x4mw==}
'@oxlint/binding-android-arm-eabi@1.71.0':
resolution: {integrity: sha512-ImGmd1njEg4FEJH03jhRnveEegtO3czCtfptvaHivKAZQIYATbVFBrrzbaYMYv0oJioTnxZAZVSyV+oL7W8S2g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxlint/binding-android-arm64@1.67.0':
resolution: {integrity: sha512-l6+NdYxMoRohix5r5bbigW16LPicceCwGcQ6LKKuE1kUdjgFfQolJjrJsQYPFetIs78Gxj/G/f5TEGoTCwj9nQ==}
'@oxlint/binding-android-arm64@1.71.0':
resolution: {integrity: sha512-4A5BEexBrwY1YFF8Kiq/lp/wQPRG79G3BWIE1FuWaM5MvmpYSd+7ZySVcKkHdwo0UDzdQGddp6pD9mpctMqLnw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxlint/binding-darwin-arm64@1.67.0':
resolution: {integrity: sha512-jOzXxS1AxFxhImLIRbtGIMrEwaXcgMw3gR57WB1cRk8ai+vpr6726kxXqVvlNsrXtJ/FrmOm8RxlC0m8SW24Qg==}
'@oxlint/binding-darwin-arm64@1.71.0':
resolution: {integrity: sha512-9wJA9GJulLwS2usU3CEisI/ESDO1n1z9eyTCvApMDrAkbJ1ve0mORgTMjcWWsKxkzkeZ2N/Gpra5IQE7x8tYgQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxlint/binding-darwin-x64@1.67.0':
resolution: {integrity: sha512-3DFAVY94OqjIZHXIPz37yGRSWwOFTAqChQ64/M69GYLawzP0KiwdhDNfqdKKYT0bTR/DNxmMnQsj3ns+8+X/Lg==}
'@oxlint/binding-darwin-x64@1.71.0':
resolution: {integrity: sha512-PlLCjS06V0PeJMAJwzjrExw1sYNW9Gch3JtNlcwwZDXGlTYDuwHNN89zYH8LTXFfgkVtsYvs2nv0FqrzyuFDzg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxlint/binding-freebsd-x64@1.67.0':
resolution: {integrity: sha512-e4dDKZuLu8TR9DEBssWSDahlPgZBwojTTHZUvnjBRJfJJbpxYCjfjKfi0Z1+CSLMiJBwI2yCDtRM1XJQaARjmg==}
'@oxlint/binding-freebsd-x64@1.71.0':
resolution: {integrity: sha512-Lhil7bWre0ncxbUoDoxfS0JzpTz17BRQKW7iwoAUY8GJ66+WwJEfYPCFJ1P0WgVZR5/O/b3Q2pENlHOjeXLOGQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxlint/binding-linux-arm-gnueabihf@1.67.0':
resolution: {integrity: sha512-BKytFdcQzbITV3xlnzDUDTEDtbUMCCiC4EaNTDZ4FyT8gdNvBC4gfiLucXp/sQl0XU3p7syTlorUWVVVBZab2g==}
'@oxlint/binding-linux-arm-gnueabihf@1.71.0':
resolution: {integrity: sha512-Oo9/L58PYD3RC0x05d2upAPLllHytTjHQGsnC06P6Ynn7jKkp5mdImQxXdJ3+FnBaKspNpGogzgVsi6g872LiA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm-musleabihf@1.67.0':
resolution: {integrity: sha512-XYAv0esBDX7BpTzRDjVX2Vdj+zndd8ll2dFQiaeQ6zTZr7A8GRDTN7fH3FP3jU+O0vCDx85oH/EtG7BzPgAXuw==}
'@oxlint/binding-linux-arm-musleabihf@1.71.0':
resolution: {integrity: sha512-mSHfyfgJrEbyIR29ejaeS50BdPk+GoNPlC1dckpDiUZbJAIel68sjSMdOt4WY0/gva+ECC7FNITQkxMJU+vSBw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm64-gnu@1.67.0':
resolution: {integrity: sha512-zizRMjA0i6u/2B0evgda04iycu+MoNuf1pBy6Eh+1CjC5wMEG7qN5zdDKTCvFc0KSYSDM9QTG3gjZHirgtQuKg==}
'@oxlint/binding-linux-arm64-gnu@1.71.0':
resolution: {integrity: sha512-n9yY4M2tiy3aij4AqtlnspzpfdpeT5JQfK2/w2d8oyp5W0FRwOb1dIeX99nORNcxGr08iD9bH8N5XFz3I2iy8w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
'@oxlint/binding-linux-arm64-musl@1.67.0':
resolution: {integrity: sha512-zB/Tf6sUjmmvvbva9Gj3JTJ8rJ9t4I8/U0o6vSRtd0DRIsIuyegBwJAzhSUFQHdMijIRJkW0exs/yBhpw2S20w==}
'@oxlint/binding-linux-arm64-musl@1.71.0':
resolution: {integrity: sha512-fJZrs5sDZtTaPIOiemRQQmo82Ezy+vOGXemPc4Ok7iVVsYsFa7SlW6Z5XN819VfsqBHRm3NJ3rTdnR8+bJYJdQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
'@oxlint/binding-linux-ppc64-gnu@1.67.0':
resolution: {integrity: sha512-kgU40Gt74CK0TCsF51KZymkIwN9U0BajKsMijB52zPqOeZU9NAHkA/NSQkZDHEaCakx42DxhXkODiAqf2b4Gug==}
'@oxlint/binding-linux-ppc64-gnu@1.71.0':
resolution: {integrity: sha512-cwl7VKGERIy9p+G+AvZdfy/06q0aHXaTt/mMRReC751iuNYJgqKjB7NydXSS30nBT9vtr2tunciOtrR4fD6FUA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
'@oxlint/binding-linux-riscv64-gnu@1.67.0':
resolution: {integrity: sha512-tOYhkk/iaG9aD3FvGpBFd1Lrw0x0RaVoJBxjUkfNzS50rC5NS5BteNCwgr8A2zCdADrIIoze6D7u6U5Ic++/iQ==}
'@oxlint/binding-linux-riscv64-gnu@1.71.0':
resolution: {integrity: sha512-eZ8ieVXvzGi8jr7+ybQGPK2STw3mldfxZlgA2738iflfB/rzA69sE6m5rDRpQaxC7dpm745Enlh1Tod0QAk9Gg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
'@oxlint/binding-linux-riscv64-musl@1.67.0':
resolution: {integrity: sha512-sEtywrPb+0b+tHYl1SDCrw903fiC4eyKoNqzP3v+f2JT3Xcv4NEYG+P8rj+eEnX7IWhqV/xj8/JmcmVj21CXaA==}
'@oxlint/binding-linux-riscv64-musl@1.71.0':
resolution: {integrity: sha512-puMDbQYe6+NXwfMusojoA7CXGn2b3utukmd23PQqc1E3XhVCwyZ+FueSMzDYeNgDV2dUfIVXAAKZBcFDeCL6sA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
'@oxlint/binding-linux-s390x-gnu@1.67.0':
resolution: {integrity: sha512-BvR8Moa0zCLxroOx4vZaZN9nUfwAUpSTwjZdxZyKy4bv3PrzrXrxKR/ZQ0L9wNSvlPhnMJeZfa3q5w6ZCTuN6Q==}
'@oxlint/binding-linux-s390x-gnu@1.71.0':
resolution: {integrity: sha512-4NJLxBs1ujISCt3L/1FcywLs73PWtJuw+piD6feK2V6h6OS6P7xu9/sWt1DTRLibe6QCzmfZzmM/2HPORoV/Lg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
'@oxlint/binding-linux-x64-gnu@1.67.0':
resolution: {integrity: sha512-mm2cxM6fksOpq6l0uFws8BUGKAR4dNa/cZCn37Npq7PFbhD5HDJqWfnoIvTaeRKMy5XdS2tO0MA0qbHDrnXAAA==}
'@oxlint/binding-linux-x64-gnu@1.71.0':
resolution: {integrity: sha512-cFDaiR8L3430qp88tfZnvFlt3KotFhR/DlbIL0nHOMMYiG/9Wy4l+6f7t8G8pTa9bd8Lt8+M0y/qjRQ/xcB74g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
'@oxlint/binding-linux-x64-musl@1.67.0':
resolution: {integrity: sha512-WmbMuLapKyDlobMkXAaAL0Y+Uczh4LETfIfQsUpbId4Ip8Ai82/jqeYTOoUCkuuhBFapgqP253+d83tLKOksJg==}
'@oxlint/binding-linux-x64-musl@1.71.0':
resolution: {integrity: sha512-orfixdt76KlpNly9z0PkWBBNfwjKz+JFVLP/7wnVchlKNU9Dpt9InU/ZggeSej6fC7qwHmHNOGlhLnQXcYoGuA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
'@oxlint/binding-openharmony-arm64@1.67.0':
resolution: {integrity: sha512-9g/PqxYJelzzTAOR5Y+RiRqdeydhEuXv2KxNeFcAKQ7UsvnWSY1OP4MsuPMbTO2Pf70tz7mFhl1j13H3fyh+8g==}
'@oxlint/binding-openharmony-arm64@1.71.0':
resolution: {integrity: sha512-9emQu2lAp6yhPB3XuI+++vR+l/o6JR1X+EpxwcumPdQXBWXEPAsquPGL7l158EqU8SebQMXTUa/S5zN98juyHw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxlint/binding-win32-arm64-msvc@1.67.0':
resolution: {integrity: sha512-2VhwE6Gatb0vJGnN0TBuQMbKCOiZlSQ/zJvVWYLK4a9d4iDiJOen/yVQkGpmsJ90MuH66fzi0kEKI0jRQMDxGA==}
'@oxlint/binding-win32-arm64-msvc@1.71.0':
resolution: {integrity: sha512-bd5kI8spYwTm3BILDtGhi73zoup5dw8MlPQNT8YB3BD5UIsjNe3K9/4ctrzQMX4SZMoK5HgzVLkLJzacEXB7fA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxlint/binding-win32-ia32-msvc@1.67.0':
resolution: {integrity: sha512-EQ3VExXfeM1InbE5+JjufhZZTWy+kHUwgt3yZR7gQ47Je/mE0WspQPan0OJznh493L5anM210YNJtH1PXjTSFg==}
'@oxlint/binding-win32-ia32-msvc@1.71.0':
resolution: {integrity: sha512-W4HvOHGzVLHcrmFu+bMrJlho+/yrlX5ZNdJZqGe8MEldkQG+RHYhxxad9P4jvWAYFmIqUA5i9DQ8QsJqSU9GIw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxlint/binding-win32-x64-msvc@1.67.0':
resolution: {integrity: sha512-bw24y+/1MHS4QDkons3YyHkPT9uCMoLHHgQhb+mb8NOjTYwub1CZ+K9Ngr8aO5DMrDrkqHwTzlTwFP2vS8Y/ZQ==}
'@oxlint/binding-win32-x64-msvc@1.71.0':
resolution: {integrity: sha512-D2kyEIPHk/G/wiZLnwTVC/sVst+T/lKldVOjAFpgTIBUAOlry72e5OiapDbDBF4LfJLkN5ypJb/8Eu6yJzkveQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
@@ -5105,8 +5105,8 @@ packages:
vite-plus:
optional: true
oxlint@1.67.0:
resolution: {integrity: sha512-blwwaHPdoH8piQ5/z0KHeoHFR7FZgl12WluKJfu4qFLPkZl6mK04PkLE45Fw1NxfBRSlh40Gu7MkxHUw++ociQ==}
oxlint@1.71.0:
resolution: {integrity: sha512-U1m1X+C0vDj7DC1e13IoZULzEcPczE7UOMTs8VlZGHUEIUaSTZKo5qkPsQEfzpgnQ29Pea/w3Xntk62UCecxZw==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -8423,61 +8423,61 @@ snapshots:
'@oxfmt/binding-win32-x64-msvc@0.52.0':
optional: true
'@oxlint/binding-android-arm-eabi@1.67.0':
'@oxlint/binding-android-arm-eabi@1.71.0':
optional: true
'@oxlint/binding-android-arm64@1.67.0':
'@oxlint/binding-android-arm64@1.71.0':
optional: true
'@oxlint/binding-darwin-arm64@1.67.0':
'@oxlint/binding-darwin-arm64@1.71.0':
optional: true
'@oxlint/binding-darwin-x64@1.67.0':
'@oxlint/binding-darwin-x64@1.71.0':
optional: true
'@oxlint/binding-freebsd-x64@1.67.0':
'@oxlint/binding-freebsd-x64@1.71.0':
optional: true
'@oxlint/binding-linux-arm-gnueabihf@1.67.0':
'@oxlint/binding-linux-arm-gnueabihf@1.71.0':
optional: true
'@oxlint/binding-linux-arm-musleabihf@1.67.0':
'@oxlint/binding-linux-arm-musleabihf@1.71.0':
optional: true
'@oxlint/binding-linux-arm64-gnu@1.67.0':
'@oxlint/binding-linux-arm64-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-arm64-musl@1.67.0':
'@oxlint/binding-linux-arm64-musl@1.71.0':
optional: true
'@oxlint/binding-linux-ppc64-gnu@1.67.0':
'@oxlint/binding-linux-ppc64-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-riscv64-gnu@1.67.0':
'@oxlint/binding-linux-riscv64-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-riscv64-musl@1.67.0':
'@oxlint/binding-linux-riscv64-musl@1.71.0':
optional: true
'@oxlint/binding-linux-s390x-gnu@1.67.0':
'@oxlint/binding-linux-s390x-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-x64-gnu@1.67.0':
'@oxlint/binding-linux-x64-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-x64-musl@1.67.0':
'@oxlint/binding-linux-x64-musl@1.71.0':
optional: true
'@oxlint/binding-openharmony-arm64@1.67.0':
'@oxlint/binding-openharmony-arm64@1.71.0':
optional: true
'@oxlint/binding-win32-arm64-msvc@1.67.0':
'@oxlint/binding-win32-arm64-msvc@1.71.0':
optional: true
'@oxlint/binding-win32-ia32-msvc@1.67.0':
'@oxlint/binding-win32-ia32-msvc@1.71.0':
optional: true
'@oxlint/binding-win32-x64-msvc@1.67.0':
'@oxlint/binding-win32-x64-msvc@1.71.0':
optional: true
'@pkgr/core@0.2.9': {}
@@ -12576,27 +12576,27 @@ snapshots:
'@oxfmt/binding-win32-ia32-msvc': 0.52.0
'@oxfmt/binding-win32-x64-msvc': 0.52.0
oxlint@1.67.0:
oxlint@1.71.0:
optionalDependencies:
'@oxlint/binding-android-arm-eabi': 1.67.0
'@oxlint/binding-android-arm64': 1.67.0
'@oxlint/binding-darwin-arm64': 1.67.0
'@oxlint/binding-darwin-x64': 1.67.0
'@oxlint/binding-freebsd-x64': 1.67.0
'@oxlint/binding-linux-arm-gnueabihf': 1.67.0
'@oxlint/binding-linux-arm-musleabihf': 1.67.0
'@oxlint/binding-linux-arm64-gnu': 1.67.0
'@oxlint/binding-linux-arm64-musl': 1.67.0
'@oxlint/binding-linux-ppc64-gnu': 1.67.0
'@oxlint/binding-linux-riscv64-gnu': 1.67.0
'@oxlint/binding-linux-riscv64-musl': 1.67.0
'@oxlint/binding-linux-s390x-gnu': 1.67.0
'@oxlint/binding-linux-x64-gnu': 1.67.0
'@oxlint/binding-linux-x64-musl': 1.67.0
'@oxlint/binding-openharmony-arm64': 1.67.0
'@oxlint/binding-win32-arm64-msvc': 1.67.0
'@oxlint/binding-win32-ia32-msvc': 1.67.0
'@oxlint/binding-win32-x64-msvc': 1.67.0
'@oxlint/binding-android-arm-eabi': 1.71.0
'@oxlint/binding-android-arm64': 1.71.0
'@oxlint/binding-darwin-arm64': 1.71.0
'@oxlint/binding-darwin-x64': 1.71.0
'@oxlint/binding-freebsd-x64': 1.71.0
'@oxlint/binding-linux-arm-gnueabihf': 1.71.0
'@oxlint/binding-linux-arm-musleabihf': 1.71.0
'@oxlint/binding-linux-arm64-gnu': 1.71.0
'@oxlint/binding-linux-arm64-musl': 1.71.0
'@oxlint/binding-linux-ppc64-gnu': 1.71.0
'@oxlint/binding-linux-riscv64-gnu': 1.71.0
'@oxlint/binding-linux-riscv64-musl': 1.71.0
'@oxlint/binding-linux-s390x-gnu': 1.71.0
'@oxlint/binding-linux-x64-gnu': 1.71.0
'@oxlint/binding-linux-x64-musl': 1.71.0
'@oxlint/binding-openharmony-arm64': 1.71.0
'@oxlint/binding-win32-arm64-msvc': 1.71.0
'@oxlint/binding-win32-ia32-msvc': 1.71.0
'@oxlint/binding-win32-x64-msvc': 1.71.0
p-limit@2.3.0:
dependencies:
+1 -1
View File
@@ -1,5 +1,5 @@
/* oxlint-disable react-doctor/no-adjust-state-on-prop-change -- Why: mobile browser state mirrors a remote desktop screencast session and CDP dialogs, which are external systems that cannot be derived during render. */
import { Buffer } from 'buffer'
import { Buffer } from 'node:buffer'
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
import {
ActivityIndicator,
+1 -1
View File
@@ -1,4 +1,4 @@
import { type ReactNode } from 'react'
import type { ReactNode } from 'react'
import { ActivityIndicator, View, Text, Pressable, StyleSheet } from 'react-native'
import { Edit3, Trash2, type LucideIcon } from 'lucide-react-native'
import { colors, spacing, typography } from '../theme/mobile-theme'
+1 -1
View File
@@ -2,7 +2,7 @@
* chunk upload, completion, and cancellation in one hook so native audio state
* cannot drift from the runtime RPC lifecycle. */
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { Buffer } from 'buffer'
import { Buffer } from 'node:buffer'
import {
addExpoTwoWayAudioEventListener,
initialize,
@@ -1,4 +1,4 @@
import { Buffer } from 'buffer'
import { Buffer } from 'node:buffer'
import * as DocumentPicker from 'expo-document-picker'
import * as ImagePicker from 'expo-image-picker'
@@ -1,9 +1,9 @@
import { useState } from 'react'
import type { ConnectionState } from '../transport/types'
import type { RpcClient } from '../transport/rpc-client'
import {
type MobileCommitFailureRecovery,
type RecordMobileCommitFailure
import type {
MobileCommitFailureRecovery,
RecordMobileCommitFailure
} from './mobile-commit-failure-recovery'
import { useMobileCommitFailureRecovery } from './use-mobile-commit-failure-recovery'
@@ -8,7 +8,7 @@ import {
isMobileGitTransientRefreshError,
type MobileGitStatusResult
} from './mobile-git-status'
import { type MobileGitBranchCompareResult } from './mobile-branch-compare'
import type { MobileGitBranchCompareResult } from './mobile-branch-compare'
import {
SELECTOR_RETRY_COUNT,
SELECTOR_RETRY_DELAY_MS,
@@ -84,7 +84,7 @@ describe('terminal accessory layout', () => {
})
it('preserves a custom v2 order and its visible subset', () => {
const reversed = [...getDefaultTerminalAccessoryBuiltInIds()].reverse()
const reversed = [...getDefaultTerminalAccessoryBuiltInIds()].toReversed()
expect(
normalizeTerminalAccessoryLayoutPreference({
+1 -1
View File
@@ -173,7 +173,7 @@
"mermaid": "^11.15.0",
"monaco-editor": "^0.55.1",
"oxfmt": "^0.52.0",
"oxlint": "^1.67.0",
"oxlint": "^1.71.0",
"oxlint-plugin-react-doctor": "0.2.10",
"oxlint-tsgolint": "0.23.0",
"pdfjs-dist": "^5.7.284",
+81 -81
View File
@@ -267,8 +267,8 @@ importers:
specifier: ^0.52.0
version: 0.52.0
oxlint:
specifier: ^1.67.0
version: 1.67.0(oxlint-tsgolint@0.23.0)
specifier: ^1.71.0
version: 1.71.0(oxlint-tsgolint@0.23.0)
oxlint-plugin-react-doctor:
specifier: 0.2.10
version: 0.2.10
@@ -1390,124 +1390,124 @@ packages:
cpu: [x64]
os: [win32]
'@oxlint/binding-android-arm-eabi@1.67.0':
resolution: {integrity: sha512-VrSi571rDv1N8HaEDM+DEX8nmT0y9jJo8tzzW13vsOWTx59xQczCIJx68n2zWOXRT5YKZsOZXp4qkHN/10x4mw==}
'@oxlint/binding-android-arm-eabi@1.71.0':
resolution: {integrity: sha512-ImGmd1njEg4FEJH03jhRnveEegtO3czCtfptvaHivKAZQIYATbVFBrrzbaYMYv0oJioTnxZAZVSyV+oL7W8S2g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxlint/binding-android-arm64@1.67.0':
resolution: {integrity: sha512-l6+NdYxMoRohix5r5bbigW16LPicceCwGcQ6LKKuE1kUdjgFfQolJjrJsQYPFetIs78Gxj/G/f5TEGoTCwj9nQ==}
'@oxlint/binding-android-arm64@1.71.0':
resolution: {integrity: sha512-4A5BEexBrwY1YFF8Kiq/lp/wQPRG79G3BWIE1FuWaM5MvmpYSd+7ZySVcKkHdwo0UDzdQGddp6pD9mpctMqLnw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxlint/binding-darwin-arm64@1.67.0':
resolution: {integrity: sha512-jOzXxS1AxFxhImLIRbtGIMrEwaXcgMw3gR57WB1cRk8ai+vpr6726kxXqVvlNsrXtJ/FrmOm8RxlC0m8SW24Qg==}
'@oxlint/binding-darwin-arm64@1.71.0':
resolution: {integrity: sha512-9wJA9GJulLwS2usU3CEisI/ESDO1n1z9eyTCvApMDrAkbJ1ve0mORgTMjcWWsKxkzkeZ2N/Gpra5IQE7x8tYgQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxlint/binding-darwin-x64@1.67.0':
resolution: {integrity: sha512-3DFAVY94OqjIZHXIPz37yGRSWwOFTAqChQ64/M69GYLawzP0KiwdhDNfqdKKYT0bTR/DNxmMnQsj3ns+8+X/Lg==}
'@oxlint/binding-darwin-x64@1.71.0':
resolution: {integrity: sha512-PlLCjS06V0PeJMAJwzjrExw1sYNW9Gch3JtNlcwwZDXGlTYDuwHNN89zYH8LTXFfgkVtsYvs2nv0FqrzyuFDzg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxlint/binding-freebsd-x64@1.67.0':
resolution: {integrity: sha512-e4dDKZuLu8TR9DEBssWSDahlPgZBwojTTHZUvnjBRJfJJbpxYCjfjKfi0Z1+CSLMiJBwI2yCDtRM1XJQaARjmg==}
'@oxlint/binding-freebsd-x64@1.71.0':
resolution: {integrity: sha512-Lhil7bWre0ncxbUoDoxfS0JzpTz17BRQKW7iwoAUY8GJ66+WwJEfYPCFJ1P0WgVZR5/O/b3Q2pENlHOjeXLOGQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxlint/binding-linux-arm-gnueabihf@1.67.0':
resolution: {integrity: sha512-BKytFdcQzbITV3xlnzDUDTEDtbUMCCiC4EaNTDZ4FyT8gdNvBC4gfiLucXp/sQl0XU3p7syTlorUWVVVBZab2g==}
'@oxlint/binding-linux-arm-gnueabihf@1.71.0':
resolution: {integrity: sha512-Oo9/L58PYD3RC0x05d2upAPLllHytTjHQGsnC06P6Ynn7jKkp5mdImQxXdJ3+FnBaKspNpGogzgVsi6g872LiA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm-musleabihf@1.67.0':
resolution: {integrity: sha512-XYAv0esBDX7BpTzRDjVX2Vdj+zndd8ll2dFQiaeQ6zTZr7A8GRDTN7fH3FP3jU+O0vCDx85oH/EtG7BzPgAXuw==}
'@oxlint/binding-linux-arm-musleabihf@1.71.0':
resolution: {integrity: sha512-mSHfyfgJrEbyIR29ejaeS50BdPk+GoNPlC1dckpDiUZbJAIel68sjSMdOt4WY0/gva+ECC7FNITQkxMJU+vSBw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxlint/binding-linux-arm64-gnu@1.67.0':
resolution: {integrity: sha512-zizRMjA0i6u/2B0evgda04iycu+MoNuf1pBy6Eh+1CjC5wMEG7qN5zdDKTCvFc0KSYSDM9QTG3gjZHirgtQuKg==}
'@oxlint/binding-linux-arm64-gnu@1.71.0':
resolution: {integrity: sha512-n9yY4M2tiy3aij4AqtlnspzpfdpeT5JQfK2/w2d8oyp5W0FRwOb1dIeX99nORNcxGr08iD9bH8N5XFz3I2iy8w==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-arm64-musl@1.67.0':
resolution: {integrity: sha512-zB/Tf6sUjmmvvbva9Gj3JTJ8rJ9t4I8/U0o6vSRtd0DRIsIuyegBwJAzhSUFQHdMijIRJkW0exs/yBhpw2S20w==}
'@oxlint/binding-linux-arm64-musl@1.71.0':
resolution: {integrity: sha512-fJZrs5sDZtTaPIOiemRQQmo82Ezy+vOGXemPc4Ok7iVVsYsFa7SlW6Z5XN819VfsqBHRm3NJ3rTdnR8+bJYJdQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxlint/binding-linux-ppc64-gnu@1.67.0':
resolution: {integrity: sha512-kgU40Gt74CK0TCsF51KZymkIwN9U0BajKsMijB52zPqOeZU9NAHkA/NSQkZDHEaCakx42DxhXkODiAqf2b4Gug==}
'@oxlint/binding-linux-ppc64-gnu@1.71.0':
resolution: {integrity: sha512-cwl7VKGERIy9p+G+AvZdfy/06q0aHXaTt/mMRReC751iuNYJgqKjB7NydXSS30nBT9vtr2tunciOtrR4fD6FUA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-riscv64-gnu@1.67.0':
resolution: {integrity: sha512-tOYhkk/iaG9aD3FvGpBFd1Lrw0x0RaVoJBxjUkfNzS50rC5NS5BteNCwgr8A2zCdADrIIoze6D7u6U5Ic++/iQ==}
'@oxlint/binding-linux-riscv64-gnu@1.71.0':
resolution: {integrity: sha512-eZ8ieVXvzGi8jr7+ybQGPK2STw3mldfxZlgA2738iflfB/rzA69sE6m5rDRpQaxC7dpm745Enlh1Tod0QAk9Gg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-riscv64-musl@1.67.0':
resolution: {integrity: sha512-sEtywrPb+0b+tHYl1SDCrw903fiC4eyKoNqzP3v+f2JT3Xcv4NEYG+P8rj+eEnX7IWhqV/xj8/JmcmVj21CXaA==}
'@oxlint/binding-linux-riscv64-musl@1.71.0':
resolution: {integrity: sha512-puMDbQYe6+NXwfMusojoA7CXGn2b3utukmd23PQqc1E3XhVCwyZ+FueSMzDYeNgDV2dUfIVXAAKZBcFDeCL6sA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxlint/binding-linux-s390x-gnu@1.67.0':
resolution: {integrity: sha512-BvR8Moa0zCLxroOx4vZaZN9nUfwAUpSTwjZdxZyKy4bv3PrzrXrxKR/ZQ0L9wNSvlPhnMJeZfa3q5w6ZCTuN6Q==}
'@oxlint/binding-linux-s390x-gnu@1.71.0':
resolution: {integrity: sha512-4NJLxBs1ujISCt3L/1FcywLs73PWtJuw+piD6feK2V6h6OS6P7xu9/sWt1DTRLibe6QCzmfZzmM/2HPORoV/Lg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-x64-gnu@1.67.0':
resolution: {integrity: sha512-mm2cxM6fksOpq6l0uFws8BUGKAR4dNa/cZCn37Npq7PFbhD5HDJqWfnoIvTaeRKMy5XdS2tO0MA0qbHDrnXAAA==}
'@oxlint/binding-linux-x64-gnu@1.71.0':
resolution: {integrity: sha512-cFDaiR8L3430qp88tfZnvFlt3KotFhR/DlbIL0nHOMMYiG/9Wy4l+6f7t8G8pTa9bd8Lt8+M0y/qjRQ/xcB74g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxlint/binding-linux-x64-musl@1.67.0':
resolution: {integrity: sha512-WmbMuLapKyDlobMkXAaAL0Y+Uczh4LETfIfQsUpbId4Ip8Ai82/jqeYTOoUCkuuhBFapgqP253+d83tLKOksJg==}
'@oxlint/binding-linux-x64-musl@1.71.0':
resolution: {integrity: sha512-orfixdt76KlpNly9z0PkWBBNfwjKz+JFVLP/7wnVchlKNU9Dpt9InU/ZggeSej6fC7qwHmHNOGlhLnQXcYoGuA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxlint/binding-openharmony-arm64@1.67.0':
resolution: {integrity: sha512-9g/PqxYJelzzTAOR5Y+RiRqdeydhEuXv2KxNeFcAKQ7UsvnWSY1OP4MsuPMbTO2Pf70tz7mFhl1j13H3fyh+8g==}
'@oxlint/binding-openharmony-arm64@1.71.0':
resolution: {integrity: sha512-9emQu2lAp6yhPB3XuI+++vR+l/o6JR1X+EpxwcumPdQXBWXEPAsquPGL7l158EqU8SebQMXTUa/S5zN98juyHw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxlint/binding-win32-arm64-msvc@1.67.0':
resolution: {integrity: sha512-2VhwE6Gatb0vJGnN0TBuQMbKCOiZlSQ/zJvVWYLK4a9d4iDiJOen/yVQkGpmsJ90MuH66fzi0kEKI0jRQMDxGA==}
'@oxlint/binding-win32-arm64-msvc@1.71.0':
resolution: {integrity: sha512-bd5kI8spYwTm3BILDtGhi73zoup5dw8MlPQNT8YB3BD5UIsjNe3K9/4ctrzQMX4SZMoK5HgzVLkLJzacEXB7fA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxlint/binding-win32-ia32-msvc@1.67.0':
resolution: {integrity: sha512-EQ3VExXfeM1InbE5+JjufhZZTWy+kHUwgt3yZR7gQ47Je/mE0WspQPan0OJznh493L5anM210YNJtH1PXjTSFg==}
'@oxlint/binding-win32-ia32-msvc@1.71.0':
resolution: {integrity: sha512-W4HvOHGzVLHcrmFu+bMrJlho+/yrlX5ZNdJZqGe8MEldkQG+RHYhxxad9P4jvWAYFmIqUA5i9DQ8QsJqSU9GIw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxlint/binding-win32-x64-msvc@1.67.0':
resolution: {integrity: sha512-bw24y+/1MHS4QDkons3YyHkPT9uCMoLHHgQhb+mb8NOjTYwub1CZ+K9Ngr8aO5DMrDrkqHwTzlTwFP2vS8Y/ZQ==}
'@oxlint/binding-win32-x64-msvc@1.71.0':
resolution: {integrity: sha512-D2kyEIPHk/G/wiZLnwTVC/sVst+T/lKldVOjAFpgTIBUAOlry72e5OiapDbDBF4LfJLkN5ypJb/8Eu6yJzkveQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
@@ -5364,8 +5364,8 @@ packages:
resolution: {integrity: sha512-3mBv3CoPbh8dFbzfDGIWa2ytZjn2v+3EX4aKRXjIhsoGFzG8GCjfRirz3rwZf1wYbZzsNLTSgpw8VjQuWdp/jA==}
hasBin: true
oxlint@1.67.0:
resolution: {integrity: sha512-blwwaHPdoH8piQ5/z0KHeoHFR7FZgl12WluKJfu4qFLPkZl6mK04PkLE45Fw1NxfBRSlh40Gu7MkxHUw++ociQ==}
oxlint@1.71.0:
resolution: {integrity: sha512-U1m1X+C0vDj7DC1e13IoZULzEcPczE7UOMTs8VlZGHUEIUaSTZKo5qkPsQEfzpgnQ29Pea/w3Xntk62UCecxZw==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -7546,61 +7546,61 @@ snapshots:
'@oxlint-tsgolint/win32-x64@0.23.0':
optional: true
'@oxlint/binding-android-arm-eabi@1.67.0':
'@oxlint/binding-android-arm-eabi@1.71.0':
optional: true
'@oxlint/binding-android-arm64@1.67.0':
'@oxlint/binding-android-arm64@1.71.0':
optional: true
'@oxlint/binding-darwin-arm64@1.67.0':
'@oxlint/binding-darwin-arm64@1.71.0':
optional: true
'@oxlint/binding-darwin-x64@1.67.0':
'@oxlint/binding-darwin-x64@1.71.0':
optional: true
'@oxlint/binding-freebsd-x64@1.67.0':
'@oxlint/binding-freebsd-x64@1.71.0':
optional: true
'@oxlint/binding-linux-arm-gnueabihf@1.67.0':
'@oxlint/binding-linux-arm-gnueabihf@1.71.0':
optional: true
'@oxlint/binding-linux-arm-musleabihf@1.67.0':
'@oxlint/binding-linux-arm-musleabihf@1.71.0':
optional: true
'@oxlint/binding-linux-arm64-gnu@1.67.0':
'@oxlint/binding-linux-arm64-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-arm64-musl@1.67.0':
'@oxlint/binding-linux-arm64-musl@1.71.0':
optional: true
'@oxlint/binding-linux-ppc64-gnu@1.67.0':
'@oxlint/binding-linux-ppc64-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-riscv64-gnu@1.67.0':
'@oxlint/binding-linux-riscv64-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-riscv64-musl@1.67.0':
'@oxlint/binding-linux-riscv64-musl@1.71.0':
optional: true
'@oxlint/binding-linux-s390x-gnu@1.67.0':
'@oxlint/binding-linux-s390x-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-x64-gnu@1.67.0':
'@oxlint/binding-linux-x64-gnu@1.71.0':
optional: true
'@oxlint/binding-linux-x64-musl@1.67.0':
'@oxlint/binding-linux-x64-musl@1.71.0':
optional: true
'@oxlint/binding-openharmony-arm64@1.67.0':
'@oxlint/binding-openharmony-arm64@1.71.0':
optional: true
'@oxlint/binding-win32-arm64-msvc@1.67.0':
'@oxlint/binding-win32-arm64-msvc@1.71.0':
optional: true
'@oxlint/binding-win32-ia32-msvc@1.67.0':
'@oxlint/binding-win32-ia32-msvc@1.71.0':
optional: true
'@oxlint/binding-win32-x64-msvc@1.67.0':
'@oxlint/binding-win32-x64-msvc@1.71.0':
optional: true
'@parcel/watcher-android-arm64@2.5.6':
@@ -11869,27 +11869,27 @@ snapshots:
'@oxlint-tsgolint/win32-arm64': 0.23.0
'@oxlint-tsgolint/win32-x64': 0.23.0
oxlint@1.67.0(oxlint-tsgolint@0.23.0):
oxlint@1.71.0(oxlint-tsgolint@0.23.0):
optionalDependencies:
'@oxlint/binding-android-arm-eabi': 1.67.0
'@oxlint/binding-android-arm64': 1.67.0
'@oxlint/binding-darwin-arm64': 1.67.0
'@oxlint/binding-darwin-x64': 1.67.0
'@oxlint/binding-freebsd-x64': 1.67.0
'@oxlint/binding-linux-arm-gnueabihf': 1.67.0
'@oxlint/binding-linux-arm-musleabihf': 1.67.0
'@oxlint/binding-linux-arm64-gnu': 1.67.0
'@oxlint/binding-linux-arm64-musl': 1.67.0
'@oxlint/binding-linux-ppc64-gnu': 1.67.0
'@oxlint/binding-linux-riscv64-gnu': 1.67.0
'@oxlint/binding-linux-riscv64-musl': 1.67.0
'@oxlint/binding-linux-s390x-gnu': 1.67.0
'@oxlint/binding-linux-x64-gnu': 1.67.0
'@oxlint/binding-linux-x64-musl': 1.67.0
'@oxlint/binding-openharmony-arm64': 1.67.0
'@oxlint/binding-win32-arm64-msvc': 1.67.0
'@oxlint/binding-win32-ia32-msvc': 1.67.0
'@oxlint/binding-win32-x64-msvc': 1.67.0
'@oxlint/binding-android-arm-eabi': 1.71.0
'@oxlint/binding-android-arm64': 1.71.0
'@oxlint/binding-darwin-arm64': 1.71.0
'@oxlint/binding-darwin-x64': 1.71.0
'@oxlint/binding-freebsd-x64': 1.71.0
'@oxlint/binding-linux-arm-gnueabihf': 1.71.0
'@oxlint/binding-linux-arm-musleabihf': 1.71.0
'@oxlint/binding-linux-arm64-gnu': 1.71.0
'@oxlint/binding-linux-arm64-musl': 1.71.0
'@oxlint/binding-linux-ppc64-gnu': 1.71.0
'@oxlint/binding-linux-riscv64-gnu': 1.71.0
'@oxlint/binding-linux-riscv64-musl': 1.71.0
'@oxlint/binding-linux-s390x-gnu': 1.71.0
'@oxlint/binding-linux-x64-gnu': 1.71.0
'@oxlint/binding-linux-x64-musl': 1.71.0
'@oxlint/binding-openharmony-arm64': 1.71.0
'@oxlint/binding-win32-arm64-msvc': 1.71.0
'@oxlint/binding-win32-ia32-msvc': 1.71.0
'@oxlint/binding-win32-x64-msvc': 1.71.0
oxlint-tsgolint: 0.23.0
p-cancelable@2.1.1: {}
+11 -3
View File
@@ -1,6 +1,14 @@
import { chmodSync, lstatSync, mkdirSync, readdirSync, rmSync, statSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import {
chmodSync,
lstatSync,
mkdirSync,
readdirSync,
rmSync,
statSync,
writeFileSync
} from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { formatBase64PayloadByteCount } from './base64-payload-byte-count'
import { quoteCliCommandArgument } from './shell-command-quote'
import type {
+3 -3
View File
@@ -1,6 +1,6 @@
import { existsSync, mkdtempSync, rmSync, utimesSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { existsSync, mkdtempSync, rmSync, utimesSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { quoteCliCommandArgument } from './shell-command-quote'
import { RuntimeRpcFailureError } from './runtime-client'
+3 -3
View File
@@ -1,6 +1,6 @@
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { getDefaultPersistedState } from '../../shared/constants'
import type { PersistedState } from '../../shared/types'
+4 -4
View File
@@ -1,7 +1,7 @@
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'fs'
import { homedir } from 'os'
import { dirname, join } from 'path'
import { randomUUID } from 'crypto'
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs'
import { homedir } from 'node:os'
import { dirname, join } from 'node:path'
import { randomUUID } from 'node:crypto'
import type { CommandHandler } from '../dispatch'
import { printResult } from '../format'
import { RuntimeClientError, type RuntimeClient, type RuntimeRpcSuccess } from '../runtime-client'
+1 -1
View File
@@ -1,4 +1,4 @@
import { spawn } from 'child_process'
import { spawn } from 'node:child_process'
import type { CommandHandler } from '../dispatch'
import { formatCliStatus, formatStatus, printResult } from '../format'
import { RuntimeClientError, serveOrcaApp } from '../runtime-client'
+1 -1
View File
@@ -1,4 +1,4 @@
import path from 'path'
import path from 'node:path'
import { beforeEach, describe, expect, it, vi } from 'vitest'
const { callMock, remoteMock } = vi.hoisted(() => ({
+2 -2
View File
@@ -1,5 +1,5 @@
/* eslint-disable max-lines -- Why: CLI parser tests share one mocked runtime client and fixture queue; splitting this file would duplicate setup and make command coverage harder to audit. */
import path from 'path'
import path from 'node:path'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
const {
@@ -82,7 +82,7 @@ vi.mock('./runtime/environments', () => ({
}))
vi.mock('child_process', async () => {
const { EventEmitter } = await import('events')
const { EventEmitter } = await import('node:events')
return {
spawn: spawnMock.mockImplementation(() => {
const child = new EventEmitter()
+1 -1
View File
@@ -1,4 +1,4 @@
import { resolve as resolvePath } from 'path'
import { resolve as resolvePath } from 'node:path'
import { RuntimeClientError } from './runtime-client'
function isAbsoluteServerPath(value: string): boolean {
+4 -4
View File
@@ -1,7 +1,7 @@
import { mkdtempSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { createServer, type Socket } from 'net'
import { mkdtempSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { createServer, type Socket } from 'node:net'
import { afterEach, describe, expect, it } from 'vitest'
import { RuntimeClient, RuntimeRpcFailureError } from './runtime-client'
@@ -1,7 +1,7 @@
import { mkdtempSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { createServer, type Server, type Socket } from 'net'
import { mkdtempSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { createServer, type Server, type Socket } from 'node:net'
import { afterEach, describe, expect, it } from 'vitest'
import { RuntimeClient } from './client'
+3 -3
View File
@@ -1,6 +1,6 @@
import { mkdtempSync, statSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdtempSync, statSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { describe, expect, it } from 'vitest'
import { encodePairingOffer } from '../../shared/pairing'
import {
+2 -2
View File
@@ -1,5 +1,5 @@
import { EventEmitter } from 'events'
import { resolve } from 'path'
import { EventEmitter } from 'node:events'
import { resolve } from 'node:path'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
const { spawnMock } = vi.hoisted(() => ({
+2 -2
View File
@@ -1,5 +1,5 @@
import { spawn as spawnProcess, type SpawnOptions } from 'child_process'
import { dirname, resolve } from 'path'
import { spawn as spawnProcess, type SpawnOptions } from 'node:child_process'
import { dirname, resolve } from 'node:path'
import { RuntimeClientError } from './types'
export function launchOrcaApp(): void {
+3 -3
View File
@@ -1,6 +1,6 @@
import { homedir } from 'os'
import { join } from 'path'
import { readFileSync } from 'fs'
import { homedir } from 'node:os'
import { join } from 'node:path'
import { readFileSync } from 'node:fs'
import {
findTransport,
getRuntimeMetadataPath,
+4 -4
View File
@@ -1,7 +1,7 @@
import { mkdtempSync, writeFileSync } from 'fs'
import { createServer, type Socket } from 'net'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdtempSync, writeFileSync } from 'node:fs'
import { createServer, type Socket } from 'node:net'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { getRuntimeMetadataPath } from '../../shared/runtime-bootstrap'
import { RuntimeClient } from './client'
+4 -4
View File
@@ -1,7 +1,7 @@
import { mkdtempSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { createServer, type Socket } from 'net'
import { mkdtempSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { createServer, type Socket } from 'node:net'
import { afterEach, describe, expect, it } from 'vitest'
import type { RuntimeMetadata } from '../../shared/runtime-bootstrap'
import { sendRequest } from './transport'
+2 -2
View File
@@ -1,5 +1,5 @@
import { createConnection } from 'net'
import { randomUUID } from 'crypto'
import { createConnection } from 'node:net'
import { randomUUID } from 'node:crypto'
import { findTransport, type RuntimeMetadata } from '../../shared/runtime-bootstrap'
import { isKeepaliveFrame, RuntimeRpcEnvelopeSchema } from './envelope-schema'
import { RuntimeClientError, type RuntimeRpcResponse } from './types'
+4 -4
View File
@@ -1,7 +1,7 @@
import { createServer, type Server } from 'http'
import { mkdtempSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { createServer, type Server } from 'node:http'
import { mkdtempSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { WebSocketServer } from 'ws'
import { encodePairingOffer, type PairingOffer } from '../../shared/pairing'
+1 -1
View File
@@ -1,4 +1,4 @@
import { isAbsolute, relative, resolve as resolvePath } from 'path'
import { isAbsolute, relative, resolve as resolvePath } from 'node:path'
import type {
ComputerAppQuery,
RuntimeWorktreeListResult,
@@ -11,7 +11,7 @@
//
// See docs/design/agent-status-over-ssh.md §8 (commit #8).
import { randomUUID } from 'crypto'
import { randomUUID } from 'node:crypto'
import type { SFTPWrapper, FileEntryWithStats } from 'ssh2'
import { isPlainObject, type HooksConfig } from './installer-utils'
+4 -4
View File
@@ -9,10 +9,10 @@ import {
statSync,
writeFileSync,
chmodSync
} from 'fs'
import { homedir, tmpdir } from 'os'
import { join } from 'path'
import { spawnSync } from 'child_process'
} from 'node:fs'
import { homedir, tmpdir } from 'node:os'
import { join } from 'node:path'
import { spawnSync } from 'node:child_process'
import {
buildWindowsAgentHookPostCommand,
buildWindowsAgentHookCurlPostCommand,
+4 -4
View File
@@ -7,10 +7,10 @@ import {
copyFileSync,
renameSync,
unlinkSync
} from 'fs'
import { homedir } from 'os'
import { dirname, join } from 'path'
import { randomUUID } from 'crypto'
} from 'node:fs'
import { homedir } from 'node:os'
import { dirname, join } from 'node:path'
import { randomUUID } from 'node:crypto'
import type { AgentHookSource } from '../../shared/agent-hook-relay'
import { grantDirAcl, isPermissionError } from '../win32-utils'
@@ -2,13 +2,13 @@
// managed agent (config entries, wrapper curl flags, and a real dead-endpoint
// shell run) so the cross-agent coverage lives together rather than fragmenting.
import { afterEach, describe, expect, it, vi } from 'vitest'
import { spawn, spawnSync } from 'child_process'
import { createServer, type Server, type Socket } from 'net'
import { chmodSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { spawn, spawnSync } from 'node:child_process'
import { createServer, type Server, type Socket } from 'node:net'
import { chmodSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import type { SFTPWrapper } from 'ssh2'
import type * as osModule from 'os'
import type * as osModule from 'node:os'
const { homedirMock } = vi.hoisted(() => ({
homedirMock: vi.fn<() => string>()
+4 -4
View File
@@ -1,6 +1,6 @@
/* eslint-disable max-lines -- Why: this suite exercises the full hook HTTP surface (Claude/Codex/Gemini parsing, transcript chunked scan, paneKey dispatch) and keeping the scenarios co-located avoids fixture drift across files. */
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { execFileSync } from 'child_process'
import { execFileSync } from 'node:child_process'
import {
existsSync,
mkdirSync,
@@ -10,9 +10,9 @@ import {
statSync,
utimesSync,
writeFileSync
} from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
} from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { AgentHookServer, agentHookServer, _internals } from './server'
import {
AGENT_STATUS_MAX_FIELD_LENGTH,
+4 -4
View File
@@ -10,10 +10,10 @@
// events (see docs/design/agent-status-over-ssh.md §5)
// - the on-disk last-status cache (`last-status.json`) that survives
// Orca restart so retained dashboard rows reappear on relaunch
import { createServer, type IncomingMessage, type ServerResponse } from 'http'
import { createHash, randomBytes, randomUUID } from 'crypto'
import { chmodSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'fs'
import { join } from 'path'
import { createServer, type IncomingMessage, type ServerResponse } from 'node:http'
import { createHash, randomBytes, randomUUID } from 'node:crypto'
import { chmodSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs'
import { join } from 'node:path'
import { track } from '../telemetry/client'
import { getCohortAtEmit } from '../telemetry/cohort-classifier'
@@ -1,4 +1,4 @@
import { basename, extname } from 'path'
import { basename, extname } from 'node:path'
import {
aiVaultAgentLabel,
buildAiVaultResumeCommand,
@@ -1,6 +1,6 @@
import { mkdir, mkdtemp, rm, stat, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { dirname, join } from 'path'
import { mkdir, mkdtemp, rm, stat, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { parseCodexSessionFile } from './session-scanner-codex-parser'
@@ -1,7 +1,7 @@
import { createReadStream } from 'fs'
import { stat } from 'fs/promises'
import { basename, dirname, join } from 'path'
import { createInterface } from 'readline'
import { createReadStream } from 'node:fs'
import { stat } from 'node:fs/promises'
import { basename, dirname, join } from 'node:path'
import { createInterface } from 'node:readline'
import type { AiVaultSession } from '../../shared/ai-vault-types'
import {
addPreviewContent,
@@ -1,4 +1,4 @@
import { dirname, resolve } from 'path'
import { dirname, resolve } from 'node:path'
export function codexHomeForSessionsDir(
sessionsDir: string,
@@ -1,6 +1,6 @@
import { mkdir, mkdtemp, rm, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { scanAiVaultSessions } from './session-scanner'
@@ -1,6 +1,6 @@
import { mkdtemp, rm, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { parseDevinSessionFile } from './session-scanner-devin-parser'
@@ -1,4 +1,4 @@
import { readFile } from 'fs/promises'
import { readFile } from 'node:fs/promises'
import type { AiVaultSession } from '../../shared/ai-vault-types'
import type { FileWithMtime } from './session-scanner-types'
import {
@@ -1,5 +1,5 @@
import { readdir, stat } from 'fs/promises'
import { basename, delimiter, extname, join } from 'path'
import { readdir, stat } from 'node:fs/promises'
import { basename, delimiter, extname, join } from 'node:path'
import type { AiVaultAgent, AiVaultScanIssue } from '../../shared/ai-vault-types'
import type { FileWithMtime, SessionFileDiscovery } from './session-scanner-types'
import { errorMessage } from './session-scanner-values'
@@ -1,5 +1,5 @@
import { homedir } from 'os'
import { basename, dirname, join } from 'path'
import { homedir } from 'node:os'
import { basename, dirname, join } from 'node:path'
import type { AiVaultScanIssue } from '../../shared/ai-vault-types'
import { discoverFiles } from './session-scanner-discovery'
import { resolveKimiSessionsDir } from './session-scanner-kimi-paths'
@@ -1,7 +1,7 @@
import { createReadStream } from 'fs'
import { readFile } from 'fs/promises'
import { basename, dirname, join } from 'path'
import { createInterface } from 'readline'
import { createReadStream } from 'node:fs'
import { readFile } from 'node:fs/promises'
import { basename, dirname, join } from 'node:path'
import { createInterface } from 'node:readline'
import type { AiVaultSession } from '../../shared/ai-vault-types'
import type { FileWithMtime, SessionAccumulator } from './session-scanner-types'
import {
@@ -1,7 +1,7 @@
import { createReadStream } from 'fs'
import { readFile } from 'fs/promises'
import { dirname, join } from 'path'
import { createInterface } from 'readline'
import { createReadStream } from 'node:fs'
import { readFile } from 'node:fs/promises'
import { dirname, join } from 'node:path'
import { createInterface } from 'node:readline'
import type { AiVaultSession } from '../../shared/ai-vault-types'
import type { FileWithMtime, SessionAccumulator } from './session-scanner-types'
import {
@@ -1,6 +1,6 @@
import { mkdir, mkdtemp, rm, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { parseKimiSessionFile } from './session-scanner-kimi-parser'
import { clearKimiSessionIndexCache } from './session-scanner-kimi-paths'
@@ -1,6 +1,6 @@
import { createReadStream } from 'fs'
import { readFile } from 'fs/promises'
import { createInterface } from 'readline'
import { createReadStream } from 'node:fs'
import { readFile } from 'node:fs/promises'
import { createInterface } from 'node:readline'
import type { AiVaultSession } from '../../shared/ai-vault-types'
import {
addPreviewContent,
@@ -1,8 +1,8 @@
import { stat } from 'fs/promises'
import { createReadStream } from 'fs'
import { homedir } from 'os'
import { basename, dirname, join } from 'path'
import { createInterface } from 'readline'
import { stat } from 'node:fs/promises'
import { createReadStream } from 'node:fs'
import { homedir } from 'node:os'
import { basename, dirname, join } from 'node:path'
import { createInterface } from 'node:readline'
import { asRecord, extractString } from './session-scanner-values'
// Why: Kimi Code stores sessions under <KIMI_CODE_HOME>/sessions/, mirroring the
@@ -1,6 +1,6 @@
import { readdir } from 'fs/promises'
import { homedir } from 'os'
import { dirname, join } from 'path'
import { readdir } from 'node:fs/promises'
import { homedir } from 'node:os'
import { dirname, join } from 'node:path'
import type { AiVaultScanIssue } from '../../shared/ai-vault-types'
import { listOpenCodeDatabases } from '../opencode-usage/scanner'
import { discoverOpenCodeSessions } from './session-scanner-opencode-sqlite-discovery'
@@ -1,7 +1,7 @@
import { mkdtemp, mkdir, rm, writeFile } from 'fs/promises'
import { mkdtempSync, rmSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'
import { mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { scanAiVaultSessions } from './session-scanner'
import Database from '../sqlite/sync-database'
@@ -1,4 +1,4 @@
import { basename, extname, join } from 'path'
import { basename, extname, join } from 'node:path'
import type { AiVaultAgent, AiVaultScanIssue } from '../../shared/ai-vault-types'
import { discoverFiles } from './session-scanner-discovery'
import { buildOpenCodeSqliteCandidatePath } from './session-scanner-opencode-sqlite-paths'
@@ -1,4 +1,4 @@
import { basename } from 'path'
import { basename } from 'node:path'
// Why: keep the synthetic candidate-path helpers separate from the SQLite
// discovery/parser so both the scanner and the agent-parser dispatcher can
@@ -1,6 +1,6 @@
import { mkdtempSync, rmSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import Database from '../sqlite/sync-database'
import { buildOpenCodeSqliteCandidatePath } from './session-scanner-opencode-sqlite-paths'
@@ -1,6 +1,6 @@
import { createReadStream } from 'fs'
import { readFile } from 'fs/promises'
import { createInterface } from 'readline'
import { createReadStream } from 'node:fs'
import { readFile } from 'node:fs/promises'
import { createInterface } from 'node:readline'
import type { AiVaultSession } from '../../shared/ai-vault-types'
import type { FileWithMtime, SessionAccumulator } from './session-scanner-types'
import {
@@ -1,7 +1,7 @@
import { createReadStream } from 'fs'
import { readdir, stat } from 'fs/promises'
import { createInterface } from 'readline'
import { extname, join } from 'path'
import { createReadStream } from 'node:fs'
import { readdir, stat } from 'node:fs/promises'
import { createInterface } from 'node:readline'
import { extname, join } from 'node:path'
import {
isPathInsideOrEqual,
normalizeRuntimePathForComparison
@@ -1,6 +1,6 @@
import { mkdtemp, mkdir, rm, utimes, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdtemp, mkdir, rm, utimes, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it } from 'vitest'
import { scanAiVaultSessions } from './session-scanner'
import type { AiVaultScanOptions } from './session-scanner-types'
@@ -1,7 +1,7 @@
import { createReadStream } from 'fs'
import { readFile, readdir } from 'fs/promises'
import { join } from 'path'
import { createInterface } from 'readline'
import { createReadStream } from 'node:fs'
import { readFile, readdir } from 'node:fs/promises'
import { join } from 'node:path'
import { createInterface } from 'node:readline'
import type { AiVaultSession } from '../../shared/ai-vault-types'
import type { FileWithMtime, SessionAccumulator } from './session-scanner-types'
import {
@@ -1,5 +1,5 @@
import { homedir } from 'os'
import { basename, join } from 'path'
import { homedir } from 'node:os'
import { basename, join } from 'node:path'
import type { AiVaultScanIssue } from '../../shared/ai-vault-types'
import { uniqueCodexSessionsDirs } from './session-scanner-codex-paths'
import { discoverFiles, discoverOpenClawFiles } from './session-scanner-discovery'
+3 -3
View File
@@ -1,6 +1,6 @@
import { homedir } from 'os'
import { basename, dirname, join } from 'path'
import { readFile } from 'fs/promises'
import { homedir } from 'node:os'
import { basename, dirname, join } from 'node:path'
import { readFile } from 'node:fs/promises'
export function timestampMs(value: unknown): number {
if (typeof value === 'string') {
+3 -3
View File
@@ -1,6 +1,6 @@
import { mkdtemp, mkdir, rm, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it, vi } from 'vitest'
import { AI_VAULT_AGENTS, buildAiVaultResumeCommand } from '../../shared/ai-vault-types'
import { scanAiVaultSessions } from './session-scanner'
+3 -3
View File
@@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { dirname, join } from 'path'
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
const { homedirMock } = vi.hoisted(() => ({
homedirMock: vi.fn<() => string>()
+4 -4
View File
@@ -2,10 +2,10 @@
managed Amp plugin source and ownership marker. Splitting would make the
emitted plugin bytes drift from the installer checks that protect user
plugin files from being overwritten. */
import { randomUUID } from 'crypto'
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'fs'
import { homedir } from 'os'
import { dirname, join } from 'path'
import { randomUUID } from 'node:crypto'
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs'
import { homedir } from 'node:os'
import { dirname, join } from 'node:path'
import type { SFTPWrapper } from 'ssh2'
import type { AgentHookInstallStatus } from '../../shared/agent-hook-types'
+3 -3
View File
@@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { dirname, join } from 'path'
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
const { homedirMock } = vi.hoisted(() => ({
homedirMock: vi.fn<() => string>()
+2 -2
View File
@@ -1,8 +1,8 @@
/* eslint-disable max-lines -- Why: local Antigravity install, Windows wrapper
generation, status cleanup, and SSH remote install must share one event list
and managed-command matcher so stale hook cleanup cannot drift by platform. */
import { homedir } from 'os'
import { join } from 'path'
import { homedir } from 'node:os'
import { join } from 'node:path'
import type { SFTPWrapper } from 'ssh2'
import type { AgentHookInstallState, AgentHookInstallStatus } from '../../shared/agent-hook-types'
import {
+2 -2
View File
@@ -2,8 +2,8 @@
scripts for both POSIX shells and Windows shells. Keeping the scripts adjacent
to the env injection code makes the attribution behavior auditable as one unit
instead of scattering generated shell fragments across files. */
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
import { join, win32 as pathWin32 } from 'path'
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
import { join, win32 as pathWin32 } from 'node:path'
import { ORCA_GIT_COMMIT_TRAILER } from '../../shared/orca-attribution'
const ATTRIBUTION_ROOT_DIR = 'orca-terminal-attribution'
+1 -1
View File
@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto'
import { randomUUID } from 'node:crypto'
const DISPATCH_TOKEN_TTL_MS = 30 * 60_000
@@ -10,7 +10,7 @@ import {
import { mapHermesJobs, mapOpenClawJobs } from './external-job-mappers'
import { getActiveMultiplexer } from '../ipc/ssh'
import type { Store } from '../persistence'
import type * as Fs from 'fs'
import type * as Fs from 'node:fs'
const execFileMock = vi.hoisted(() =>
vi.fn((...args: unknown[]) => {
+5 -5
View File
@@ -1,10 +1,10 @@
/* eslint-disable max-lines -- Why: external automation discovery, pagination,
* and lifecycle routing share provider/target validation and remote relay fallbacks. */
import { execFile } from 'child_process'
import { existsSync } from 'fs'
import { readFile } from 'fs/promises'
import { homedir } from 'os'
import { join } from 'path'
import { execFile } from 'node:child_process'
import { existsSync } from 'node:fs'
import { readFile } from 'node:fs/promises'
import { homedir } from 'node:os'
import { join } from 'node:path'
import type {
ExternalAutomationAction,
ExternalAutomationActionInput,
@@ -1,6 +1,6 @@
import { mkdtemp, mkdir, rm, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { dirname, join } from 'path'
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { dirname, join } from 'node:path'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
let hermesHome: string | null = null
+4 -4
View File
@@ -1,9 +1,9 @@
/* eslint-disable max-lines -- Why: Hermes run history has to reconcile
* markdown output files with SQLite session transcripts from separate stores. */
import { existsSync } from 'fs'
import { open, readdir, readFile, realpath, stat } from 'fs/promises'
import { homedir } from 'os'
import { isAbsolute, join, relative, resolve, sep } from 'path'
import { existsSync } from 'node:fs'
import { open, readdir, readFile, realpath, stat } from 'node:fs/promises'
import { homedir } from 'node:os'
import { isAbsolute, join, relative, resolve, sep } from 'node:path'
import Database from '../sqlite/sync-database'
const HERMES_HOME = process.env.HERMES_HOME?.trim() || join(homedir(), '.hermes')
@@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { mkdtempSync, rmSync } from 'fs'
import { join } from 'path'
import { tmpdir } from 'os'
import { mkdtempSync, rmSync } from 'node:fs'
import { join } from 'node:path'
import { tmpdir } from 'node:os'
import type { Repo } from '../../shared/types'
import { AutomationService } from './service'
+3 -3
View File
@@ -1,7 +1,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { mkdtempSync, rmSync } from 'fs'
import { join } from 'path'
import { tmpdir } from 'os'
import { mkdtempSync, rmSync } from 'node:fs'
import { join } from 'node:path'
import { tmpdir } from 'node:os'
import type { Repo } from '../../shared/types'
import { toRuntimeExecutionHostId } from '../../shared/execution-host'
import { AutomationService } from './service'
@@ -1,4 +1,4 @@
import { Buffer } from 'buffer'
import { Buffer } from 'node:buffer'
import type { AzureDevOpsRepoRef } from './repository-ref'
const REQUEST_TIMEOUT_MS = 5000
@@ -1,4 +1,4 @@
import { Buffer } from 'buffer'
import { Buffer } from 'node:buffer'
import type { CreateHostedReviewInput, CreateHostedReviewResult } from '../../shared/hosted-review'
import {
normalizeHostedReviewBaseRef,
+1 -1
View File
@@ -1,4 +1,4 @@
import { Buffer } from 'buffer'
import { Buffer } from 'node:buffer'
import type { CheckStatus } from '../../shared/types'
import {
deriveBitbucketBuildStatus,
+4 -4
View File
@@ -1,8 +1,8 @@
/* eslint-disable max-lines */
import { execFile, type ChildProcess } from 'child_process'
import { existsSync, accessSync, chmodSync, readFileSync, constants } from 'fs'
import { join } from 'path'
import { platform, arch } from 'os'
import { execFile, type ChildProcess } from 'node:child_process'
import { existsSync, accessSync, chmodSync, readFileSync, constants } from 'node:fs'
import { join } from 'node:path'
import { platform, arch } from 'node:os'
import { app, type WebContents } from 'electron'
import { CdpWsProxy } from './cdp-ws-proxy'
import { captureFullPageScreenshot } from './cdp-screenshot'
@@ -1,8 +1,8 @@
/* eslint-disable max-lines -- Why: integration test covering the full browser automation pipeline end-to-end. */
import { mkdtempSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { createConnection } from 'net'
import { mkdtempSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { createConnection } from 'node:net'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
// ── Electron mocks ──
+1 -1
View File
@@ -1,6 +1,6 @@
/* eslint-disable max-lines -- Why: this proxy owns HTTP discovery, websocket client lifecycle, and CDP debugger forwarding together. */
import { WebSocketServer, WebSocket } from 'ws'
import { createServer, type Server, type IncomingMessage, type ServerResponse } from 'http'
import { createServer, type Server, type IncomingMessage, type ServerResponse } from 'node:http'
import type { WebContents } from 'electron'
import { captureScreenshot } from './cdp-screenshot'
import { ANTI_DETECTION_SCRIPT } from './anti-detection'
@@ -1,4 +1,4 @@
import { randomUUID } from 'crypto'
import { randomUUID } from 'node:crypto'
import { BrowserWindow } from 'electron'
import { ORCA_BROWSER_PARTITION } from '../../shared/constants'
import { ORCA_BROWSER_GUEST_WEB_PREFERENCES } from '../../shared/browser-guest-web-preferences'
@@ -1,5 +1,5 @@
import { readFileSync } from 'fs'
import { resolve } from 'path'
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { describe, expect, it } from 'vitest'
const OFFSCREEN_BACKEND_SOURCE = resolve(__dirname, 'offscreen-browser-backend.ts')
@@ -1,8 +1,8 @@
import { describe, expect, it, vi } from 'vitest'
import type { Dirent } from 'node:fs'
import type * as FsPromises from 'fs/promises'
import type * as NodeOs from 'os'
import { join } from 'path'
import type * as FsPromises from 'node:fs/promises'
import type * as NodeOs from 'node:os'
import { join } from 'node:path'
const { homedirMock, readdirMock } = vi.hoisted(() => ({
homedirMock: vi.fn<() => string>(),
+5 -5
View File
@@ -1,9 +1,9 @@
import { mkdtemp, mkdir, rm, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { join } from 'path'
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it, vi } from 'vitest'
import type * as Os from 'os'
import type * as FsPromises from 'fs/promises'
import type * as Os from 'node:os'
import type * as FsPromises from 'node:fs/promises'
const tempRoots: string[] = []
+3 -3
View File
@@ -5,9 +5,9 @@ import {
parseClaudeUsageFile,
parseClaudeUsageRecord
} from './scanner'
import { mkdtemp, rm, writeFile } from 'fs/promises'
import { join } from 'path'
import { tmpdir } from 'os'
import { mkdtemp, rm, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
import { tmpdir } from 'node:os'
describe('parseClaudeUsageRecord', () => {
it('extracts token usage from assistant transcript lines', () => {
+5 -5
View File
@@ -1,9 +1,9 @@
/* eslint-disable max-lines -- Why: transcript discovery, parsing, attribution, and aggregation share one data shape pipeline. Keeping them co-located makes it easier to audit correctness when Claude usage numbers look surprising. */
import { homedir } from 'os'
import { join, basename } from 'path'
import { realpath, readdir, stat } from 'fs/promises'
import { createReadStream } from 'fs'
import { createInterface } from 'readline'
import { homedir } from 'node:os'
import { join, basename } from 'node:path'
import { realpath, readdir, stat } from 'node:fs/promises'
import { createReadStream } from 'node:fs'
import { createInterface } from 'node:readline'
import type { Repo } from '../../shared/types'
import type {
ClaudeUsageAttributedTurn,
+2 -2
View File
@@ -1,7 +1,7 @@
/* eslint-disable max-lines -- Why: this store is the single main-process owner for Claude usage persistence, scan gating, and query semantics. Keeping those policy decisions together avoids split-brain range/scope logic across multiple files. */
import { app } from 'electron'
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs'
import { dirname, join } from 'path'
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import type {
ClaudeUsageBreakdownKind,
ClaudeUsageBreakdownRow,
+3 -3
View File
@@ -3,9 +3,9 @@
// or the script body that lands on the remote box. Local install behavior
// is exercised through `installer-utils.test.ts` and the per-CLI status
// audit; this file covers ONLY the SFTP-backed path added in commit #8.
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { vi, describe, expect, it } from 'vitest'
vi.mock('electron', () => ({
+2 -2
View File
@@ -1,5 +1,5 @@
import { homedir } from 'os'
import { join } from 'path'
import { homedir } from 'node:os'
import { join } from 'node:path'
import {
buildManagedCommandHook,
createManagedCommandMatcher,
+2 -2
View File
@@ -1,5 +1,5 @@
import { readFileSync } from 'fs'
import { join } from 'path'
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
import { describe, expect, it } from 'vitest'
describe('packaged Windows CLI launcher asset', () => {
@@ -1,7 +1,7 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import type { Dirent, Stats } from 'node:fs'
import type * as FsPromises from 'fs/promises'
import { join } from 'path'
import type * as FsPromises from 'node:fs/promises'
import { join } from 'node:path'
const { getLegacyCopiedCodexSessionBridgeScanPreferenceMock, readdirMock, statMock } = vi.hoisted(
() => ({
+3 -3
View File
@@ -1,9 +1,9 @@
/* eslint-disable max-lines -- Why: path discovery and legacy bridge scan preference cases need shared mocked homes to keep filesystem behavior realistic. */
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { linkSync, lstatSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs'
import { tmpdir } from 'os'
import { linkSync, lstatSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
import { tmpdir } from 'node:os'
import type * as NodeOs from 'node:os'
import { join } from 'path'
import { join } from 'node:path'
const { getPathMock, homedirMock } = vi.hoisted(() => ({
getPathMock: vi.fn<(name: string) => string>(),

Some files were not shown because too many files have changed in this diff Show More