mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 06:42:03 +00:00
- Add edge dragging to create dependencies in graph view - Add spawn sub-task action available in graph view and kanban board - Implement ancestor context selection when spawning tasks - Add dependency validation (circular, self, duplicate prevention) - Include ancestor context in spawned task descriptions 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
import { Feature } from '@/store/app-store';
|
|
|
|
/**
|
|
* Checks if adding a dependency from sourceId to targetId would create a circular dependency.
|
|
* Uses DFS to detect if targetId can reach sourceId through existing dependencies.
|
|
*
|
|
* @param features - All features in the system
|
|
* @param sourceId - The feature that would become a dependency (the prerequisite)
|
|
* @param targetId - The feature that would depend on sourceId
|
|
* @returns true if adding this dependency would create a cycle
|
|
*/
|
|
export function wouldCreateCircularDependency(
|
|
features: Feature[],
|
|
sourceId: string,
|
|
targetId: string
|
|
): boolean {
|
|
const featureMap = new Map(features.map((f) => [f.id, f]));
|
|
const visited = new Set<string>();
|
|
|
|
function canReach(currentId: string, targetId: string): boolean {
|
|
if (currentId === targetId) return true;
|
|
if (visited.has(currentId)) return false;
|
|
|
|
visited.add(currentId);
|
|
const feature = featureMap.get(currentId);
|
|
if (!feature?.dependencies) return false;
|
|
|
|
for (const depId of feature.dependencies) {
|
|
if (canReach(depId, targetId)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Check if source can reach target through existing dependencies
|
|
// If so, adding target -> source would create a cycle
|
|
return canReach(sourceId, targetId);
|
|
}
|
|
|
|
/**
|
|
* Checks if a dependency already exists between two features.
|
|
*
|
|
* @param features - All features in the system
|
|
* @param sourceId - The potential dependency (prerequisite)
|
|
* @param targetId - The feature that might depend on sourceId
|
|
* @returns true if targetId already depends on sourceId
|
|
*/
|
|
export function dependencyExists(features: Feature[], sourceId: string, targetId: string): boolean {
|
|
const targetFeature = features.find((f) => f.id === targetId);
|
|
if (!targetFeature?.dependencies) return false;
|
|
return targetFeature.dependencies.includes(sourceId);
|
|
}
|