feat(chats): add managed projectless chat sessions
Create projectless chat sessions under a managed, date-scoped Chats directory and clean abandoned or deleted session folders. Add Chats to sidebar state, startup cache, shared context, and Electron Mini Chat while keeping VS Code project-only. Resolve managed chat directories to one server-side memory owner and document the runtime contracts.
This commit is contained in:
@@ -22,6 +22,8 @@ import { useSessionUIStore } from '@/sync/session-ui-store';
|
||||
import { useSessionWorktreeStore } from '@/sync/session-worktree-store';
|
||||
import { formatSessionWorktreeBadge } from '@/sync/session-worktree-contract';
|
||||
import { buildSessionMessageRecordsSnapshot, useDirectoryStore, useGlobalSessionStatus, useSessionMessagesResolved } from '@/sync/sync-context';
|
||||
import { useDirectoryStore as useAppDirectoryStore } from '@/stores/useDirectoryStore';
|
||||
import { isChatDirectoryForHome } from '@/lib/chatDirectories';
|
||||
import { useSync } from '@/sync/use-sync';
|
||||
import { useProjectsStore } from '@/stores/useProjectsStore';
|
||||
import { useQuotaAutoRefresh, useQuotaStore } from '@/stores/useQuotaStore';
|
||||
@@ -1052,6 +1054,10 @@ export const Header: React.FC<HeaderProps> = ({
|
||||
}
|
||||
return normalize(state.newSessionDraft.bootstrapPendingDirectory ?? state.newSessionDraft.directoryOverride ?? '');
|
||||
});
|
||||
const draftTarget = useSessionUIStore((state) => state.newSessionDraft.target);
|
||||
const draftProjectId = useSessionUIStore((state) => state.newSessionDraft.selectedProjectId);
|
||||
const selectedSessionDirectory = useSessionUIStore((state) => state.currentSessionDirectory);
|
||||
const homeDirectory = useAppDirectoryStore((state) => state.homeDirectory);
|
||||
|
||||
const openDirectory = React.useMemo(() => {
|
||||
return worktreeDirectory || sessionDirectory || draftDirectory;
|
||||
@@ -1080,10 +1086,13 @@ export const Header: React.FC<HeaderProps> = ({
|
||||
|
||||
const gitBranchForDirectory = useGitBranchLabel(openDirectory || null);
|
||||
const currentBranchLabel = gitBranchForDirectory || currentSessionWorktreeBranch || catalogWorktreeBranch;
|
||||
const isChatContext = isNewSessionDraftOpen
|
||||
? draftTarget === 'chat'
|
||||
: isChatDirectoryForHome(sessionDirectory || selectedSessionDirectory, homeDirectory);
|
||||
|
||||
// Whether the title carries a second line under it. Hoisted because the
|
||||
// session menu's vertical alignment depends on the same answer.
|
||||
const showHeaderMetaRow = !workStatusPanelVisible
|
||||
const showHeaderMetaRow = !isChatContext && !workStatusPanelVisible
|
||||
&& Boolean(activeProjectLabel || currentBranchLabel || (!isNewSessionDraftOpen && worktreeBadgeKind));
|
||||
|
||||
|
||||
@@ -1423,14 +1432,14 @@ export const Header: React.FC<HeaderProps> = ({
|
||||
|
||||
const handleOpenDraftMiniChat = React.useCallback(() => {
|
||||
void invokeDesktop('desktop_open_draft_mini_chat_window', {
|
||||
directory: normalize(openDirectory || activeProject?.path || ''),
|
||||
projectId: activeProject?.id ?? null,
|
||||
directory: isChatContext ? '' : draftDirectory,
|
||||
projectId: isChatContext ? null : draftProjectId,
|
||||
apiBaseUrl: getRuntimeApiBaseUrl(),
|
||||
clientToken: getRuntimeBearerTokenSync(),
|
||||
}).catch((error) => {
|
||||
console.warn('[header] failed to open draft mini chat window', error);
|
||||
});
|
||||
}, [activeProject?.id, activeProject?.path, openDirectory]);
|
||||
}, [draftDirectory, draftProjectId, isChatContext]);
|
||||
|
||||
const handleOpenCurrentMiniChat = React.useCallback(() => {
|
||||
if (isNewSessionDraftOpen) {
|
||||
@@ -1443,13 +1452,13 @@ export const Header: React.FC<HeaderProps> = ({
|
||||
}
|
||||
void invokeDesktop('desktop_open_session_mini_chat_window', {
|
||||
sessionId: currentSessionId,
|
||||
directory: normalize(openDirectory || activeProject?.path || ''),
|
||||
directory: sessionDirectory || normalize(selectedSessionDirectory || '') || worktreeDirectory,
|
||||
apiBaseUrl: getRuntimeApiBaseUrl(),
|
||||
clientToken: getRuntimeBearerTokenSync(),
|
||||
}).catch((error) => {
|
||||
console.warn('[header] failed to open session mini chat window', error);
|
||||
});
|
||||
}, [activeProject?.path, currentSessionId, handleOpenDraftMiniChat, isNewSessionDraftOpen, openDirectory]);
|
||||
}, [currentSessionId, handleOpenDraftMiniChat, isNewSessionDraftOpen, selectedSessionDirectory, sessionDirectory, worktreeDirectory]);
|
||||
|
||||
const handleOpenContextPanel = React.useCallback(() => {
|
||||
const directory = normalize(openDirectory || '');
|
||||
|
||||
Reference in New Issue
Block a user