## Batch D Complete (#1313)

Successfully fixed all low-priority `any` types and catch blocks across 7 files:

### Changes Made:

**1. [lib/types.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/3da6-batch-d-fix-low/frontend/src/lib/types.ts)**
- Added imports: `NormalizedEntry`, `ExecutionProcessStatus`
- `entry: any` → `entry: NormalizedEntry`
- `process: any` → `process: ExecutionProcess`
- `processStatus: string` → `processStatus: ExecutionProcessStatus`

**2. [lib/modals.ts](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/3da6-batch-d-fix-low/frontend/src/lib/modals.ts)**
- Removed `any[]` and `component as any`
- Properly typed function arguments with `ShowArgs<P>`
- Used `React.FC<ComponentProps<P>>` for NiceModal compatibility

**3. [EditBranchNameDialog.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/3da6-batch-d-fix-low/frontend/src/components/dialogs/tasks/EditBranchNameDialog.tsx)**
- `catch (err: any)` → `catch (err: unknown)`
- Used `getErrorMessage(err)` helper

**4. [TagEditDialog.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/3da6-batch-d-fix-low/frontend/src/components/dialogs/tasks/TagEditDialog.tsx)**
- `catch (err: any)` → `catch (err: unknown)`
- Used `getErrorMessage(err)` helper

**5. [GhCliSetupDialog.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/3da6-batch-d-fix-low/frontend/src/components/dialogs/auth/GhCliSetupDialog.tsx)**
- `catch (err: any)` → `catch (err: unknown)`
- Added safe type narrowing with `isGhCliSetupError` guard
- Used `getErrorMessage(err)` helper

**6. [ImageUploadSection.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/3da6-batch-d-fix-low/frontend/src/components/ui/ImageUploadSection.tsx)**
- `catch (error: any)` → `catch (error: unknown)`
- Used `instanceof Error` check

