Disallow and suppress unsafe assignment (#19736)

This commit is contained in:
Christian Gunderman
2026-02-20 22:28:55 +00:00
committed by GitHub
parent b746524a1b
commit 58d637f919
71 changed files with 149 additions and 22 deletions
@@ -145,6 +145,7 @@ class RecursiveFileSearch implements FileSearch {
if (pattern.includes('*') || !this.fzf) {
filteredCandidates = await filter(candidates, pattern, options.signal);
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
filteredCandidates = await this.fzf
.find(pattern)
.then((results: Array<FzfResultItem<string>>) =>
+4
View File
@@ -23,12 +23,16 @@ export const getPty = async (): Promise<PtyImplementation> => {
}
try {
const lydell = '@lydell/node-pty';
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const module = await import(lydell);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
return { module, name: 'lydell-node-pty' };
} catch (_e) {
try {
const nodePty = 'node-pty';
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const module = await import(nodePty);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
return { module, name: 'node-pty' };
} catch (_e2) {
return null;
+7
View File
@@ -166,10 +166,12 @@ export function parseGoogleApiError(error: unknown): GoogleApiError | null {
depth < maxDepth
) {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const parsedMessage = JSON.parse(
currentError.message.replace(/\u00A0/g, '').replace(/\n/g, ' '),
);
if (parsedMessage.error) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
currentError = parsedMessage.error;
depth++;
} else {
@@ -243,6 +245,7 @@ function fromGaxiosError(errorObj: object): ErrorShape | undefined {
if (typeof data === 'string') {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
data = JSON.parse(data);
} catch (_) {
// Not a JSON string, can't parse.
@@ -250,6 +253,7 @@ function fromGaxiosError(errorObj: object): ErrorShape | undefined {
}
if (Array.isArray(data) && data.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
data = data[0];
}
@@ -288,6 +292,7 @@ function fromApiError(errorObj: object): ErrorShape | undefined {
if (typeof data === 'string') {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
data = JSON.parse(data);
} catch (_) {
// Not a JSON string, can't parse.
@@ -297,6 +302,7 @@ function fromApiError(errorObj: object): ErrorShape | undefined {
const lastBrace = data.lastIndexOf('}');
if (firstBrace !== -1 && lastBrace !== -1 && lastBrace > firstBrace) {
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
data = JSON.parse(data.substring(firstBrace, lastBrace + 1));
} catch (__) {
// Still failed
@@ -307,6 +313,7 @@ function fromApiError(errorObj: object): ErrorShape | undefined {
}
if (Array.isArray(data) && data.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
data = data[0];
}
@@ -127,6 +127,7 @@ async function getGeminiMdFilePathsInternal(
result.value.global.forEach((p) => globalPaths.add(p));
result.value.project.forEach((p) => projectPaths.add(p));
} else {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const error = result.reason;
const message = error instanceof Error ? error.message : String(error);
logger.error(`Error discovering files in directory: ${message}`);
@@ -299,6 +300,7 @@ export async function readGeminiMdFiles(
} else {
// This case shouldn't happen since we catch all errors above,
// but handle it for completeness
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const error = result.reason;
const message = error instanceof Error ? error.message : String(error);
logger.error(`Unexpected error processing file: ${message}`);
@@ -37,6 +37,7 @@ export function safeJsonStringify(
function removeEmptyObjects(data: any): object {
const cleanedObject: { [key: string]: unknown } = {};
for (const k in data) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const v = data[k];
if (v !== null && v !== undefined && typeof v === 'boolean') {
cleanedObject[k] = v;
+5 -3
View File
@@ -12,9 +12,9 @@ import * as addFormats from 'ajv-formats';
import { debugLogger } from './debugLogger.js';
// Ajv's ESM/CJS interop: use 'any' for compatibility as recommended by Ajv docs
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion, @typescript-eslint/no-unsafe-assignment
const AjvClass = (AjvPkg as any).default || AjvPkg;
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion, @typescript-eslint/no-unsafe-assignment
const Ajv2020Class = (Ajv2020Pkg as any).default || Ajv2020Pkg;
const ajvOptions = {
@@ -29,12 +29,14 @@ const ajvOptions = {
};
// Draft-07 validator (default)
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const ajvDefault: Ajv = new AjvClass(ajvOptions);
// Draft-2020-12 validator for MCP servers using rmcp
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const ajv2020: Ajv = new Ajv2020Class(ajvOptions);
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion, @typescript-eslint/no-unsafe-assignment
const addFormatsFunc = (addFormats as any).default || addFormats;
addFormatsFunc(ajvDefault);
addFormatsFunc(ajv2020);
+1
View File
@@ -479,6 +479,7 @@ function parsePowerShellCommandDetails(
hasRedirection?: boolean;
} | null = null;
try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
parsed = JSON.parse(output);
} catch {
return { details: [], hasError: true };
+2
View File
@@ -88,6 +88,7 @@ export function createWorkingStdio() {
if (prop === 'write') {
return writeToStdout;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const value = Reflect.get(target, prop, receiver);
if (typeof value === 'function') {
return value.bind(target);
@@ -101,6 +102,7 @@ export function createWorkingStdio() {
if (prop === 'write') {
return writeToStderr;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const value = Reflect.get(target, prop, receiver);
if (typeof value === 'function') {
return value.bind(target);
@@ -30,6 +30,7 @@ export class UserAccountManager {
return defaultState;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const parsed = JSON.parse(content);
// Inlined validation logic
@@ -50,7 +51,9 @@ export class UserAccountManager {
}
return {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
active: parsed.active ?? null,
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
old: parsed.old ?? [],
};
}