From ef5584a4882032dbdcc8036dab59f0354d8a611f Mon Sep 17 00:00:00 2001 From: Cody Seibert Date: Tue, 9 Dec 2025 01:42:42 -0500 Subject: [PATCH] Remove analysis link and related code - Removed Analysis navigation link from sidebar - Removed AnalysisView component import and case from page.tsx - Removed analysis from ViewMode type in app-store - Removed analysis-related state (projectAnalysis, isAnalyzing) and actions - Deleted analysis-view.tsx file - Removed unused Search icon import Generated with Claude Code https://claude.com/claude-code Co-Authored-By: Claude Opus 4.5 --- .automaker/feature_list.json | 14 +- app/src/app/page.tsx | 3 - app/src/components/layout/sidebar.tsx | 2 - app/src/components/views/analysis-view.tsx | 1119 -------------------- app/src/store/app-store.ts | 36 +- 5 files changed, 9 insertions(+), 1165 deletions(-) delete mode 100644 app/src/components/views/analysis-view.tsx diff --git a/.automaker/feature_list.json b/.automaker/feature_list.json index 2095e4dd..c418e2f2 100644 --- a/.automaker/feature_list.json +++ b/.automaker/feature_list.json @@ -16,7 +16,7 @@ "3. archive it", "4. expect empty state placeholder in right panel" ], - "status": "verified" + "status": "in_progress" }, { "id": "feature-1765260557163-86b3tby5d", @@ -30,14 +30,14 @@ "category": "Kanban", "description": "when clicking a value in the typeahead, there is a bug where it does not close automatically, fix this", "steps": [], - "status": "verified" + "status": "in_progress" }, { "id": "feature-1765260671085-7dgotl21h", "category": "Kanban", "description": "show a error toast when concurrency limit is hit and someone tries to drag a card into in progress to give them feedback why it won't work.", "steps": [], - "status": "verified" + "status": "in_progress" }, { "id": "feature-1765260791341-iaxxt172n", @@ -58,21 +58,21 @@ "category": "Kanban", "description": "add a count up timer for showing how long the card has been in progress", "steps": [], - "status": "verified" + "status": "in_progress" }, { "id": "feature-1765261027396-b78maajg7", "category": "Kanban", "description": "When the agent is marked as verified, remove their context file", "steps": [], - "status": "verified" + "status": "backlog" }, { "id": "feature-1765261574969-kaqzq39fh", "category": "Core", "description": "change the recent change for adding the ability to edit the context .automaker/context directory to instead be in .automaker/support and auto add it to prompts", "steps": [], - "status": "verified" + "status": "in_progress" }, { "id": "feature-1765262225700-q2rkue6l8", @@ -86,7 +86,7 @@ "category": "Kanban", "description": "Ability to delete in progress cards which will auto stop their agents on delete", "steps": [], - "status": "verified" + "status": "in_progress" }, { "id": "feature-1765262348401-hivjg6vuq", diff --git a/app/src/app/page.tsx b/app/src/app/page.tsx index ad7bf75b..024477c2 100644 --- a/app/src/app/page.tsx +++ b/app/src/app/page.tsx @@ -8,7 +8,6 @@ import { SpecView } from "@/components/views/spec-view"; import { CodeView } from "@/components/views/code-view"; import { AgentView } from "@/components/views/agent-view"; import { SettingsView } from "@/components/views/settings-view"; -import { AnalysisView } from "@/components/views/analysis-view"; import { AgentToolsView } from "@/components/views/agent-tools-view"; import { InterviewView } from "@/components/views/interview-view"; import { ContextView } from "@/components/views/context-view"; @@ -72,8 +71,6 @@ export default function Home() { return ; case "settings": return ; - case "analysis": - return ; case "tools": return ; case "interview": diff --git a/app/src/components/layout/sidebar.tsx b/app/src/components/layout/sidebar.tsx index 5d73e785..df4ce5b4 100644 --- a/app/src/components/layout/sidebar.tsx +++ b/app/src/components/layout/sidebar.tsx @@ -16,7 +16,6 @@ import { ChevronRight, Folder, X, - Search, Wrench, PanelLeft, PanelLeftClose, @@ -71,7 +70,6 @@ export function Sidebar() { { id: "spec", label: "Spec Editor", icon: FileText }, { id: "context", label: "Context", icon: BookOpen }, { id: "code", label: "Code View", icon: Code }, - { id: "analysis", label: "Analysis", icon: Search }, { id: "tools", label: "Agent Tools", icon: Wrench }, ], }, diff --git a/app/src/components/views/analysis-view.tsx b/app/src/components/views/analysis-view.tsx deleted file mode 100644 index 4a4d3005..00000000 --- a/app/src/components/views/analysis-view.tsx +++ /dev/null @@ -1,1119 +0,0 @@ -"use client"; - -import { useCallback, useState } from "react"; -import { useAppStore, FileTreeNode, ProjectAnalysis } from "@/store/app-store"; -import { getElectronAPI } from "@/lib/electron"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; -import { Button } from "@/components/ui/button"; -import { - Folder, - FolderOpen, - File, - ChevronRight, - ChevronDown, - Search, - RefreshCw, - BarChart3, - FileCode, - Loader2, - FileText, - CheckCircle, - AlertCircle, - ListChecks, -} from "lucide-react"; -import { cn } from "@/lib/utils"; - -const IGNORE_PATTERNS = [ - "node_modules", - ".git", - ".next", - "dist", - "build", - ".DS_Store", - "*.log", - ".cache", - "coverage", - "__pycache__", - ".pytest_cache", - ".venv", - "venv", - ".env", -]; - -const shouldIgnore = (name: string) => { - return IGNORE_PATTERNS.some((pattern) => { - if (pattern.startsWith("*")) { - return name.endsWith(pattern.slice(1)); - } - return name === pattern; - }); -}; - -const getExtension = (filename: string): string => { - const parts = filename.split("."); - return parts.length > 1 ? parts.pop() || "" : ""; -}; - -export function AnalysisView() { - const { - currentProject, - projectAnalysis, - isAnalyzing, - setProjectAnalysis, - setIsAnalyzing, - clearAnalysis, - } = useAppStore(); - - const [expandedFolders, setExpandedFolders] = useState>( - new Set() - ); - const [isGeneratingSpec, setIsGeneratingSpec] = useState(false); - const [specGenerated, setSpecGenerated] = useState(false); - const [specError, setSpecError] = useState(null); - const [isGeneratingFeatureList, setIsGeneratingFeatureList] = useState(false); - const [featureListGenerated, setFeatureListGenerated] = useState(false); - const [featureListError, setFeatureListError] = useState(null); - - // Recursively scan directory - const scanDirectory = useCallback( - async (path: string, depth: number = 0): Promise => { - if (depth > 10) return []; // Prevent infinite recursion - - const api = getElectronAPI(); - try { - const result = await api.readdir(path); - if (!result.success || !result.entries) return []; - - const nodes: FileTreeNode[] = []; - const entries = result.entries.filter((e) => !shouldIgnore(e.name)); - - for (const entry of entries) { - const fullPath = `${path}/${entry.name}`; - const node: FileTreeNode = { - name: entry.name, - path: fullPath, - isDirectory: entry.isDirectory, - extension: entry.isFile ? getExtension(entry.name) : undefined, - }; - - if (entry.isDirectory) { - // Recursively scan subdirectories - node.children = await scanDirectory(fullPath, depth + 1); - } - - nodes.push(node); - } - - // Sort: directories first, then files alphabetically - nodes.sort((a, b) => { - if (a.isDirectory && !b.isDirectory) return -1; - if (!a.isDirectory && b.isDirectory) return 1; - return a.name.localeCompare(b.name); - }); - - return nodes; - } catch (error) { - console.error("Failed to scan directory:", path, error); - return []; - } - }, - [] - ); - - // Count files and directories - const countNodes = ( - nodes: FileTreeNode[] - ): { files: number; dirs: number; byExt: Record } => { - let files = 0; - let dirs = 0; - const byExt: Record = {}; - - const traverse = (items: FileTreeNode[]) => { - for (const item of items) { - if (item.isDirectory) { - dirs++; - if (item.children) traverse(item.children); - } else { - files++; - if (item.extension) { - byExt[item.extension] = (byExt[item.extension] || 0) + 1; - } else { - byExt["(no extension)"] = (byExt["(no extension)"] || 0) + 1; - } - } - } - }; - - traverse(nodes); - return { files, dirs, byExt }; - }; - - // Run the analysis - const runAnalysis = useCallback(async () => { - if (!currentProject) return; - - setIsAnalyzing(true); - clearAnalysis(); - - try { - const fileTree = await scanDirectory(currentProject.path); - const counts = countNodes(fileTree); - - const analysis: ProjectAnalysis = { - fileTree, - totalFiles: counts.files, - totalDirectories: counts.dirs, - filesByExtension: counts.byExt, - analyzedAt: new Date().toISOString(), - }; - - setProjectAnalysis(analysis); - } catch (error) { - console.error("Analysis failed:", error); - } finally { - setIsAnalyzing(false); - } - }, [ - currentProject, - setIsAnalyzing, - clearAnalysis, - scanDirectory, - setProjectAnalysis, - ]); - - // Generate app_spec.txt from analysis - const generateSpec = useCallback(async () => { - if (!currentProject || !projectAnalysis) return; - - setIsGeneratingSpec(true); - setSpecError(null); - setSpecGenerated(false); - - try { - const api = getElectronAPI(); - - // Read key files to understand the project better - const fileContents: Record = {}; - const keyFiles = ["package.json", "README.md", "tsconfig.json"]; - - // Collect file paths from analysis - const collectFilePaths = ( - nodes: FileTreeNode[], - maxDepth: number = 3, - currentDepth: number = 0 - ): string[] => { - const paths: string[] = []; - for (const node of nodes) { - if (!node.isDirectory) { - paths.push(node.path); - } else if (node.children && currentDepth < maxDepth) { - paths.push( - ...collectFilePaths(node.children, maxDepth, currentDepth + 1) - ); - } - } - return paths; - }; - - const allFilePaths = collectFilePaths(projectAnalysis.fileTree); - - // Try to read key configuration files - for (const keyFile of keyFiles) { - const filePath = `${currentProject.path}/${keyFile}`; - const exists = await api.exists(filePath); - if (exists) { - const result = await api.readFile(filePath); - if (result.success && result.content) { - fileContents[keyFile] = result.content; - } - } - } - - // Detect project type and tech stack - const detectTechStack = () => { - const stack: string[] = []; - const extensions = projectAnalysis.filesByExtension; - - // Check package.json for dependencies - if (fileContents["package.json"]) { - try { - const pkg = JSON.parse(fileContents["package.json"]); - if (pkg.dependencies?.react || pkg.dependencies?.["react-dom"]) - stack.push("React"); - if (pkg.dependencies?.next) stack.push("Next.js"); - if (pkg.dependencies?.vue) stack.push("Vue"); - if (pkg.dependencies?.angular) stack.push("Angular"); - if (pkg.dependencies?.express) stack.push("Express"); - if (pkg.dependencies?.electron) stack.push("Electron"); - if (pkg.devDependencies?.typescript || pkg.dependencies?.typescript) - stack.push("TypeScript"); - if ( - pkg.devDependencies?.tailwindcss || - pkg.dependencies?.tailwindcss - ) - stack.push("Tailwind CSS"); - if (pkg.devDependencies?.playwright || pkg.dependencies?.playwright) - stack.push("Playwright"); - if (pkg.devDependencies?.jest || pkg.dependencies?.jest) - stack.push("Jest"); - } catch { - // Ignore JSON parse errors - } - } - - // Detect by file extensions - if (extensions["ts"] || extensions["tsx"]) stack.push("TypeScript"); - if (extensions["py"]) stack.push("Python"); - if (extensions["go"]) stack.push("Go"); - if (extensions["rs"]) stack.push("Rust"); - if (extensions["java"]) stack.push("Java"); - if (extensions["css"] || extensions["scss"] || extensions["sass"]) - stack.push("CSS/SCSS"); - - // Remove duplicates - return [...new Set(stack)]; - }; - - // Get project name from package.json or folder name - const getProjectName = () => { - if (fileContents["package.json"]) { - try { - const pkg = JSON.parse(fileContents["package.json"]); - if (pkg.name) return pkg.name; - } catch { - // Ignore JSON parse errors - } - } - // Fall back to folder name - return currentProject.name; - }; - - // Get project description from package.json or README - const getProjectDescription = () => { - if (fileContents["package.json"]) { - try { - const pkg = JSON.parse(fileContents["package.json"]); - if (pkg.description) return pkg.description; - } catch { - // Ignore JSON parse errors - } - } - if (fileContents["README.md"]) { - // Extract first paragraph from README - const lines = fileContents["README.md"].split("\n"); - for (const line of lines) { - const trimmed = line.trim(); - if ( - trimmed && - !trimmed.startsWith("#") && - !trimmed.startsWith("!") && - trimmed.length > 20 - ) { - return trimmed.substring(0, 200); - } - } - } - return "A software project"; - }; - - // Group files by directory for structure analysis - const analyzeStructure = () => { - const structure: string[] = []; - const topLevelDirs = projectAnalysis.fileTree - .filter((n) => n.isDirectory) - .map((n) => n.name); - - for (const dir of topLevelDirs) { - structure.push(` `); - } - return structure.join("\n"); - }; - - const projectName = getProjectName(); - const description = getProjectDescription(); - const techStack = detectTechStack(); - - // Generate the spec content - const specContent = ` - ${projectName} - - - ${description} - - - - -${Object.entries(projectAnalysis.filesByExtension) - .filter(([ext]) => - ["ts", "tsx", "js", "jsx", "py", "go", "rs", "java", "cpp", "c"].includes( - ext - ) - ) - .sort((a, b) => b[1] - a[1]) - .slice(0, 5) - .map(([ext, count]) => ` `) - .join("\n")} - - -${techStack.map((tech) => ` ${tech}`).join("\n")} - - - - - ${projectAnalysis.totalFiles} - ${projectAnalysis.totalDirectories} - -${analyzeStructure()} - - - - -${Object.entries(projectAnalysis.filesByExtension) - .sort((a, b) => b[1] - a[1]) - .slice(0, 10) - .map( - ([ext, count]) => - ` ` - ) - .join("\n")} - - - ${projectAnalysis.analyzedAt} - -`; - - // Write the spec file - const specPath = `${currentProject.path}/app_spec.txt`; - const writeResult = await api.writeFile(specPath, specContent); - - if (writeResult.success) { - setSpecGenerated(true); - } else { - setSpecError(writeResult.error || "Failed to write spec file"); - } - } catch (error) { - console.error("Failed to generate spec:", error); - setSpecError( - error instanceof Error ? error.message : "Failed to generate spec" - ); - } finally { - setIsGeneratingSpec(false); - } - }, [currentProject, projectAnalysis]); - - // Generate .automaker/feature_list.json from analysis - const generateFeatureList = useCallback(async () => { - if (!currentProject || !projectAnalysis) return; - - setIsGeneratingFeatureList(true); - setFeatureListError(null); - setFeatureListGenerated(false); - - try { - const api = getElectronAPI(); - - // Read key files to understand the project - const fileContents: Record = {}; - const keyFiles = ["package.json", "README.md"]; - - // Try to read key configuration files - for (const keyFile of keyFiles) { - const filePath = `${currentProject.path}/${keyFile}`; - const exists = await api.exists(filePath); - if (exists) { - const result = await api.readFile(filePath); - if (result.success && result.content) { - fileContents[keyFile] = result.content; - } - } - } - - // Collect file paths from analysis - const collectFilePaths = (nodes: FileTreeNode[]): string[] => { - const paths: string[] = []; - for (const node of nodes) { - if (!node.isDirectory) { - paths.push(node.path); - } else if (node.children) { - paths.push(...collectFilePaths(node.children)); - } - } - return paths; - }; - - const allFilePaths = collectFilePaths(projectAnalysis.fileTree); - - // Analyze directories and files to detect features - interface DetectedFeature { - category: string; - description: string; - steps: string[]; - passes: boolean; - } - - const detectedFeatures: DetectedFeature[] = []; - - // Detect features based on project structure and files - const detectFeatures = () => { - const extensions = projectAnalysis.filesByExtension; - const topLevelDirs = projectAnalysis.fileTree - .filter((n) => n.isDirectory) - .map((n) => n.name.toLowerCase()); - const topLevelFiles = projectAnalysis.fileTree - .filter((n) => !n.isDirectory) - .map((n) => n.name.toLowerCase()); - - // Check for test directories and files - const hasTests = - topLevelDirs.includes("tests") || - topLevelDirs.includes("test") || - topLevelDirs.includes("__tests__") || - allFilePaths.some( - (p) => p.includes(".spec.") || p.includes(".test.") - ); - - if (hasTests) { - detectedFeatures.push({ - category: "Testing", - description: "Automated test suite", - steps: [ - "Step 1: Tests directory exists", - "Step 2: Test files are present", - "Step 3: Run test suite", - ], - passes: true, - }); - } - - // Check for components directory (UI components) - const hasComponents = - topLevelDirs.includes("components") || - allFilePaths.some((p) => p.toLowerCase().includes("/components/")); - - if (hasComponents) { - detectedFeatures.push({ - category: "UI/Design", - description: "Component-based UI architecture", - steps: [ - "Step 1: Components directory exists", - "Step 2: UI components are defined", - "Step 3: Components are reusable", - ], - passes: true, - }); - } - - // Check for src directory (organized source code) - if (topLevelDirs.includes("src")) { - detectedFeatures.push({ - category: "Project Structure", - description: "Organized source code structure", - steps: [ - "Step 1: Source directory exists", - "Step 2: Code is properly organized", - "Step 3: Follows best practices", - ], - passes: true, - }); - } - - // Check package.json for dependencies and detect features - if (fileContents["package.json"]) { - try { - const pkg = JSON.parse(fileContents["package.json"]); - - // React/Next.js app detection - if (pkg.dependencies?.react || pkg.dependencies?.["react-dom"]) { - detectedFeatures.push({ - category: "Frontend", - description: "React-based user interface", - steps: [ - "Step 1: React is installed", - "Step 2: Components render correctly", - "Step 3: State management works", - ], - passes: true, - }); - } - - if (pkg.dependencies?.next) { - detectedFeatures.push({ - category: "Framework", - description: "Next.js framework integration", - steps: [ - "Step 1: Next.js is configured", - "Step 2: Pages/routes are defined", - "Step 3: Server-side rendering works", - ], - passes: true, - }); - } - - // TypeScript support - if ( - pkg.devDependencies?.typescript || - pkg.dependencies?.typescript || - extensions["ts"] || - extensions["tsx"] - ) { - detectedFeatures.push({ - category: "Developer Experience", - description: "TypeScript type safety", - steps: [ - "Step 1: TypeScript is configured", - "Step 2: Type definitions exist", - "Step 3: Code compiles without errors", - ], - passes: true, - }); - } - - // Tailwind CSS - if ( - pkg.devDependencies?.tailwindcss || - pkg.dependencies?.tailwindcss - ) { - detectedFeatures.push({ - category: "UI/Design", - description: "Tailwind CSS styling", - steps: [ - "Step 1: Tailwind is configured", - "Step 2: Styles are applied", - "Step 3: Responsive design works", - ], - passes: true, - }); - } - - // ESLint/Prettier (code quality) - if (pkg.devDependencies?.eslint || pkg.devDependencies?.prettier) { - detectedFeatures.push({ - category: "Developer Experience", - description: "Code quality tools", - steps: [ - "Step 1: Linter is configured", - "Step 2: Code passes lint checks", - "Step 3: Formatting is consistent", - ], - passes: true, - }); - } - - // Electron (desktop app) - if (pkg.dependencies?.electron || pkg.devDependencies?.electron) { - detectedFeatures.push({ - category: "Platform", - description: "Electron desktop application", - steps: [ - "Step 1: Electron is configured", - "Step 2: Main process runs", - "Step 3: Renderer process loads", - ], - passes: true, - }); - } - - // Playwright testing - if ( - pkg.devDependencies?.playwright || - pkg.devDependencies?.["@playwright/test"] - ) { - detectedFeatures.push({ - category: "Testing", - description: "Playwright end-to-end testing", - steps: [ - "Step 1: Playwright is configured", - "Step 2: E2E tests are defined", - "Step 3: Tests pass successfully", - ], - passes: true, - }); - } - } catch { - // Ignore JSON parse errors - } - } - - // Check for documentation - if ( - topLevelFiles.includes("readme.md") || - topLevelDirs.includes("docs") - ) { - detectedFeatures.push({ - category: "Documentation", - description: "Project documentation", - steps: [ - "Step 1: README exists", - "Step 2: Documentation is comprehensive", - "Step 3: Setup instructions are clear", - ], - passes: true, - }); - } - - // Check for CI/CD configuration - const hasCICD = - topLevelDirs.includes(".github") || - topLevelFiles.includes(".gitlab-ci.yml") || - topLevelFiles.includes(".travis.yml"); - - if (hasCICD) { - detectedFeatures.push({ - category: "DevOps", - description: "CI/CD pipeline configuration", - steps: [ - "Step 1: CI config exists", - "Step 2: Pipeline runs on push", - "Step 3: Automated checks pass", - ], - passes: true, - }); - } - - // Check for API routes (Next.js API or Express) - const hasAPIRoutes = allFilePaths.some( - (p) => - p.includes("/api/") || - p.includes("/routes/") || - p.includes("/endpoints/") - ); - - if (hasAPIRoutes) { - detectedFeatures.push({ - category: "Backend", - description: "API endpoints", - steps: [ - "Step 1: API routes are defined", - "Step 2: Endpoints respond correctly", - "Step 3: Error handling is implemented", - ], - passes: true, - }); - } - - // Check for state management - const hasStateManagement = allFilePaths.some( - (p) => - p.includes("/store/") || - p.includes("/stores/") || - p.includes("/redux/") || - p.includes("/context/") - ); - - if (hasStateManagement) { - detectedFeatures.push({ - category: "Architecture", - description: "State management system", - steps: [ - "Step 1: Store is configured", - "Step 2: State updates correctly", - "Step 3: Components access state", - ], - passes: true, - }); - } - - // Check for configuration files - if ( - topLevelFiles.includes("tsconfig.json") || - topLevelFiles.includes("package.json") - ) { - detectedFeatures.push({ - category: "Configuration", - description: "Project configuration files", - steps: [ - "Step 1: Config files exist", - "Step 2: Configuration is valid", - "Step 3: Build process works", - ], - passes: true, - }); - } - }; - - detectFeatures(); - - // If no features were detected, add a default feature - if (detectedFeatures.length === 0) { - detectedFeatures.push({ - category: "Core", - description: "Basic project structure", - steps: [ - "Step 1: Project directory exists", - "Step 2: Files are present", - "Step 3: Project can be loaded", - ], - passes: true, - }); - } - - // Generate the feature list content - const featureListContent = JSON.stringify(detectedFeatures, null, 2); - - // Write the feature list file - const featureListPath = `${currentProject.path}/feature_list.json`; - const writeResult = await api.writeFile( - featureListPath, - featureListContent - ); - - if (writeResult.success) { - setFeatureListGenerated(true); - } else { - setFeatureListError( - writeResult.error || "Failed to write feature list file" - ); - } - } catch (error) { - console.error("Failed to generate feature list:", error); - setFeatureListError( - error instanceof Error - ? error.message - : "Failed to generate feature list" - ); - } finally { - setIsGeneratingFeatureList(false); - } - }, [currentProject, projectAnalysis]); - - // Toggle folder expansion - const toggleFolder = (path: string) => { - const newExpanded = new Set(expandedFolders); - if (expandedFolders.has(path)) { - newExpanded.delete(path); - } else { - newExpanded.add(path); - } - setExpandedFolders(newExpanded); - }; - - // Render file tree node - const renderNode = (node: FileTreeNode, depth: number = 0) => { - const isExpanded = expandedFolders.has(node.path); - - return ( -
-
{ - if (node.isDirectory) { - toggleFolder(node.path); - } - }} - > - {node.isDirectory ? ( - <> - {isExpanded ? ( - - ) : ( - - )} - {isExpanded ? ( - - ) : ( - - )} - - ) : ( - <> - - - - )} - {node.name} - {node.extension && ( - - .{node.extension} - - )} -
- {node.isDirectory && isExpanded && node.children && ( -
- {node.children.map((child) => renderNode(child, depth + 1))} -
- )} -
- ); - }; - - if (!currentProject) { - return ( -
-

No project selected

-
- ); - } - - return ( -
- {/* Header */} -
-
- -
-

Project Analysis

-

- {currentProject.name} -

-
-
- -
- - {/* Content */} -
- {!projectAnalysis && !isAnalyzing ? ( -
- -

No Analysis Yet

-

- Click "Analyze Project" to scan your codebase and get - insights about its structure. -

- -
- ) : isAnalyzing ? ( -
- -

Scanning project files...

-
- ) : projectAnalysis ? ( -
- {/* Stats Panel */} -
- - - - - Statistics - - - Analyzed{" "} - {new Date(projectAnalysis.analyzedAt).toLocaleString()} - - - -
- - Total Files - - - {projectAnalysis.totalFiles} - -
-
- - Total Directories - - - {projectAnalysis.totalDirectories} - -
-
-
- - - - - - Files by Extension - - - -
- {Object.entries(projectAnalysis.filesByExtension) - .sort((a, b) => b[1] - a[1]) - .slice(0, 15) - .map(([ext, count]) => ( -
- - {ext.startsWith("(") ? ext : `.${ext}`} - - {count} -
- ))} -
-
-
- - {/* Generate Spec Card */} - - - - - Generate Specification - - - Create app_spec.txt from analysis - - - -

- Generate a project specification file based on the analyzed - codebase structure and detected technologies. -

- - {specGenerated && ( -
- - app_spec.txt created successfully! -
- )} - {specError && ( -
- - {specError} -
- )} -
-
- - {/* Generate Feature List Card */} - - - - - Generate Feature List - - - Create .automaker/feature_list.json from analysis - - - -

- Automatically detect and generate a feature list based on - the analyzed codebase structure, dependencies, and project - configuration. -

- - {featureListGenerated && ( -
- - feature_list.json created successfully! -
- )} - {featureListError && ( -
- - {featureListError} -
- )} -
-
-
- - {/* File Tree */} - - - - - File Tree - - - {projectAnalysis.totalFiles} files in{" "} - {projectAnalysis.totalDirectories} directories - - - -
- {projectAnalysis.fileTree.map((node) => renderNode(node))} -
-
-
-
- ) : null} -
-
- ); -} diff --git a/app/src/store/app-store.ts b/app/src/store/app-store.ts index a19514ef..6b3a3b64 100644 --- a/app/src/store/app-store.ts +++ b/app/src/store/app-store.ts @@ -2,7 +2,7 @@ import { create } from "zustand"; import { persist } from "zustand/middleware"; import type { Project } from "@/lib/electron"; -export type ViewMode = "welcome" | "spec" | "board" | "code" | "agent" | "settings" | "analysis" | "tools" | "interview" | "context"; +export type ViewMode = "welcome" | "spec" | "board" | "code" | "agent" | "settings" | "tools" | "interview" | "context"; export type ThemeMode = "light" | "dark" | "system"; export interface ApiKeys { @@ -51,23 +51,7 @@ export interface Feature { steps: string[]; status: "backlog" | "in_progress" | "verified"; images?: FeatureImage[]; -} - -export interface FileTreeNode { - name: string; - path: string; - isDirectory: boolean; - children?: FileTreeNode[]; - size?: number; - extension?: string; -} - -export interface ProjectAnalysis { - fileTree: FileTreeNode[]; - totalFiles: number; - totalDirectories: number; - filesByExtension: Record; - analyzedAt: string; + startedAt?: string; // ISO timestamp for when the card moved to in_progress } export interface AppState { @@ -94,10 +78,6 @@ export interface AppState { // API Keys apiKeys: ApiKeys; - // Project Analysis - projectAnalysis: ProjectAnalysis | null; - isAnalyzing: boolean; - // Chat Sessions chatSessions: ChatSession[]; currentChatSession: ChatSession | null; @@ -152,11 +132,6 @@ export interface AppActions { // API Keys actions setApiKeys: (keys: Partial) => void; - // Analysis actions - setProjectAnalysis: (analysis: ProjectAnalysis | null) => void; - setIsAnalyzing: (isAnalyzing: boolean) => void; - clearAnalysis: () => void; - // Chat Session actions createChatSession: (title?: string) => ChatSession; updateChatSession: (sessionId: string, updates: Partial) => void; @@ -194,8 +169,6 @@ const initialState: AppState = { anthropic: "", google: "", }, - projectAnalysis: null, - isAnalyzing: false, chatSessions: [], currentChatSession: null, chatHistoryOpen: false, @@ -285,11 +258,6 @@ export const useAppStore = create()( // API Keys actions setApiKeys: (keys) => set({ apiKeys: { ...get().apiKeys, ...keys } }), - // Analysis actions - setProjectAnalysis: (analysis) => set({ projectAnalysis: analysis }), - setIsAnalyzing: (isAnalyzing) => set({ isAnalyzing }), - clearAnalysis: () => set({ projectAnalysis: null, isAnalyzing: false }), - // Chat Session actions createChatSession: (title) => { const currentProject = get().currentProject;