chore(compiler): Enable strict property access TS compiler flag. (#6255)

Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
Richie Foreman
2025-08-17 12:43:21 -04:00
committed by GitHub
parent ec1fa954d1
commit 2998f27f70
75 changed files with 495 additions and 483 deletions

View File

@@ -1089,7 +1089,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
alignItems={isNarrow ? 'flex-start' : 'center'}
>
<Box>
{process.env.GEMINI_SYSTEM_MD && (
{process.env['GEMINI_SYSTEM_MD'] && (
<Text color={Colors.AccentRed}>|_| </Text>
)}
{ctrlCPressedOnce ? (

View File

@@ -41,8 +41,8 @@ export function IdeIntegrationNudge({
const { displayName: ideName } = getIdeInfo(ide);
// Assume extension is already installed if the env variables are set.
const isExtensionPreInstalled =
!!process.env.GEMINI_CLI_IDE_SERVER_PORT &&
!!process.env.GEMINI_CLI_IDE_WORKSPACE_PATH;
!!process.env['GEMINI_CLI_IDE_SERVER_PORT'] &&
!!process.env['GEMINI_CLI_IDE_WORKSPACE_PATH'];
const OPTIONS: Array<RadioSelectItem<IdeIntegrationNudgeResult>> = [
{

View File

@@ -44,7 +44,7 @@ describe('aboutCommand', () => {
vi.spyOn(mockContext.services.config!, 'getModel').mockReturnValue(
'test-model',
);
process.env.GOOGLE_CLOUD_PROJECT = 'test-gcp-project';
process.env['GOOGLE_CLOUD_PROJECT'] = 'test-gcp-project';
Object.defineProperty(process, 'platform', {
value: 'test-os',
});
@@ -68,7 +68,7 @@ describe('aboutCommand', () => {
});
it('should call addItem with all version info', async () => {
process.env.SANDBOX = '';
process.env['SANDBOX'] = '';
if (!aboutCommand.action) {
throw new Error('The about command must have an action.');
}
@@ -91,7 +91,7 @@ describe('aboutCommand', () => {
});
it('should show the correct sandbox environment variable', async () => {
process.env.SANDBOX = 'gemini-sandbox';
process.env['SANDBOX'] = 'gemini-sandbox';
if (!aboutCommand.action) {
throw new Error('The about command must have an action.');
}
@@ -107,8 +107,8 @@ describe('aboutCommand', () => {
});
it('should show sandbox-exec profile when applicable', async () => {
process.env.SANDBOX = 'sandbox-exec';
process.env.SEATBELT_PROFILE = 'test-profile';
process.env['SANDBOX'] = 'sandbox-exec';
process.env['SEATBELT_PROFILE'] = 'test-profile';
if (!aboutCommand.action) {
throw new Error('The about command must have an action.');
}

View File

@@ -16,18 +16,18 @@ export const aboutCommand: SlashCommand = {
action: async (context) => {
const osVersion = process.platform;
let sandboxEnv = 'no sandbox';
if (process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec') {
sandboxEnv = process.env.SANDBOX;
} else if (process.env.SANDBOX === 'sandbox-exec') {
if (process.env['SANDBOX'] && process.env['SANDBOX'] !== 'sandbox-exec') {
sandboxEnv = process.env['SANDBOX'];
} else if (process.env['SANDBOX'] === 'sandbox-exec') {
sandboxEnv = `sandbox-exec (${
process.env.SEATBELT_PROFILE || 'unknown'
process.env['SEATBELT_PROFILE'] || 'unknown'
})`;
}
const modelVersion = context.services.config?.getModel() || 'Unknown';
const cliVersion = await getCliVersion();
const selectedAuthType =
context.services.settings.merged.selectedAuthType || '';
const gcpProject = process.env.GOOGLE_CLOUD_PROJECT || '';
const gcpProject = process.env['GOOGLE_CLOUD_PROJECT'] || '';
const ideClient =
context.services.config?.getIdeClient()?.getDetectedIdeDisplayName() ||
'';

View File

@@ -27,11 +27,11 @@ export const bugCommand: SlashCommand = {
const osVersion = `${process.platform} ${process.version}`;
let sandboxEnv = 'no sandbox';
if (process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec') {
sandboxEnv = process.env.SANDBOX.replace(/^gemini-(?:code-)?/, '');
} else if (process.env.SANDBOX === 'sandbox-exec') {
if (process.env['SANDBOX'] && process.env['SANDBOX'] !== 'sandbox-exec') {
sandboxEnv = process.env['SANDBOX'].replace(/^gemini-(?:code-)?/, '');
} else if (process.env['SANDBOX'] === 'sandbox-exec') {
sandboxEnv = `sandbox-exec (${
process.env.SEATBELT_PROFILE || 'unknown'
process.env['SEATBELT_PROFILE'] || 'unknown'
})`;
}
const modelVersion = config?.getModel() || 'Unknown';

View File

@@ -56,7 +56,7 @@ describe('docsCommand', () => {
}
// Simulate a sandbox environment
process.env.SANDBOX = 'gemini-sandbox';
vi.stubEnv('SANDBOX', 'gemini-sandbox');
const docsUrl = 'https://goo.gle/gemini-cli-docs';
await docsCommand.action(mockContext, '');
@@ -79,7 +79,7 @@ describe('docsCommand', () => {
}
// Simulate the specific 'sandbox-exec' environment
process.env.SANDBOX = 'sandbox-exec';
vi.stubEnv('SANDBOX', 'sandbox-exec');
const docsUrl = 'https://goo.gle/gemini-cli-docs';
await docsCommand.action(mockContext, '');

View File

@@ -20,7 +20,7 @@ export const docsCommand: SlashCommand = {
action: async (context: CommandContext): Promise<void> => {
const docsUrl = 'https://goo.gle/gemini-cli-docs';
if (process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec') {
if (process.env['SANDBOX'] && process.env['SANDBOX'] !== 'sandbox-exec') {
context.ui.addItem(
{
type: MessageType.INFO,

View File

@@ -73,7 +73,7 @@ describe('mcpCommand', () => {
vi.clearAllMocks();
// Set up default mock environment
delete process.env.SANDBOX;
vi.unstubAllEnvs();
// Default mock implementations
vi.mocked(getMCPServerStatus).mockReturnValue(MCPServerStatus.CONNECTED);

View File

@@ -17,8 +17,8 @@ describe('AuthDialog', () => {
beforeEach(() => {
originalEnv = { ...process.env };
process.env.GEMINI_API_KEY = '';
process.env.GEMINI_DEFAULT_AUTH_TYPE = '';
process.env['GEMINI_API_KEY'] = '';
process.env['GEMINI_DEFAULT_AUTH_TYPE'] = '';
vi.clearAllMocks();
});
@@ -27,7 +27,7 @@ describe('AuthDialog', () => {
});
it('should show an error if the initial auth type is invalid', () => {
process.env.GEMINI_API_KEY = '';
process.env['GEMINI_API_KEY'] = '';
const settings: LoadedSettings = new LoadedSettings(
{
@@ -62,7 +62,7 @@ describe('AuthDialog', () => {
describe('GEMINI_API_KEY environment variable', () => {
it('should detect GEMINI_API_KEY environment variable', () => {
process.env.GEMINI_API_KEY = 'foobar';
process.env['GEMINI_API_KEY'] = 'foobar';
const settings: LoadedSettings = new LoadedSettings(
{
@@ -94,8 +94,8 @@ describe('AuthDialog', () => {
});
it('should not show the GEMINI_API_KEY message if GEMINI_DEFAULT_AUTH_TYPE is set to something else', () => {
process.env.GEMINI_API_KEY = 'foobar';
process.env.GEMINI_DEFAULT_AUTH_TYPE = AuthType.LOGIN_WITH_GOOGLE;
process.env['GEMINI_API_KEY'] = 'foobar';
process.env['GEMINI_DEFAULT_AUTH_TYPE'] = AuthType.LOGIN_WITH_GOOGLE;
const settings: LoadedSettings = new LoadedSettings(
{
@@ -127,8 +127,8 @@ describe('AuthDialog', () => {
});
it('should show the GEMINI_API_KEY message if GEMINI_DEFAULT_AUTH_TYPE is set to use api key', () => {
process.env.GEMINI_API_KEY = 'foobar';
process.env.GEMINI_DEFAULT_AUTH_TYPE = AuthType.USE_GEMINI;
process.env['GEMINI_API_KEY'] = 'foobar';
process.env['GEMINI_DEFAULT_AUTH_TYPE'] = AuthType.USE_GEMINI;
const settings: LoadedSettings = new LoadedSettings(
{
@@ -162,7 +162,7 @@ describe('AuthDialog', () => {
describe('GEMINI_DEFAULT_AUTH_TYPE environment variable', () => {
it('should select the auth type specified by GEMINI_DEFAULT_AUTH_TYPE', () => {
process.env.GEMINI_DEFAULT_AUTH_TYPE = AuthType.LOGIN_WITH_GOOGLE;
process.env['GEMINI_DEFAULT_AUTH_TYPE'] = AuthType.LOGIN_WITH_GOOGLE;
const settings: LoadedSettings = new LoadedSettings(
{
@@ -222,7 +222,7 @@ describe('AuthDialog', () => {
});
it('should show an error and fall back to default if GEMINI_DEFAULT_AUTH_TYPE is invalid', () => {
process.env.GEMINI_DEFAULT_AUTH_TYPE = 'invalid-auth-type';
process.env['GEMINI_DEFAULT_AUTH_TYPE'] = 'invalid-auth-type';
const settings: LoadedSettings = new LoadedSettings(
{

View File

@@ -42,18 +42,18 @@ export function AuthDialog({
}
const defaultAuthType = parseDefaultAuthType(
process.env.GEMINI_DEFAULT_AUTH_TYPE,
process.env['GEMINI_DEFAULT_AUTH_TYPE'],
);
if (process.env.GEMINI_DEFAULT_AUTH_TYPE && defaultAuthType === null) {
if (process.env['GEMINI_DEFAULT_AUTH_TYPE'] && defaultAuthType === null) {
return (
`Invalid value for GEMINI_DEFAULT_AUTH_TYPE: "${process.env.GEMINI_DEFAULT_AUTH_TYPE}". ` +
`Invalid value for GEMINI_DEFAULT_AUTH_TYPE: "${process.env['GEMINI_DEFAULT_AUTH_TYPE']}". ` +
`Valid values are: ${Object.values(AuthType).join(', ')}.`
);
}
if (
process.env.GEMINI_API_KEY &&
process.env['GEMINI_API_KEY'] &&
(!defaultAuthType || defaultAuthType === AuthType.USE_GEMINI)
) {
return 'Existing API key detected (GEMINI_API_KEY). Select "Gemini API Key" option to use it.';
@@ -65,7 +65,7 @@ export function AuthDialog({
label: 'Login with Google',
value: AuthType.LOGIN_WITH_GOOGLE,
},
...(process.env.CLOUD_SHELL === 'true'
...(process.env['CLOUD_SHELL'] === 'true'
? [
{
label: 'Use Cloud Shell user credentials',
@@ -86,13 +86,13 @@ export function AuthDialog({
}
const defaultAuthType = parseDefaultAuthType(
process.env.GEMINI_DEFAULT_AUTH_TYPE,
process.env['GEMINI_DEFAULT_AUTH_TYPE'],
);
if (defaultAuthType) {
return item.value === defaultAuthType;
}
if (process.env.GEMINI_API_KEY) {
if (process.env['GEMINI_API_KEY']) {
return item.value === AuthType.USE_GEMINI;
}

View File

@@ -103,15 +103,16 @@ export const Footer: React.FC<FooterProps> = ({
>
{isTrustedFolder === false ? (
<Text color={theme.status.warning}>untrusted</Text>
) : process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec' ? (
) : process.env['SANDBOX'] &&
process.env['SANDBOX'] !== 'sandbox-exec' ? (
<Text color="green">
{process.env.SANDBOX.replace(/^gemini-(?:cli-)?/, '')}
{process.env['SANDBOX'].replace(/^gemini-(?:cli-)?/, '')}
</Text>
) : process.env.SANDBOX === 'sandbox-exec' ? (
) : process.env['SANDBOX'] === 'sandbox-exec' ? (
<Text color={theme.status.warning}>
macOS Seatbelt{' '}
<Text color={theme.text.secondary}>
({process.env.SEATBELT_PROFILE})
({process.env['SEATBELT_PROFILE']})
</Text>
</Text>
) : (

View File

@@ -321,7 +321,7 @@ function visitBoxRow(element: React.ReactNode): Row {
const segment: StyledText = { text, props: parentProps ?? {} };
// Check the 'wrap' property from the merged props to decide the segment type.
if (parentProps === undefined || parentProps.wrap === 'wrap') {
if (parentProps === undefined || parentProps['wrap'] === 'wrap') {
hasSeenWrapped = true;
row.segments.push(segment);
} else {

View File

@@ -362,20 +362,20 @@ export async function handleAtCommand({
// Inform user about ignored paths
const totalIgnored =
ignoredByReason.git.length +
ignoredByReason.gemini.length +
ignoredByReason.both.length;
ignoredByReason['git'].length +
ignoredByReason['gemini'].length +
ignoredByReason['both'].length;
if (totalIgnored > 0) {
const messages = [];
if (ignoredByReason.git.length) {
messages.push(`Git-ignored: ${ignoredByReason.git.join(', ')}`);
if (ignoredByReason['git'].length) {
messages.push(`Git-ignored: ${ignoredByReason['git'].join(', ')}`);
}
if (ignoredByReason.gemini.length) {
messages.push(`Gemini-ignored: ${ignoredByReason.gemini.join(', ')}`);
if (ignoredByReason['gemini'].length) {
messages.push(`Gemini-ignored: ${ignoredByReason['gemini'].join(', ')}`);
}
if (ignoredByReason.both.length) {
messages.push(`Ignored by both: ${ignoredByReason.both.join(', ')}`);
if (ignoredByReason['both'].length) {
messages.push(`Ignored by both: ${ignoredByReason['both'].join(', ')}`);
}
const message = `Ignored ${totalIgnored} files:\n${messages.join('\n')}`;

View File

@@ -116,7 +116,7 @@ describe('useKeypress', () => {
});
originalNodeVersion = process.versions.node;
delete process.env['PASTE_WORKAROUND'];
vi.unstubAllEnvs();
});
afterEach(() => {
@@ -197,7 +197,7 @@ describe('useKeypress', () => {
description: 'Workaround Env Var',
setup: () => {
setNodeVersion('20.0.0');
process.env['PASTE_WORKAROUND'] = 'true';
vi.stubEnv('PASTE_WORKAROUND', 'true');
},
isLegacy: true,
},

View File

@@ -39,7 +39,7 @@ export const useThemeCommand = (
}, [loadedSettings.merged.theme, setThemeError]);
const openThemeDialog = useCallback(() => {
if (process.env.NO_COLOR) {
if (process.env['NO_COLOR']) {
addItem(
{
type: MessageType.INFO,

View File

@@ -124,18 +124,18 @@ describe('Color Utils', () => {
describe('CSS_NAME_TO_HEX_MAP', () => {
it('should contain expected CSS color mappings', () => {
expect(CSS_NAME_TO_HEX_MAP.darkkhaki).toBe('#bdb76b');
expect(CSS_NAME_TO_HEX_MAP.coral).toBe('#ff7f50');
expect(CSS_NAME_TO_HEX_MAP.teal).toBe('#008080');
expect(CSS_NAME_TO_HEX_MAP.tomato).toBe('#ff6347');
expect(CSS_NAME_TO_HEX_MAP.turquoise).toBe('#40e0d0');
expect(CSS_NAME_TO_HEX_MAP['darkkhaki']).toBe('#bdb76b');
expect(CSS_NAME_TO_HEX_MAP['coral']).toBe('#ff7f50');
expect(CSS_NAME_TO_HEX_MAP['teal']).toBe('#008080');
expect(CSS_NAME_TO_HEX_MAP['tomato']).toBe('#ff6347');
expect(CSS_NAME_TO_HEX_MAP['turquoise']).toBe('#40e0d0');
});
it('should not contain Ink-supported color names', () => {
expect(CSS_NAME_TO_HEX_MAP.black).toBeUndefined();
expect(CSS_NAME_TO_HEX_MAP.red).toBeUndefined();
expect(CSS_NAME_TO_HEX_MAP.green).toBeUndefined();
expect(CSS_NAME_TO_HEX_MAP.blue).toBeUndefined();
expect(CSS_NAME_TO_HEX_MAP['black']).toBeUndefined();
expect(CSS_NAME_TO_HEX_MAP['red']).toBeUndefined();
expect(CSS_NAME_TO_HEX_MAP['green']).toBeUndefined();
expect(CSS_NAME_TO_HEX_MAP['blue']).toBeUndefined();
});
});

View File

@@ -5,8 +5,8 @@
*/
// Patch: Unset NO_COLOR at the very top before any imports
if (process.env.NO_COLOR !== undefined) {
delete process.env.NO_COLOR;
if (process.env['NO_COLOR'] !== undefined) {
delete process.env['NO_COLOR'];
}
import { describe, it, expect, beforeEach } from 'vitest';
@@ -87,13 +87,13 @@ describe('ThemeManager', () => {
});
it('should return NoColorTheme if NO_COLOR is set', () => {
const original = process.env.NO_COLOR;
process.env.NO_COLOR = '1';
const original = process.env['NO_COLOR'];
process.env['NO_COLOR'] = '1';
expect(themeManager.getActiveTheme().name).toBe('NoColor');
if (original === undefined) {
delete process.env.NO_COLOR;
delete process.env['NO_COLOR'];
} else {
process.env.NO_COLOR = original;
process.env['NO_COLOR'] = original;
}
});
});

View File

@@ -125,7 +125,7 @@ class ThemeManager {
* @returns The active theme.
*/
getActiveTheme(): Theme {
if (process.env.NO_COLOR) {
if (process.env['NO_COLOR']) {
return NoColorTheme;
}
// Ensure the active theme is always valid (fall back to default if not)

View File

@@ -38,7 +38,7 @@ function renderHastNode(
// Handle Element Nodes: Determine color and pass it down, don't wrap
if (node.type === 'element') {
const nodeClasses: string[] =
(node.properties?.className as string[]) || [];
(node.properties?.['className'] as string[]) || [];
let elementColor: string | undefined = undefined;
// Find color defined specifically for this element's class

View File

@@ -52,22 +52,24 @@ type SupportedTerminal = 'vscode' | 'cursor' | 'windsurf';
// Terminal detection
async function detectTerminal(): Promise<SupportedTerminal | null> {
const termProgram = process.env.TERM_PROGRAM;
const termProgram = process.env['TERM_PROGRAM'];
// Check VS Code and its forks - check forks first to avoid false positives
// Check for Cursor-specific indicators
if (
process.env.CURSOR_TRACE_ID ||
process.env.VSCODE_GIT_ASKPASS_MAIN?.toLowerCase().includes('cursor')
process.env['CURSOR_TRACE_ID'] ||
process.env['VSCODE_GIT_ASKPASS_MAIN']?.toLowerCase().includes('cursor')
) {
return 'cursor';
}
// Check for Windsurf-specific indicators
if (process.env.VSCODE_GIT_ASKPASS_MAIN?.toLowerCase().includes('windsurf')) {
if (
process.env['VSCODE_GIT_ASKPASS_MAIN']?.toLowerCase().includes('windsurf')
) {
return 'windsurf';
}
// Check VS Code last since forks may also set VSCODE env vars
if (termProgram === 'vscode' || process.env.VSCODE_GIT_IPC_HANDLE) {
if (termProgram === 'vscode' || process.env['VSCODE_GIT_IPC_HANDLE']) {
return 'vscode';
}
@@ -118,10 +120,10 @@ function getVSCodeStyleConfigDir(appName: string): string | null {
'User',
);
} else if (platform === 'win32') {
if (!process.env.APPDATA) {
if (!process.env['APPDATA']) {
return null;
}
return path.join(process.env.APPDATA, appName, 'User');
return path.join(process.env['APPDATA'], appName, 'User');
} else {
return path.join(os.homedir(), '.config', appName, 'User');
}

View File

@@ -22,7 +22,7 @@ describe('checkForUpdates', () => {
vi.useFakeTimers();
vi.resetAllMocks();
// Clear DEV environment variable before each test
delete process.env.DEV;
delete process.env['DEV'];
});
afterEach(() => {
@@ -31,7 +31,7 @@ describe('checkForUpdates', () => {
});
it('should return null when running from source (DEV=true)', async () => {
process.env.DEV = 'true';
process.env['DEV'] = 'true';
getPackageJson.mockResolvedValue({
name: 'test-package',
version: '1.0.0',

View File

@@ -41,7 +41,7 @@ function getBestAvailableUpdate(
export async function checkForUpdates(): Promise<UpdateObject | null> {
try {
// Skip update check when running from source (development mode)
if (process.env.DEV === 'true') {
if (process.env['DEV'] === 'true') {
return null;
}
const packageJson = await getPackageJson();