mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-04 15:34:39 +00:00
* fix(app): add hosts without leaving the current screen A retained Settings route replayed its addHost query after appearance remounts. Own the connection flow outside screen lifetimes and let each consumer choose its completion navigation. * fix(app): release the project dialog before adding a host * fix(app): size the QR scanner viewport on wide layouts * test(app): align creation and desktop setup with in-place host flow
641 lines
32 KiB
JSON
641 lines
32 KiB
JSON
{
|
|
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
|
"options": {
|
|
"typeAware": false
|
|
},
|
|
"ignorePatterns": [".dev/**"],
|
|
"plugins": ["react", "react-perf", "unicorn", "typescript", "oxc", "import", "promise"],
|
|
"jsPlugins": ["./scripts/oxlint/paseo-plugin.mjs"],
|
|
"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": [
|
|
// Exceptions name individual APIs in individual modules; new APIs still fail in these files.
|
|
// TODO entries are runtime debt, not startup exemptions. Do not add directory-wide exceptions.
|
|
{
|
|
"files": ["packages/server/src/**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}"],
|
|
"rules": {
|
|
"paseo/no-sync-io": [
|
|
"error",
|
|
{
|
|
"allow": {
|
|
// TODO: literal executableExists is a synchronous public capability; move its callers and Windows existence predicates to async together.
|
|
"executable-resolution/executable-resolution.ts": ["existsSync"],
|
|
// TODO: winget enumeration shares synchronous existence predicates with literal lookup; convert the executable-resolution boundary together.
|
|
"executable-resolution/windows.ts": ["readdirSync"],
|
|
// TODO: live file-change classification is a synchronous event mapper; move the probe to async event ingestion.
|
|
"server/agent/providers/claude/agent.ts": ["existsSync"],
|
|
// TODO: new-session construction still resolves its project directory synchronously; move preparation before construction.
|
|
"server/agent/providers/claude/project-dir.ts": ["realpathSync"],
|
|
// TODO: live subagent output is read by a synchronous event mapper; add bounded async loading at ingestion.
|
|
"server/agent/providers/claude/subagents/workflow-output.ts": [
|
|
"closeSync",
|
|
"openSync",
|
|
"readSync"
|
|
],
|
|
// TODO: diagnostics probes provider-owned auth/session storage; convert alongside provider discovery and readiness.
|
|
"server/agent/providers/omp/agent.ts": ["existsSync"],
|
|
// TODO: synchronous provider configuration discovery; move discovery into async launch preparation.
|
|
"server/agent/providers/omp/provider-config.ts": ["existsSync"],
|
|
// TODO: synchronous session-root selection is shared by descriptor builders; migrate callers with explicit readiness.
|
|
"server/agent/providers/omp/session-descriptor.ts": ["existsSync"],
|
|
// TODO: launch directory creation shares the server generation/start state machine; audit concurrent rotation before adding an await.
|
|
"server/agent/providers/opencode/server-manager.ts": ["mkdirSync"],
|
|
// TODO: launch preparation owns MCP config merge, extension generation and synchronous cleanup; migrate lifecycle and diagnostics together.
|
|
"server/agent/providers/pi/agent.ts": [
|
|
"existsSync",
|
|
"mkdtempSync",
|
|
"readFileSync",
|
|
"rmSync",
|
|
"writeFileSync"
|
|
],
|
|
// Provider child process: Pi loads this extension outside the daemon; it reads child-agent status there.
|
|
"server/agent/providers/pi/extensions/pi-subagents/index.ts": ["readFileSync"],
|
|
// Startup/shutdown only: remove stale Unix listening sockets before bind and during disposal.
|
|
"server/bootstrap.ts": ["existsSync", "unlinkSync"],
|
|
// Startup configuration resolution: detect the bundled app distribution before the daemon listens.
|
|
"server/config.ts": ["existsSync"],
|
|
// Startup identity: load or create the daemon keypair before accepting connections.
|
|
"server/daemon-keypair.ts": ["existsSync", "readFileSync"],
|
|
// Fatal exit diagnostics: synchronously flush the exit reason when the worker is about to terminate.
|
|
"server/daemon-worker.ts": ["appendFileSync", "mkdirSync"],
|
|
// Startup host identity: memoized scutil lookup is warmed before listening; later callers use the cache.
|
|
"server/host-name.ts": ["execFileSync"],
|
|
// TODO: relationship persistence is atomic with enrollment/revocation state transitions; serialize those transitions before async writes.
|
|
"server/hub/relationship-controller.ts": [
|
|
"existsSync",
|
|
"readFileSync",
|
|
"renameSync",
|
|
"rmSync"
|
|
],
|
|
// Local client bootstrap: reads the local credential and pid lock to select/authenticate a daemon connection.
|
|
"server/local-credential.ts": ["readFileSync"],
|
|
// Startup logger construction: create the log directory before opening the logging destination.
|
|
"server/logger.ts": ["mkdirSync"],
|
|
// TODO: runtime skill commands resolve their bundled source through a synchronous targets capability; migrate the capability and controller together.
|
|
"server/orchestration-skills/internal/paths.ts": ["existsSync"],
|
|
// Module initialization: the package version is resolved once and cached at import.
|
|
"server/package-version.ts": ["existsSync", "readFileSync"],
|
|
// Startup config and exported synchronous configuration API; runtime DaemonConfigStore uses the async load/save capabilities.
|
|
"server/persisted-config.ts": ["existsSync", "readFileSync"],
|
|
// Startup pid identity: read and memoize the Linux boot id for the daemon lock.
|
|
"server/pid-lock.ts": ["readFileSync"],
|
|
// Startup builtin loader construction: select the bundled plugin root before loading plugins.
|
|
"server/plugins/builtin/index.ts": ["existsSync"],
|
|
// Build child process: plugin graph traversal and esbuild preparation run in the isolated compiler process.
|
|
"server/plugins/compiler-build.ts": ["existsSync", "readFileSync", "realpathSync"],
|
|
// Build child process: select the esbuild binary for the isolated plugin compiler.
|
|
"server/plugins/compiler-esbuild.ts": ["existsSync"],
|
|
// Build child process: TypeScript resolution and source reads run in the isolated plugin compiler.
|
|
"server/plugins/compiler-imports.ts": ["readFileSync", "realpathSync"],
|
|
// TODO: plugin install/update/remove commits sources.json synchronously; preserve record/write ordering with an async mutation queue.
|
|
"server/plugins/managed-source.ts": ["existsSync", "readFileSync"],
|
|
// TODO: shared synchronous persistence supports startup identity plus Hub/plugin/push runtime writers; migrate those owners before removing these exports.
|
|
"server/private-files.ts": [
|
|
"chmodSync",
|
|
"mkdirSync",
|
|
"realpathSync",
|
|
"renameSync",
|
|
"rmSync",
|
|
"writeFileSync"
|
|
],
|
|
// TODO: constructor load plus runtime renew/revoke/prune use synchronous persistence; introduce ordered async mutations and readiness.
|
|
"server/push/token-store.ts": ["existsSync", "readFileSync"],
|
|
// Startup identity: load or create the server id before accepting connections.
|
|
"server/server-id.ts": ["existsSync", "readFileSync"],
|
|
// Listener lifecycle only: unlink the Unix socket before binding or after stopping the proxy.
|
|
"server/service-proxy.ts": ["existsSync", "unlinkSync"],
|
|
// TODO: self-update origin validation exposes synchronous package-root and realpath checks; migrate validation and its runtime interface together.
|
|
"server/session/daemon/install-origin.ts": ["existsSync", "readFileSync"],
|
|
// TODO: npm self-update inspection probes the reported install path; move the probe into bounded async installation inspection.
|
|
"server/session/daemon/npm-global-cli.ts": ["lstatSync"],
|
|
// Speech child process: model-file validation runs in the worker-backed local speech provider.
|
|
"server/speech/providers/local/sherpa/sherpa-offline-recognizer.ts": ["existsSync"],
|
|
// Speech child process: native addon discovery and patchelf run outside the daemon.
|
|
"server/speech/providers/local/sherpa/sherpa-onnx-node-loader.ts": [
|
|
"existsSync",
|
|
"spawnSync"
|
|
],
|
|
// Speech child process: model-file validation runs in the worker-backed local speech provider.
|
|
"server/speech/providers/local/sherpa/sherpa-tts.ts": ["existsSync"],
|
|
// TODO: static request selection and index injection need bounded async serving with response/error ownership; keep this as a separate request-path conversion.
|
|
"server/web-ui.ts": ["readFileSync", "statSync"],
|
|
// Startup registry hydration: check persisted workspace directories before the runtime reconciliation service starts.
|
|
"server/workspace-registry-bootstrap.ts": ["statSync"],
|
|
// Terminal child process: hook config installation/removal is owned by terminal creation and teardown in the worker.
|
|
"terminal/agent-hooks/agent-hook-installer.ts": [
|
|
"existsSync",
|
|
"readFileSync",
|
|
"rmSync"
|
|
],
|
|
// Terminal child process: launcher readiness and PTY record ownership run outside the daemon.
|
|
"terminal/terminal-worker-process.ts": [
|
|
"chmodSync",
|
|
"closeSync",
|
|
"existsSync",
|
|
"openSync",
|
|
"rmSync",
|
|
"writeSync"
|
|
],
|
|
// Worker startup only: choose and secure the local listening socket before accepting a controller.
|
|
"terminal/terminal-worker-socket-path.ts": ["lstatSync", "mkdirSync"],
|
|
// Startup only: build an independent worker installation before launching; Electron ASAR sources require plain fs reads.
|
|
"terminal/terminal-worker-runtime.ts": [
|
|
"chmodSync",
|
|
"existsSync",
|
|
"mkdirSync",
|
|
"readdirSync",
|
|
"readFileSync",
|
|
"renameSync",
|
|
"rmSync",
|
|
"statSync",
|
|
"writeFileSync"
|
|
],
|
|
// TODO: CLI shim lookup moved out of terminal.ts; migrate the executable-resolution boundary together.
|
|
"terminal/paseo-cli-path.ts": ["existsSync"],
|
|
// Node loader thread: TypeScript terminal-worker resolution runs in the loader, outside the daemon event loop.
|
|
"terminal/terminal-ts-loader.mjs": ["existsSync"],
|
|
// Terminal child process: executable preparation and shell integration run in the worker-backed terminal manager.
|
|
"terminal/terminal.ts": [
|
|
"accessSync",
|
|
"chmodSync",
|
|
"existsSync",
|
|
"mkdirSync",
|
|
"readFileSync",
|
|
"statSync"
|
|
],
|
|
// TODO: legacy realpath helpers still serve install-origin validation and other synchronous consumers; migrate remaining callers before removing them.
|
|
"utils/path.ts": ["realpathSync"]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"files": [
|
|
"packages/server/src/**/*.{test,spec,fixture}.{ts,tsx,mts,cts,js,jsx,mjs,cjs}",
|
|
"packages/server/src/**/test-utils/**",
|
|
"packages/server/src/server/daemon-e2e/**",
|
|
"packages/server/src/server/agent/providers/pi/extensions/*-test.ts"
|
|
],
|
|
"rules": { "paseo/no-sync-io": "off" }
|
|
},
|
|
{
|
|
"files": [
|
|
"plugins/*-provider/server/**/*.ts",
|
|
"packages/plugin/src/server/acp-internal/**/*.ts"
|
|
],
|
|
"rules": {
|
|
"no-restricted-imports": [
|
|
"error",
|
|
{
|
|
"paths": [
|
|
{
|
|
"name": "node:child_process",
|
|
"importNames": [
|
|
"spawn",
|
|
"exec",
|
|
"execFile",
|
|
"spawnSync",
|
|
"execSync",
|
|
"execFileSync"
|
|
],
|
|
"message": "Use the plugin server process helpers so Windows command scripts and argv are handled consistently."
|
|
},
|
|
{
|
|
"name": "child_process",
|
|
"importNames": [
|
|
"spawn",
|
|
"exec",
|
|
"execFile",
|
|
"spawnSync",
|
|
"execSync",
|
|
"execFileSync"
|
|
],
|
|
"message": "Use the plugin server process helpers so Windows command scripts and argv are handled consistently."
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"files": ["packages/app/src/**/*.{ts,tsx}"],
|
|
"rules": {
|
|
// React Native style arrays must read Unistyles proxies during render. Hoisting them to
|
|
// satisfy this allocation rule captures the temporary startup theme instead.
|
|
"react-perf/jsx-no-new-array-as-prop": "off",
|
|
"no-restricted-imports": [
|
|
"error",
|
|
{
|
|
"paths": [
|
|
{
|
|
"name": "react-native",
|
|
"importNames": ["TextInput"],
|
|
"message": "Use EditingTextInput from @/components/ui/text-input. Raw TextInput bypasses editing-surface authority and IME safety."
|
|
},
|
|
{
|
|
"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",
|
|
"importNames": ["TextInput"],
|
|
"message": "Use EditingTextInput from @/components/ui/text-input. Raw TextInput bypasses editing-surface authority and IME safety."
|
|
},
|
|
{
|
|
"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: 34 files total; the 28 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-settings/index.ts",
|
|
"packages/app/src/panels/terminal-panel.tsx",
|
|
"packages/app/src/projects/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",
|
|
"importNames": ["TextInput"],
|
|
"message": "Use EditingTextInput from @/components/ui/text-input. Raw TextInput bypasses editing-surface authority and IME safety."
|
|
},
|
|
{
|
|
"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/components/adaptive-modal-sheet.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/desktop/browser/pane/index.electron.tsx",
|
|
"packages/app/src/desktop/browser/pane/index.tsx",
|
|
"packages/app/src/desktop/browser/pane/index.web.tsx",
|
|
"packages/app/src/components/command-center.tsx",
|
|
"packages/app/src/components/compact-explorer-sidebar.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/headers/back-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/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": "react-native",
|
|
"importNames": ["TextInput"],
|
|
"message": "Use EditingTextInput from @/components/ui/text-input. Raw TextInput bypasses editing-surface authority and IME safety."
|
|
},
|
|
{
|
|
"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": [
|
|
"error",
|
|
{
|
|
"paths": [
|
|
{
|
|
"name": "react-native",
|
|
"importNames": ["TextInput"],
|
|
"message": "Use EditingTextInput from @/components/ui/text-input. Raw TextInput bypasses editing-surface authority and IME safety."
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"files": [
|
|
"packages/app/src/components/ui/text-input/**/*.{ts,tsx}",
|
|
"packages/app/src/agent-stream/scroll-keyboard-dismiss/use-scroll-keyboard-dismiss.ts"
|
|
],
|
|
"rules": {
|
|
"no-restricted-imports": "off"
|
|
}
|
|
},
|
|
{
|
|
"files": ["packages/app/src/**/*.{ts,tsx}"],
|
|
"rules": {
|
|
"paseo/no-raw-pressable": "error"
|
|
}
|
|
},
|
|
// Press feedback is owned by the primitives in components/ui. Raw pressable burn-down:
|
|
// 94 files. They may only leave this list.
|
|
{
|
|
"files": [
|
|
"packages/app/src/components/ui/**/*.{ts,tsx}",
|
|
"packages/app/src/**/*.{test,spec}.{ts,tsx}",
|
|
"packages/app/src/agent-profiles/settings/agent-profile-appearance-field.tsx",
|
|
"packages/app/src/agent-skills/selection-sheet.tsx",
|
|
"packages/app/src/agent-stream/chat-outline/rail.web.tsx",
|
|
"packages/app/src/agent-stream/view.tsx",
|
|
"packages/app/src/changelog/internal/changelog-sheet.tsx",
|
|
"packages/app/src/command-center/command-center.tsx",
|
|
"packages/app/src/components/adaptive-modal-sheet.tsx",
|
|
"packages/app/src/components/add-project-flow.tsx",
|
|
"packages/app/src/components/agent-list.tsx",
|
|
"packages/app/src/components/app-diagnostic-sheet.tsx",
|
|
"packages/app/src/components/attachment-lightbox.tsx",
|
|
"packages/app/src/components/attachment-pill.tsx",
|
|
"packages/app/src/components/combined-model-selector.tsx",
|
|
"packages/app/src/components/compact-explorer-sidebar.tsx",
|
|
"packages/app/src/components/context-window-meter.tsx",
|
|
"packages/app/src/components/desktop/window-controls.tsx",
|
|
"packages/app/src/components/dictation-controls.tsx",
|
|
"packages/app/src/components/download-toast.tsx",
|
|
"packages/app/src/components/file-explorer-pane.tsx",
|
|
"packages/app/src/components/headers/back-header.tsx",
|
|
"packages/app/src/components/highlighted-code-block.tsx",
|
|
"packages/app/src/components/hosts/host-filter.tsx",
|
|
"packages/app/src/components/hosts/host-picker.tsx",
|
|
"packages/app/src/components/import-session-sheet.tsx",
|
|
"packages/app/src/components/left-sidebar.tsx",
|
|
"packages/app/src/components/markdown/fence/mermaid/host.native.tsx",
|
|
"packages/app/src/components/markdown/fence/mermaid/host.web.tsx",
|
|
"packages/app/src/components/message.tsx",
|
|
"packages/app/src/components/model-browser.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/realtime-voice-overlay.tsx",
|
|
"packages/app/src/components/schedules/schedule-row.tsx",
|
|
"packages/app/src/components/settings/collapsible-row.tsx",
|
|
"packages/app/src/components/settings/headings/settings-info-tip.tsx",
|
|
"packages/app/src/components/sidebar-callout.tsx",
|
|
"packages/app/src/components/sidebar-resize-handle.tsx",
|
|
"packages/app/src/components/sidebar-workspace-list.tsx",
|
|
"packages/app/src/components/sidebar/sidebar-group-toggle-row.tsx",
|
|
"packages/app/src/components/sidebar/sidebar-header-row.tsx",
|
|
"packages/app/src/components/sidebar/sidebar-section-header.tsx",
|
|
"packages/app/src/components/sidebar/sidebar-status-list.tsx",
|
|
"packages/app/src/components/sidebar/workspace-meta-row/index.tsx",
|
|
"packages/app/src/components/terminal-copy-paste-actions.tsx",
|
|
"packages/app/src/components/terminal-emulator-native-grid.native.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/welcome-screen.tsx",
|
|
"packages/app/src/components/workspace-hover-card.tsx",
|
|
"packages/app/src/components/zoomable-viewport/toolbar.tsx",
|
|
"packages/app/src/composer/agent-controls/index.tsx",
|
|
"packages/app/src/composer/diff-stat-pill.tsx",
|
|
"packages/app/src/composer/dock/internal/background.native.tsx",
|
|
"packages/app/src/composer/draft/import-pill.tsx",
|
|
"packages/app/src/composer/index.tsx",
|
|
"packages/app/src/composer/tracks.tsx",
|
|
"packages/app/src/desktop/browser/pane/index.electron.tsx",
|
|
"packages/app/src/git/actions-split-button.tsx",
|
|
"packages/app/src/git/commits-section/commit-row.tsx",
|
|
"packages/app/src/git/commits-section/commits-section.tsx",
|
|
"packages/app/src/git/diff-pane.tsx",
|
|
"packages/app/src/git/forges/gitlab.view.tsx",
|
|
"packages/app/src/git/pull-request-panel/checks-section.tsx",
|
|
"packages/app/src/git/pull-request-panel/pane.tsx",
|
|
"packages/app/src/git/pull-request-panel/section-kit.tsx",
|
|
"packages/app/src/hosts/host-chooser.tsx",
|
|
"packages/app/src/mobile-panels/presentation.tsx",
|
|
"packages/app/src/panels/new-tab-panel.tsx",
|
|
"packages/app/src/panels/setup-panel.tsx",
|
|
"packages/app/src/plugins/buttons/view.tsx",
|
|
"packages/app/src/review/surface.tsx",
|
|
"packages/app/src/screens/open-project-screen.tsx",
|
|
"packages/app/src/screens/project-settings-screen.tsx",
|
|
"packages/app/src/screens/projects-screen.tsx",
|
|
"packages/app/src/screens/settings-screen.tsx",
|
|
"packages/app/src/screens/settings/host-appearance-section.tsx",
|
|
"packages/app/src/screens/settings/host-page.tsx",
|
|
"packages/app/src/screens/settings/providers-section.tsx",
|
|
"packages/app/src/screens/workspace/compact-workspace-header/tab-switcher.tsx",
|
|
"packages/app/src/screens/workspace/scripts/workspace-scripts-button.tsx",
|
|
"packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx",
|
|
"packages/app/src/screens/workspace/workspace-tab-presentation.tsx",
|
|
"packages/app/src/tool-calls/detail-level/overview/sheet.tsx",
|
|
"packages/app/src/usage/sidebar-item.tsx",
|
|
"packages/app/src/usage/window-bar.tsx",
|
|
"packages/app/src/workspace-labels/manager-modal.tsx",
|
|
"packages/app/src/workspace-labels/swatch.tsx",
|
|
"packages/app/src/workspace/open-in-editor/button.tsx"
|
|
],
|
|
"rules": {
|
|
"paseo/no-raw-pressable": "off"
|
|
}
|
|
},
|
|
{
|
|
"files": ["**/e2e/**/fixtures.ts"],
|
|
"rules": {
|
|
"no-empty-pattern": "off"
|
|
}
|
|
}
|
|
]
|
|
}
|