**7. [McpSettings.tsx](file:///private/var/folders/m1/9q_ct1913z10v6wbnv54j25r0000gn/T/vibe-kanban/worktrees/3da6-batch-d-fix-low/frontend/src/pages/settings/McpSettings.tsx)**
- `catch (err: any)` → `catch (err: unknown)`
- `Record<string, any>` → `Record<string, unknown>` for preconfigured/meta/servers
- Added safe narrowing for meta access

All type checks pass ✓
All formatting complete ✓
This commit is contained in:
Louis Knight-Webb
2025-11-17 22:54:11 +00:00
committed by GitHub
parent 41376eba94
commit b35708e7b9
7 changed files with 60 additions and 29 deletions

View File

@@ -7,7 +7,7 @@ import {
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import { defineModal } from '@/lib/modals';
import { defineModal, getErrorMessage } from '@/lib/modals';
import { attemptsApi } from '@/lib/api';
import type { GhCliSetupError } from 'shared/types';
import { useRef, useState } from 'react';
@@ -143,13 +143,25 @@ const GhCliSetupDialogImpl = NiceModal.create<GhCliSetupDialogProps>(
hasResolvedRef.current = true;
modal.resolve(null);
modal.hide();
} catch (err: any) {
} catch (err: unknown) {
const rawMessage =
typeof err?.message === 'string'
? err.message
: t('settings:integrations.github.cliSetup.errors.setupFailed');
getErrorMessage(err) ||
t('settings:integrations.github.cliSetup.errors.setupFailed');
const maybeErrorData =
typeof err === 'object' && err !== null && 'error_data' in err
? (err as { error_data?: unknown }).error_data
: undefined;
const isGhCliSetupError = (x: unknown): x is GhCliSetupError =>
x === 'BREW_MISSING' ||
x === 'SETUP_HELPER_NOT_SUPPORTED' ||
(typeof x === 'object' && x !== null && 'OTHER' in x);
const errorData = isGhCliSetupError(maybeErrorData)
? maybeErrorData
: undefined;
const errorData = err?.error_data as GhCliSetupError | undefined;
const resolvedError: GhCliSetupError = errorData ?? {
OTHER: { message: rawMessage },
};

View File

@@ -11,7 +11,7 @@ import {
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import { defineModal } from '@/lib/modals';
import { defineModal, getErrorMessage } from '@/lib/modals';
import { useRenameBranch } from '@/hooks/useRenameBranch';
export interface EditBranchNameDialogProps {
@@ -40,8 +40,8 @@ const EditBranchNameDialogImpl = NiceModal.create<EditBranchNameDialogProps>(
} as EditBranchNameDialogResult);
modal.hide();
},
(err: any) => {
setError(err?.message || 'Failed to rename branch');
(err: unknown) => {
setError(getErrorMessage(err) || 'Failed to rename branch');
}
);

View File

@@ -16,7 +16,7 @@ import { Loader2 } from 'lucide-react';
import { tagsApi } from '@/lib/api';
import type { Tag, CreateTag, UpdateTag } from 'shared/types';
import NiceModal, { useModal } from '@ebay/nice-modal-react';
import { defineModal } from '@/lib/modals';
import { defineModal, getErrorMessage } from '@/lib/modals';
export interface TagEditDialogProps {
tag?: Tag | null; // null for create mode
@@ -79,9 +79,10 @@ const TagEditDialogImpl = NiceModal.create<TagEditDialogProps>(({ tag }) => {
modal.resolve('saved' as TagEditResult);
modal.hide();
} catch (err: any) {
} catch (err: unknown) {
setError(
err.message || t('settings.general.tags.dialog.errors.saveFailed')
getErrorMessage(err) ||
t('settings.general.tags.dialog.errors.saveFailed')
);
} finally {
setSaving(false);

View File

@@ -151,10 +151,12 @@ export const ImageUploadSection = forwardRef<
}
setErrorMessage(null);
} catch (error: any) {
} catch (error: unknown) {
console.error('Failed to upload image:', error);
const message =
error.message || 'Failed to upload image. Please try again.';
error instanceof Error
? error.message
: 'Failed to upload image. Please try again.';
setErrorMessage(message);
} finally {
setUploadingFiles((prev) => {

View File

@@ -23,10 +23,13 @@ export function defineModal<P, R>(
component: React.ComponentType<ComponentProps<P> & NiceModalHocProps>
): Modalized<P, R> {
const c = component as unknown as Modalized<P, R>;
c.show = ((...args: any[]) =>
NiceModal.show(component as any, args[0])) as Modalized<P, R>['show'];
c.hide = () => NiceModal.hide(component as any);
c.remove = () => NiceModal.remove(component as any);
c.show = ((...args: ShowArgs<P>) =>
NiceModal.show(
component as React.FC<ComponentProps<P>>,
args[0] as ComponentProps<P>
) as Promise<R>) as Modalized<P, R>['show'];
c.hide = () => NiceModal.hide(component as React.FC<ComponentProps<P>>);
c.remove = () => NiceModal.remove(component as React.FC<ComponentProps<P>>);
return c;
}

View File

@@ -1,4 +1,8 @@
import { ExecutionProcess } from 'shared/types';
import {
ExecutionProcess,
NormalizedEntry,
ExecutionProcessStatus,
} from 'shared/types';
export type AttemptData = {
processes: ExecutionProcess[];
@@ -6,12 +10,12 @@ export type AttemptData = {
};
export interface ConversationEntryDisplayType {
entry: any;
entry: NormalizedEntry;
processId: string;
processPrompt?: string;
processStatus: string;
processStatus: ExecutionProcessStatus;
processIsRunning: boolean;
process: any;
process: ExecutionProcess;
isFirstInProcess: boolean;
processIndex: number;
entryIndex: number;

View File

@@ -91,8 +91,11 @@ export function McpSettings() {
const configJson = JSON.stringify(fullConfig, null, 2);
setMcpServers(configJson);
setMcpConfigPath(result.config_path);
} catch (err: any) {
if (err?.message && err.message.includes('does not support MCP')) {
} catch (err: unknown) {
if (
err instanceof Error &&
err.message.includes('does not support MCP')
) {
setMcpError(err.message);
} else {
console.error('Error loading MCP servers:', err);
@@ -210,14 +213,20 @@ export function McpSettings() {
}
};
const preconfigured = (mcpConfig?.preconfigured ?? {}) as Record<string, any>;
const meta = (preconfigured.meta ?? {}) as Record<
const preconfiguredObj = (mcpConfig?.preconfigured ?? {}) as Record<
string,
unknown
>;
const meta =
typeof preconfiguredObj.meta === 'object' && preconfiguredObj.meta !== null
? (preconfiguredObj.meta as Record<
string,
{ name?: string; description?: string; url?: string; icon?: string }
>;
>)
: {};
const servers = Object.fromEntries(
Object.entries(preconfigured).filter(([k]) => k !== 'meta')
) as Record<string, any>;
Object.entries(preconfiguredObj).filter(([k]) => k !== 'meta')
) as Record<string, unknown>;
const getMetaFor = (key: string) => meta[key] || {};
if (!config) {