mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 21:03:08 +00:00
- 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.
129 lines
4.0 KiB
TypeScript
129 lines
4.0 KiB
TypeScript
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; name?: string } | null;
|
|
specCreatingForProject: string | null;
|
|
setSpecCreatingForProject: (path: string | null) => void;
|
|
checkContextExists: (featureId: string) => Promise<boolean>;
|
|
features: Feature[];
|
|
isLoading: boolean;
|
|
featuresWithContext: Set<string>;
|
|
setFeaturesWithContext: (set: Set<string>) => void;
|
|
}
|
|
|
|
export function useBoardEffects({
|
|
currentProject,
|
|
specCreatingForProject,
|
|
setSpecCreatingForProject,
|
|
checkContextExists,
|
|
features,
|
|
isLoading,
|
|
featuresWithContext,
|
|
setFeaturesWithContext,
|
|
}: UseBoardEffectsProps) {
|
|
// Keep a ref to the current featuresWithContext for use in event handlers
|
|
const featuresWithContextRef = useRef(featuresWithContext);
|
|
useEffect(() => {
|
|
featuresWithContextRef.current = featuresWithContext;
|
|
}, [featuresWithContext]);
|
|
// Make current project available globally for modal
|
|
useEffect(() => {
|
|
if (currentProject) {
|
|
window.__currentProject = currentProject;
|
|
}
|
|
return () => {
|
|
window.__currentProject = null;
|
|
};
|
|
}, [currentProject]);
|
|
|
|
// Subscribe to spec regeneration events to clear creating state on completion
|
|
useEffect(() => {
|
|
const api = getElectronAPI();
|
|
if (!api.specRegeneration) return;
|
|
|
|
const unsubscribe = api.specRegeneration.onEvent((event) => {
|
|
logger.info('Spec regeneration event:', event.type, 'for project:', event.projectPath);
|
|
|
|
if (event.projectPath !== specCreatingForProject) {
|
|
return;
|
|
}
|
|
|
|
if (event.type === 'spec_regeneration_complete') {
|
|
setSpecCreatingForProject(null);
|
|
} else if (event.type === 'spec_regeneration_error') {
|
|
setSpecCreatingForProject(null);
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
unsubscribe();
|
|
};
|
|
}, [specCreatingForProject, setSpecCreatingForProject]);
|
|
|
|
// Note: Running tasks sync is now handled by useAutoMode hook in BoardView
|
|
// which correctly handles worktree/branch scoping.
|
|
|
|
// Check which features have context files
|
|
useEffect(() => {
|
|
const checkAllContexts = async () => {
|
|
const featuresWithPotentialContext = features.filter(
|
|
(f) =>
|
|
f.status === 'in_progress' ||
|
|
f.status === 'waiting_approval' ||
|
|
f.status === 'verified' ||
|
|
(typeof f.status === 'string' && f.status.startsWith('pipeline_'))
|
|
);
|
|
const contextChecks = await Promise.all(
|
|
featuresWithPotentialContext.map(async (f) => ({
|
|
id: f.id,
|
|
hasContext: await checkContextExists(f.id),
|
|
}))
|
|
);
|
|
|
|
const newSet = new Set<string>();
|
|
contextChecks.forEach(({ id, hasContext }) => {
|
|
if (hasContext) {
|
|
newSet.add(id);
|
|
}
|
|
});
|
|
|
|
setFeaturesWithContext(newSet);
|
|
};
|
|
|
|
if (features.length > 0 && !isLoading) {
|
|
checkAllContexts();
|
|
}
|
|
}, [features, isLoading, checkContextExists, setFeaturesWithContext]);
|
|
|
|
// Re-check context when a feature stops, completes, or errors
|
|
// This ensures hasContext is updated even if the features array doesn't change
|
|
useEffect(() => {
|
|
const api = getElectronAPI();
|
|
if (!api?.autoMode) return;
|
|
|
|
const unsubscribe = api.autoMode.onEvent(async (event) => {
|
|
// When a feature stops (error/abort) or completes, re-check its context
|
|
if (
|
|
(event.type === 'auto_mode_error' || event.type === 'auto_mode_feature_complete') &&
|
|
event.featureId
|
|
) {
|
|
const hasContext = await checkContextExists(event.featureId);
|
|
if (hasContext) {
|
|
const newSet = new Set(featuresWithContextRef.current);
|
|
newSet.add(event.featureId);
|
|
setFeaturesWithContext(newSet);
|
|
}
|
|
}
|
|
});
|
|
|
|
return () => {
|
|
unsubscribe();
|
|
};
|
|
}, [checkContextExists, setFeaturesWithContext]);
|
|
}
|