chore: Enhance type safety and improve code consistency across components

- Added a new `typecheck` script in `package.json` for better type checking in the UI workspace.
- Refactored several components to remove unnecessary type assertions and improve type safety, particularly in `new-project-modal.tsx`, `edit-project-dialog.tsx`, and `task-progress-panel.tsx`.
- Updated event handling in `git-diff-panel.tsx` to use async functions for better error handling.
- Improved type definitions in various files, including `setup-view` and `electron.ts`, to ensure consistent usage of types across the codebase.
- Cleaned up global type definitions for better clarity and maintainability.

These changes aim to streamline the development process and reduce potential runtime errors.
This commit is contained in:
Shirone
2026-01-25 18:11:48 +01:00
parent b65037d995
commit 0fb471ca15
28 changed files with 320 additions and 125 deletions

View File

@@ -98,13 +98,11 @@ export const PriorityBadges = memo(function PriorityBadges({
return;
}
// eslint-disable-next-line no-undef
const interval = setInterval(() => {
setCurrentTime(Date.now());
}, 1000);
return () => {
// eslint-disable-next-line no-undef
clearInterval(interval);
};
}, [feature.justFinishedAt, feature.status, currentTime]);

View File

@@ -17,6 +17,7 @@ import { useAppStore } from '@/store/app-store';
import { extractSummary } from '@/lib/log-parser';
import { useAgentOutput } from '@/hooks/queries';
import type { AutoModeEvent } from '@/types/electron';
import type { BacklogPlanEvent } from '@automaker/types';
interface AgentOutputModalProps {
open: boolean;
@@ -48,18 +49,16 @@ export function AgentOutputModal({
const isBacklogPlan = featureId.startsWith('backlog-plan:');
// Resolve project path - prefer prop, fallback to window.__currentProject
const resolvedProjectPath = projectPathProp || (window as any).__currentProject?.path || '';
const resolvedProjectPath = projectPathProp || window.__currentProject?.path || '';
// Track additional content from WebSocket events (appended to query data)
const [streamedContent, setStreamedContent] = useState<string>('');
const [viewMode, setViewMode] = useState<ViewMode | null>(null);
// Use React Query for initial output loading
const { data: initialOutput = '', isLoading } = useAgentOutput(
resolvedProjectPath,
featureId,
open && !!resolvedProjectPath
);
const { data: initialOutput = '', isLoading } = useAgentOutput(resolvedProjectPath, featureId, {
enabled: open && !!resolvedProjectPath,
});
// Reset streamed content when modal opens or featureId changes
useEffect(() => {
@@ -262,7 +261,8 @@ export function AgentOutputModal({
const api = getElectronAPI();
if (!api?.backlogPlan) return;
const unsubscribe = api.backlogPlan.onEvent((event: any) => {
const unsubscribe = api.backlogPlan.onEvent((data: unknown) => {
const event = data as BacklogPlanEvent;
if (!event?.type) return;
let newContent = '';

View File

@@ -1,15 +1,16 @@
import { useEffect, useRef } from 'react';
import { getElectronAPI } from '@/lib/electron';
import { createLogger } from '@automaker/utils/logger';
import type { Feature } from '@/store/app-store';
const logger = createLogger('BoardEffects');
interface UseBoardEffectsProps {
currentProject: { path: string; id: string } | null;
currentProject: { path: string; id: string; name?: string } | null;
specCreatingForProject: string | null;
setSpecCreatingForProject: (path: string | null) => void;
checkContextExists: (featureId: string) => Promise<boolean>;
features: any[];
features: Feature[];
isLoading: boolean;
featuresWithContext: Set<string>;
setFeaturesWithContext: (set: Set<string>) => void;
@@ -33,10 +34,10 @@ export function useBoardEffects({
// Make current project available globally for modal
useEffect(() => {
if (currentProject) {
(window as any).__currentProject = currentProject;
window.__currentProject = currentProject;
}
return () => {
(window as any).__currentProject = null;
window.__currentProject = null;
};
}, [currentProject]);

View File

@@ -1,4 +1,3 @@
// @ts-nocheck - model selector with provider-specific model options and validation
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { Brain, AlertTriangle } from 'lucide-react';
@@ -7,7 +6,7 @@ import { cn } from '@/lib/utils';
import { useAppStore } from '@/store/app-store';
import { useSetupStore } from '@/store/setup-store';
import { getModelProvider } from '@automaker/types';
import type { ModelProvider } from '@automaker/types';
import type { ModelProvider, CursorModelId } from '@automaker/types';
import { CLAUDE_MODELS, CURSOR_MODELS, ModelOption } from './model-constants';
import { useEffect } from 'react';
import { Spinner } from '@/components/ui/spinner';
@@ -40,6 +39,7 @@ export function ModelSelector({
const isCursorAvailable = cursorCliStatus?.installed && cursorCliStatus?.auth?.authenticated;
// Check if Codex CLI is available
// @ts-expect-error - codexCliStatus uses CliStatus type but should use CodexCliStatus which has auth
const isCodexAvailable = codexCliStatus?.installed && codexCliStatus?.auth?.authenticated;
// Fetch Codex models on mount
@@ -75,8 +75,8 @@ export function ModelSelector({
// Check both the full ID (for GPT models) and the unprefixed version (for non-GPT models)
const unprefixedId = model.id.startsWith('cursor-') ? model.id.slice(7) : model.id;
return (
enabledCursorModels.includes(model.id as any) ||
enabledCursorModels.includes(unprefixedId as any)
enabledCursorModels.includes(model.id as CursorModelId) ||
enabledCursorModels.includes(unprefixedId as CursorModelId)
);
});