diff --git a/.automaker/feature_list.json b/.automaker/feature_list.json index e4b8f903..603fcaf4 100644 --- a/.automaker/feature_list.json +++ b/.automaker/feature_list.json @@ -25,7 +25,7 @@ "category": "Kanban", "description": "Make in progress column double width so that the cards display 2 columns masonry layout", "steps": [], - "status": "in_progress" + "status": "verified" }, { "id": "feature-1765262430461-vennhg2b5", @@ -60,7 +60,13 @@ "category": "Core", "description": "remove the code view link", "steps": [], - "status": "in_progress", - "startedAt": "2025-12-09T07:12:24.361Z" + "status": "verified" + }, + { + "id": "feature-1765264472003-ikdarjmlw", + "category": "Core", + "description": "Add shortcuts keys to all left navigation links, then add shortcuts to the add buttons on the routes (such as kanbam add feature). mske sure they don't mess with normal input or textarea typing or typeaheads. display the shortkey in link or button for users to know (K)", + "steps": [], + "status": "in_progress" } ] \ No newline at end of file diff --git a/app/src/app/page.tsx b/app/src/app/page.tsx index 024477c2..a9691a92 100644 --- a/app/src/app/page.tsx +++ b/app/src/app/page.tsx @@ -5,7 +5,6 @@ import { Sidebar } from "@/components/layout/sidebar"; import { WelcomeView } from "@/components/views/welcome-view"; import { BoardView } from "@/components/views/board-view"; 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 { AgentToolsView } from "@/components/views/agent-tools-view"; @@ -65,8 +64,6 @@ export default function Home() { return ; case "spec": return ; - case "code": - return ; case "agent": return ; case "settings": diff --git a/app/src/components/layout/sidebar.tsx b/app/src/components/layout/sidebar.tsx index df4ce5b4..237157b6 100644 --- a/app/src/components/layout/sidebar.tsx +++ b/app/src/components/layout/sidebar.tsx @@ -10,7 +10,6 @@ import { Settings, FileText, LayoutGrid, - Code, Bot, ChevronLeft, ChevronRight, @@ -69,7 +68,6 @@ export function Sidebar() { items: [ { id: "spec", label: "Spec Editor", icon: FileText }, { id: "context", label: "Context", icon: BookOpen }, - { id: "code", label: "Code View", icon: Code }, { id: "tools", label: "Agent Tools", icon: Wrench }, ], }, diff --git a/app/src/components/views/code-view.tsx b/app/src/components/views/code-view.tsx deleted file mode 100644 index fcbb74b8..00000000 --- a/app/src/components/views/code-view.tsx +++ /dev/null @@ -1,301 +0,0 @@ -"use client"; - -import { useEffect, useState, useCallback } from "react"; -import { useAppStore } from "@/store/app-store"; -import { getElectronAPI } from "@/lib/electron"; -import { Card, CardContent } from "@/components/ui/card"; -import { Button } from "@/components/ui/button"; -import { - File, - Folder, - FolderOpen, - ChevronRight, - ChevronDown, - RefreshCw, - Code, -} from "lucide-react"; -import { cn } from "@/lib/utils"; - -interface FileTreeNode { - name: string; - path: string; - isDirectory: boolean; - children?: FileTreeNode[]; - isExpanded?: boolean; -} - -const IGNORE_PATTERNS = [ - "node_modules", - ".git", - ".next", - "dist", - "build", - ".DS_Store", - "*.log", -]; - -const shouldIgnore = (name: string) => { - return IGNORE_PATTERNS.some((pattern) => { - if (pattern.startsWith("*")) { - return name.endsWith(pattern.slice(1)); - } - return name === pattern; - }); -}; - -export function CodeView() { - const { currentProject } = useAppStore(); - const [fileTree, setFileTree] = useState([]); - const [selectedFile, setSelectedFile] = useState(null); - const [fileContent, setFileContent] = useState(""); - const [isLoading, setIsLoading] = useState(true); - const [expandedFolders, setExpandedFolders] = useState>( - new Set() - ); - - // Load directory tree - const loadTree = useCallback(async () => { - if (!currentProject) return; - - setIsLoading(true); - try { - const api = getElectronAPI(); - const result = await api.readdir(currentProject.path); - - if (result.success && result.entries) { - const entries = result.entries - .filter((e) => !shouldIgnore(e.name)) - .sort((a, b) => { - // Directories first - if (a.isDirectory && !b.isDirectory) return -1; - if (!a.isDirectory && b.isDirectory) return 1; - return a.name.localeCompare(b.name); - }) - .map((e) => ({ - name: e.name, - path: `${currentProject.path}/${e.name}`, - isDirectory: e.isDirectory, - })); - - setFileTree(entries); - } - } catch (error) { - console.error("Failed to load file tree:", error); - } finally { - setIsLoading(false); - } - }, [currentProject]); - - useEffect(() => { - loadTree(); - }, [loadTree]); - - // Load subdirectory - const loadSubdirectory = async (path: string): Promise => { - try { - const api = getElectronAPI(); - const result = await api.readdir(path); - - if (result.success && result.entries) { - return result.entries - .filter((e) => !shouldIgnore(e.name)) - .sort((a, b) => { - if (a.isDirectory && !b.isDirectory) return -1; - if (!a.isDirectory && b.isDirectory) return 1; - return a.name.localeCompare(b.name); - }) - .map((e) => ({ - name: e.name, - path: `${path}/${e.name}`, - isDirectory: e.isDirectory, - })); - } - } catch (error) { - console.error("Failed to load subdirectory:", error); - } - return []; - }; - - // Load file content - const loadFileContent = async (path: string) => { - try { - const api = getElectronAPI(); - const result = await api.readFile(path); - - if (result.success && result.content) { - setFileContent(result.content); - setSelectedFile(path); - } - } catch (error) { - console.error("Failed to load file:", error); - } - }; - - // Toggle folder expansion - const toggleFolder = async (node: FileTreeNode) => { - const newExpanded = new Set(expandedFolders); - - if (expandedFolders.has(node.path)) { - newExpanded.delete(node.path); - } else { - newExpanded.add(node.path); - - // Load children if not already loaded - if (!node.children) { - const children = await loadSubdirectory(node.path); - // Update the tree with children - const updateTree = (nodes: FileTreeNode[]): FileTreeNode[] => { - return nodes.map((n) => { - if (n.path === node.path) { - return { ...n, children }; - } - if (n.children) { - return { ...n, children: updateTree(n.children) }; - } - return n; - }); - }; - setFileTree(updateTree(fileTree)); - } - } - - setExpandedFolders(newExpanded); - }; - - // Render file tree node - const renderNode = (node: FileTreeNode, depth: number = 0) => { - const isExpanded = expandedFolders.has(node.path); - const isSelected = selectedFile === node.path; - - return ( -
-
{ - if (node.isDirectory) { - toggleFolder(node); - } else { - loadFileContent(node.path); - } - }} - data-testid={`file-tree-item-${node.name}`} - > - {node.isDirectory ? ( - <> - {isExpanded ? ( - - ) : ( - - )} - {isExpanded ? ( - - ) : ( - - )} - - ) : ( - <> - - - - )} - {node.name} -
- {node.isDirectory && isExpanded && node.children && ( -
- {node.children.map((child) => renderNode(child, depth + 1))} -
- )} -
- ); - }; - - if (!currentProject) { - return ( -
-

No project selected

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

Code Explorer

-

- {currentProject.name} -

-
-
- -
- - {/* Split View */} -
- {/* File Tree */} -
-
{fileTree.map((node) => renderNode(node))}
-
- - {/* Code Preview */} -
- {selectedFile ? ( -
-
-

- {selectedFile.replace(currentProject.path, "")} -

-
- - -
-                    {fileContent}
-                  
-
-
-
- ) : ( -
-

- Select a file to view its contents -

-
- )} -
-
-
- ); -}