refactor: P3 polish — Interactor type safety, error response builder, ESLint#316
refactor: P3 polish — Interactor type safety, error response builder, ESLint#316
Conversation
- Export Interactor type and add `satisfies Interactor` to both return objects in getInteractor() for compile-time completeness checking - Create errorResponse/successResponse builder in handlers/response.ts and adopt it in 5 representative handler files (find, record-trace, interaction-press, session-deploy, snapshot-wait) - Add ESLint with typescript-eslint, fix unused imports and trivial lint issues, configure rules to warn for stylistic patterns Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…S exports, standardize dispatch Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ode, unused export Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
|
||
| function shellQuote(value: string): string { | ||
| return `'${value.replace(/'/g, `'\"'\"'`)}'`; | ||
| return `'${value.replace(/'/g, `'"'"'`)}'`; |
Check warning
Code scanning / CodeQL
Unsafe shell command constructed from library input Medium
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 6 hours ago
General approach: Avoid manually building a shell command string with ad-hoc quoting. Instead, use a standard library (shell-quote) to escape arbitrary strings before embedding them in a shell command. This keeps the /bin/sh -c pattern (needed for nohup ... & echo $!) but ensures all untrusted inputs (metro.command, its args, and logPath) are correctly escaped for the shell.
Concrete fix in this file:
- Add an import for
shell-quoteinsrc/client-metro.ts. - Replace the custom
shellQuotehelper with a thin wrapper aroundshell-quote’squotefunction, so it still returns a string suitable for inclusion in a shell command. - Leave the existing use sites in
startMetroProcessas-is (shellQuote(metro.command),metro.installArgs.map(shellQuote), andshellQuote(logPath)), now backed by the library implementation.
This preserves all existing behavior (still using /bin/sh -c with nohup ... & echo $!, same function signatures, same return types) while eliminating the home-grown quoting logic that CodeQL flags. Changes are limited to src/client-metro.ts: one new import at the top, and a new implementation of shellQuote near lines 243–245.
| @@ -3,6 +3,7 @@ | ||
| import { AppError } from './utils/errors.ts'; | ||
| import { runCmdSync } from './utils/exec.ts'; | ||
| import { resolveUserPath } from './utils/path-resolution.ts'; | ||
| import shellQuoteLib from 'shell-quote'; | ||
|
|
||
| export type MetroPrepareKind = 'auto' | 'react-native' | 'expo'; | ||
| type ResolvedMetroKind = Exclude<MetroPrepareKind, 'auto'>; | ||
| @@ -241,7 +242,8 @@ | ||
| } | ||
|
|
||
| function shellQuote(value: string): string { | ||
| return `'${value.replace(/'/g, `'"'"'`)}'`; | ||
| // Use a well-tested library to safely escape values for the shell. | ||
| return shellQuoteLib.quote([value]); | ||
| } | ||
|
|
||
| function installDependenciesIfNeeded( |
| @@ -68,7 +68,8 @@ | ||
| "android" | ||
| ], | ||
| "dependencies": { | ||
| "pngjs": "^7.0.0" | ||
| "pngjs": "^7.0.0", | ||
| "shell-quote": "^1.8.3" | ||
| }, | ||
| "devDependencies": { | ||
| "@microsoft/api-extractor": "^7.52.10", |
| Package | Version | Security advisories |
| shell-quote (npm) | 1.8.3 | None |
Summary
This PR is a P3 polish/refactor pass against
main, with three concrete outcomes.oxlint+oxfmt) instead of introducing a heavier ESLint + Prettier stack.noUnusedLocals,noUnusedParameters) and enablesisolatedModulesso type-checking better matches the actual build pipeline.runner-contract.tsseam forRunnerCommandand runner connect/error helpers.Additional cleanup included in the same scope:
@rslib/coreso the compiler and declaration build path stay internally consistent.package-lock.jsonaddition so the repo stays on a single package manager (pnpm).Why this is better than the base branch:
mainhad no repo-level lint/format enforcement here; this adds one, but does it with the smaller/faster OXC toolchain rather than adding parallel ESLint + Prettier maintenance.runner-transport.tsno longer imports back fromrunner-client.ts; both now depend on a small leaf contract module.Validation
pnpm formatpnpm lintpnpm typecheckpnpm buildpnpm test:unitpnpm test:smoke