fix: require valid project directory for session creation

- Backend: POST /api/chat/sessions now validates working_directory
  exists (400 MISSING_DIRECTORY / INVALID_DIRECTORY)
- db.ts: remove process.cwd() fallback in createSession
- ChatListPanel: validate last-working-directory before use,
  open FolderPicker when invalid; add SSR guard for localStorage
- NewChatPage: block sending without a project directory selected

Bump version to 0.10.5.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7418andClaude Opus 4.6 committed 2026-02-13 15:37:51 +08:00
1 parent ae8a905581
commit 916b8889b7
6 files changed
+63 -12

No files matched your search

+23 -4
View File
@@ -53,6 +53,7 @@ function formatRelativeTime(dateStr: string): string {
const COLLAPSED_PROJECTS_KEY = "codepilot:collapsed-projects";
function loadCollapsedProjects(): Set<string> {
if (typeof window === 'undefined') return new Set();
try {
const raw = localStorage.getItem(COLLAPSED_PROJECTS_KEY);
if (raw) return new Set(JSON.parse(raw));
@@ -129,27 +130,45 @@ export function ChatListPanel({ open, width }: ChatListPanelProps) {
const [creatingChat, setCreatingChat] = useState(false);
const handleNewChat = useCallback(async () => {
const lastDir = localStorage.getItem("codepilot:last-working-directory");
const lastDir = typeof window !== 'undefined'
? localStorage.getItem("codepilot:last-working-directory")
: null;
if (!lastDir) {
router.push("/chat");
// No saved directory — let user pick one
setFolderPickerOpen(true);
return;
}
// Validate the saved directory still exists
setCreatingChat(true);
try {
const checkRes = await fetch(
`/api/files/browse?dir=${encodeURIComponent(lastDir)}`
);
if (!checkRes.ok) {
// Directory is gone — clear stale value and prompt user
localStorage.removeItem("codepilot:last-working-directory");
setFolderPickerOpen(true);
return;
}
const res = await fetch("/api/chat/sessions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ working_directory: lastDir }),
});
if (!res.ok) {
router.push("/chat");
// Backend rejected it (e.g. INVALID_DIRECTORY) — prompt user
localStorage.removeItem("codepilot:last-working-directory");
setFolderPickerOpen(true);
return;
}
const data = await res.json();
router.push(`/chat/${data.session.id}`);
window.dispatchEvent(new CustomEvent("session-created"));
} catch {
router.push("/chat");
setFolderPickerOpen(true);
} finally {
setCreatingChat(false);
}