feat(automaker): enhance feature management and UI components

- Updated `.gitignore` to include agent context files and user-uploaded images for better organization.
- Added "Uncategorized" category to `categories.json` for improved feature classification.
- Populated `feature_list.json` with new features, including detailed descriptions and image attachments for better context.
- Changed application icon to `icon_gold.png` for a refreshed look.
- Enhanced `AutoModeService` to support max concurrency and periodic checks, improving feature execution management.
- Updated image handling in `DescriptionImageDropZone` to save images in the project directory.
- Improved UI components with better styling and responsiveness, including drag-and-drop functionality for project management.

This update significantly enhances the feature management process and user experience within the application.
This commit is contained in:
Cody Seibert
2025-12-09 21:23:09 -05:00
parent ac5b562f7a
commit 7b760090e4
28 changed files with 1207 additions and 774 deletions

View File

@@ -23,7 +23,6 @@ import {
FeatureImagePath,
} from "@/store/app-store";
import { getElectronAPI } from "@/lib/electron";
import { cn } from "@/lib/utils";
import {
Card,
CardDescription,
@@ -50,7 +49,6 @@ import {
} from "@/components/ui/dialog";
import { KanbanColumn } from "./kanban-column";
import { KanbanCard } from "./kanban-card";
import { AutoModeLog } from "./auto-mode-log";
import { AgentOutputModal } from "./agent-output-modal";
import {
Plus,
@@ -58,8 +56,6 @@ import {
Play,
StopCircle,
Loader2,
ChevronUp,
ChevronDown,
Users,
Trash2,
FastForward,
@@ -114,7 +110,6 @@ export function BoardView() {
});
const [isLoading, setIsLoading] = useState(true);
const [isMounted, setIsMounted] = useState(false);
const [showActivityLog, setShowActivityLog] = useState(false);
const [showOutputModal, setShowOutputModal] = useState(false);
const [outputFeature, setOutputFeature] = useState<Feature | null>(null);
const [featuresWithContext, setFeaturesWithContext] = useState<Set<string>>(
@@ -342,12 +337,6 @@ export function BoardView() {
}
}, [showAddDialog, defaultSkipTests]);
// Auto-show activity log when auto mode starts
useEffect(() => {
if (autoMode.isRunning && !showActivityLog) {
setShowActivityLog(true);
}
}, [autoMode.isRunning, showActivityLog]);
// Listen for auto mode feature completion and reload features
useEffect(() => {
@@ -408,11 +397,12 @@ export function BoardView() {
// Check which features have context files
useEffect(() => {
const checkAllContexts = async () => {
const inProgressFeatures = features.filter(
(f) => f.status === "in_progress"
// Check context for in_progress, waiting_approval, and verified features
const featuresWithPotentialContext = features.filter(
(f) => f.status === "in_progress" || f.status === "waiting_approval" || f.status === "verified"
);
const contextChecks = await Promise.all(
inProgressFeatures.map(async (f) => ({
featuresWithPotentialContext.map(async (f) => ({
id: f.id,
hasContext: await checkContextExists(f.id),
}))
@@ -659,6 +649,34 @@ export function BoardView() {
}
}
// Delete agent context file if it exists
try {
const api = getElectronAPI();
const contextPath = `${currentProject.path}/.automaker/agents-context/${featureId}.md`;
await api.deleteFile(contextPath);
console.log(`[Board] Deleted agent context for feature ${featureId}`);
} catch (error) {
// Context file might not exist, which is fine
console.log(`[Board] Context file not found or already deleted for feature ${featureId}`);
}
// Delete attached images if they exist
if (feature.imagePaths && feature.imagePaths.length > 0) {
try {
const api = getElectronAPI();
for (const imagePathObj of feature.imagePaths) {
try {
await api.deleteFile(imagePathObj.path);
console.log(`[Board] Deleted image: ${imagePathObj.path}`);
} catch (error) {
console.error(`[Board] Failed to delete image ${imagePathObj.path}:`, error);
}
}
} catch (error) {
console.error(`[Board] Error deleting images for feature ${featureId}:`, error);
}
}
// Remove the feature immediately without confirmation
removeFeature(featureId);
};
@@ -1175,23 +1193,6 @@ export function BoardView() {
</>
)}
{isMounted && autoMode.isRunning && (
<Button
variant="outline"
size="sm"
onClick={() => setShowActivityLog(!showActivityLog)}
data-testid="toggle-activity-log"
>
<Loader2 className="w-4 h-4 mr-2 animate-spin text-purple-500" />
Activity
{showActivityLog ? (
<ChevronDown className="w-4 h-4 ml-2" />
) : (
<ChevronUp className="w-4 h-4 ml-2" />
)}
</Button>
)}
<Button
size="sm"
onClick={() => setShowAddDialog(true)}
@@ -1212,12 +1213,7 @@ export function BoardView() {
{/* Main Content Area */}
<div className="flex-1 flex overflow-hidden">
{/* Kanban Columns */}
<div
className={cn(
"flex-1 overflow-x-auto p-4",
showActivityLog && "transition-all"
)}
>
<div className="flex-1 overflow-x-auto p-4">
<DndContext
sensors={sensors}
collisionDetection={collisionDetectionStrategy}
@@ -1320,13 +1316,6 @@ export function BoardView() {
</DragOverlay>
</DndContext>
</div>
{/* Activity Log Panel */}
{showActivityLog && (
<div className="w-96 border-l border-border flex-shrink-0">
<AutoModeLog onClose={() => setShowActivityLog(false)} />
</div>
)}
</div>
{/* Add Feature Dialog */}
@@ -1605,6 +1594,8 @@ export function BoardView() {
variant="destructive"
onClick={async () => {
const verifiedFeatures = getColumnFeatures("verified");
const api = getElectronAPI();
for (const feature of verifiedFeatures) {
// Check if the feature is currently running
const isRunning = runningAutoTasks.includes(feature.id);
@@ -1621,6 +1612,16 @@ export function BoardView() {
}
}
// Delete agent context file if it exists
try {
const contextPath = `${currentProject.path}/.automaker/agents-context/${feature.id}.md`;
await api.deleteFile(contextPath);
console.log(`[Board] Deleted agent context for feature ${feature.id}`);
} catch (error) {
// Context file might not exist, which is fine
console.debug("[Board] No context file to delete for feature:", feature.id);
}
// Remove the feature
removeFeature(feature.id);
}