Merge branch 'main' into feature/shared-packages

This commit is contained in:
Test User
2025-12-20 23:55:03 -05:00
76 changed files with 1898 additions and 893 deletions

View File

@@ -191,7 +191,9 @@ export function WorktreeTab({
)}
onClick={() => onSelectWorktree(worktree)}
disabled={isActivating}
title="Click to preview main"
title={`Click to preview ${worktree.branch}`}
aria-label={worktree.branch}
data-testid={`worktree-branch-${worktree.branch}`}
>
{isRunning && <Loader2 className="w-3 h-3 animate-spin" />}
{isActivating && !isRunning && (

View File

@@ -8,6 +8,7 @@ import {
PanelLeftClose,
} from "lucide-react";
import { cn, pathsEqual } from "@/lib/utils";
import { getItem, setItem } from "@/lib/storage";
import type { WorktreePanelProps, WorktreeInfo } from "./types";
import {
useWorktrees,
@@ -91,13 +92,12 @@ export function WorktreePanel({
// Collapse state with localStorage persistence
const [isCollapsed, setIsCollapsed] = useState(() => {
if (typeof window === "undefined") return false;
const saved = localStorage.getItem(WORKTREE_PANEL_COLLAPSED_KEY);
const saved = getItem(WORKTREE_PANEL_COLLAPSED_KEY);
return saved === "true";
});
useEffect(() => {
localStorage.setItem(WORKTREE_PANEL_COLLAPSED_KEY, String(isCollapsed));
setItem(WORKTREE_PANEL_COLLAPSED_KEY, String(isCollapsed));
}, [isCollapsed]);
const toggleCollapsed = () => setIsCollapsed((prev) => !prev);

View File

@@ -1,4 +1,3 @@
import { useState, useCallback, useRef, useEffect } from "react";
import { useAppStore, Feature } from "@/store/app-store";
import { Card, CardContent } from "@/components/ui/card";
@@ -20,6 +19,10 @@ import { Markdown } from "@/components/ui/markdown";
import { useFileBrowser } from "@/contexts/file-browser-context";
import { toast } from "sonner";
import { useNavigate } from "@tanstack/react-router";
import {
getDefaultWorkspaceDirectory,
saveLastProjectDirectory,
} from "@/lib/workspace-config";
interface InterviewMessage {
id: string;
@@ -65,8 +68,7 @@ const INTERVIEW_QUESTIONS = [
];
export function InterviewView() {
const { addProject, setCurrentProject, setAppSpec } =
useAppStore();
const { addProject, setCurrentProject, setAppSpec } = useAppStore();
const { openFileBrowser } = useFileBrowser();
const navigate = useNavigate();
const [input, setInput] = useState("");
@@ -89,6 +91,35 @@ export function InterviewView() {
const messagesContainerRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
// Default parent directory using workspace config utility
useEffect(() => {
if (projectPath) return;
let isMounted = true;
const loadWorkspaceDir = async () => {
try {
const defaultDir = await getDefaultWorkspaceDirectory();
if (!isMounted || projectPath) {
return;
}
if (defaultDir) {
setProjectPath(defaultDir);
}
} catch (error) {
console.error("Failed to load default workspace directory:", error);
}
};
loadWorkspaceDir();
return () => {
isMounted = false;
};
}, [projectPath]);
// Initialize with first question
useEffect(() => {
if (messages.length === 0) {
@@ -295,10 +326,12 @@ export function InterviewView() {
title: "Select Base Directory",
description:
"Choose the parent directory where your new project will be created",
initialPath: projectPath || undefined,
});
if (selectedPath) {
setProjectPath(selectedPath);
saveLastProjectDirectory(selectedPath);
}
};
@@ -308,6 +341,7 @@ export function InterviewView() {
setIsGenerating(true);
try {
saveLastProjectDirectory(projectPath);
const api = getElectronAPI();
// Use platform-specific path separator
const pathSep =
@@ -423,8 +457,8 @@ export function InterviewView() {
index < currentQuestionIndex
? "bg-green-500"
: index === currentQuestionIndex
? "bg-primary"
: "bg-zinc-700"
? "bg-primary"
: "bg-zinc-700"
)}
/>
))}

View File

@@ -239,6 +239,24 @@ export function WelcomeView() {
const api = getElectronAPI();
const projectPath = `${parentDir}/${projectName}`;
// Validate that parent directory exists
const parentExists = await api.exists(parentDir);
if (!parentExists) {
toast.error("Parent directory does not exist", {
description: `Cannot create project in non-existent directory: ${parentDir}`,
});
return;
}
// Verify parent is actually a directory
const parentStat = await api.stat(parentDir);
if (parentStat && !parentStat.isDirectory) {
toast.error("Parent path is not a directory", {
description: `${parentDir} is not a directory`,
});
return;
}
// Create project directory
const mkdirResult = await api.mkdir(projectPath);
if (!mkdirResult.success) {