fix(chats): align folders and session actions
Render managed Chats through the shared folder-aware session group and keep folder ownership at the Chats root, including new drafts and older per-directory scopes. Hide worktree actions for Chats, make worktree shortcuts inert on Chat drafts, and let new-session shortcuts inherit an active session directory while explicit Chats controls still create managed Chat drafts.
This commit is contained in:
@@ -2062,7 +2062,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
<DropdownMenuItem onClick={() => void shareCurrentSession()}><Icon name="share-2" className="mr-2 size-4" />{t('sessions.sidebar.session.menu.share')}</DropdownMenuItem>
|
<DropdownMenuItem onClick={() => void shareCurrentSession()}><Icon name="share-2" className="mr-2 size-4" />{t('sessions.sidebar.session.menu.share')}</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
<DropdownMenuItem onClick={() => void exportCurrentSession()}><Icon name="download" className="mr-2 size-4" />{t('sessions.sidebar.session.menu.exportMarkdown')}</DropdownMenuItem>
|
<DropdownMenuItem onClick={() => void exportCurrentSession()}><Icon name="download" className="mr-2 size-4" />{t('sessions.sidebar.session.menu.exportMarkdown')}</DropdownMenuItem>
|
||||||
{!isVSCode && currentSession && !currentSession.parentId ? (
|
{!isVSCode && !isChatContext && currentSession && !currentSession.parentId ? (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span className="block">
|
<span className="block">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { isChatDirectoryForHome, isChatDirectoryPath } from '@/lib/chatDirectories';
|
import { getChatsRootForHome, getChatsRootFromDirectory, isChatDirectoryForHome, isChatDirectoryPath } from '@/lib/chatDirectories';
|
||||||
import { mergeSidebarSessionSources } from './sidebar/sidebarSessionSources';
|
import { mergeSidebarSessionSources } from './sidebar/sidebarSessionSources';
|
||||||
import type { Session } from '@opencode-ai/sdk/v2';
|
import type { Session } from '@opencode-ai/sdk/v2';
|
||||||
import { toast } from '@/components/ui';
|
import { toast } from '@/components/ui';
|
||||||
@@ -41,7 +41,7 @@ import { UpdateDialog } from '@/components/ui/UpdateDialog';
|
|||||||
import { SessionGroupSection } from './sidebar/SessionGroupSection';
|
import { SessionGroupSection } from './sidebar/SessionGroupSection';
|
||||||
import { SidebarHeader } from './sidebar/SidebarHeader';
|
import { SidebarHeader } from './sidebar/SidebarHeader';
|
||||||
import { SidebarNav } from './sidebar/SidebarNav';
|
import { SidebarNav } from './sidebar/SidebarNav';
|
||||||
import { SidebarActivitySections } from './sidebar/SidebarActivitySections';
|
import { SidebarActivitySections, type ActivityItem } from './sidebar/SidebarActivitySections';
|
||||||
import { SidebarFooter } from './sidebar/SidebarFooter';
|
import { SidebarFooter } from './sidebar/SidebarFooter';
|
||||||
import { SidebarProjectsList } from './sidebar/SidebarProjectsList';
|
import { SidebarProjectsList } from './sidebar/SidebarProjectsList';
|
||||||
import { SessionNodeItem } from './sidebar/SessionNodeItem';
|
import { SessionNodeItem } from './sidebar/SessionNodeItem';
|
||||||
@@ -1730,6 +1730,8 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
|||||||
normalizedSessionSearchQuery,
|
normalizedSessionSearchQuery,
|
||||||
groupSearchDataByGroup,
|
groupSearchDataByGroup,
|
||||||
visibleSessionCountByGroup,
|
visibleSessionCountByGroup,
|
||||||
|
isSingleProjectMode,
|
||||||
|
sessionGroupingMode,
|
||||||
collapsedGroups,
|
collapsedGroups,
|
||||||
hideDirectoryControls,
|
hideDirectoryControls,
|
||||||
collapsedFolderIds,
|
collapsedFolderIds,
|
||||||
@@ -1773,6 +1775,36 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
|||||||
openNewSessionDraft();
|
openNewSessionDraft();
|
||||||
}, [mobileVariant, openNewSessionDraft, setActiveMainTab, setSessionSwitcherOpen]);
|
}, [mobileVariant, openNewSessionDraft, setActiveMainTab, setSessionSwitcherOpen]);
|
||||||
|
|
||||||
|
const renderChatsSection = React.useCallback((items: ActivityItem[]) => {
|
||||||
|
const chatsRoot = getChatsRootForHome(homeDirectory)
|
||||||
|
?? items.map((item) => getChatsRootFromDirectory(item.node.session.directory)).find(Boolean)
|
||||||
|
?? null;
|
||||||
|
if (!chatsRoot) return items.map((item) => renderSessionNode(item.node, 0, item.groupDirectory));
|
||||||
|
|
||||||
|
const folderDirectories = [
|
||||||
|
chatsRoot,
|
||||||
|
...items.map((item) => normalizePath(item.node.session.directory ?? null)).filter((directory): directory is string => Boolean(directory)),
|
||||||
|
];
|
||||||
|
const folderScopes = Array.from(new Set(folderDirectories)).map((directory) => ({
|
||||||
|
scopeKey: directory,
|
||||||
|
directory,
|
||||||
|
}));
|
||||||
|
const group: SessionGroup = {
|
||||||
|
id: 'managed-chats',
|
||||||
|
label: '',
|
||||||
|
branch: null,
|
||||||
|
description: null,
|
||||||
|
isMain: true,
|
||||||
|
worktree: null,
|
||||||
|
directory: chatsRoot,
|
||||||
|
folderScopeKey: chatsRoot,
|
||||||
|
folderScopes,
|
||||||
|
draftTarget: 'chat',
|
||||||
|
sessions: items.map((item) => item.node),
|
||||||
|
};
|
||||||
|
return renderGroupSessions(group, 'managed-chats', null, true);
|
||||||
|
}, [homeDirectory, renderGroupSessions, renderSessionNode]);
|
||||||
|
|
||||||
const topContent = React.useMemo(
|
const topContent = React.useMemo(
|
||||||
() => (!isVSCode && !hasSessionSearchQuery && hasActivitySectionItems) ? (
|
() => (!isVSCode && !hasSessionSearchQuery && hasActivitySectionItems) ? (
|
||||||
<SidebarActivitySections
|
<SidebarActivitySections
|
||||||
@@ -1785,9 +1817,10 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
|||||||
isDesktopShellRuntime={isDesktopShellRuntime}
|
isDesktopShellRuntime={isDesktopShellRuntime}
|
||||||
onNewChat={handleOpenNewSessionDraftFromHeader}
|
onNewChat={handleOpenNewSessionDraftFromHeader}
|
||||||
alwaysShowActions={alwaysShowSidebarActions}
|
alwaysShowActions={alwaysShowSidebarActions}
|
||||||
|
renderChatsSection={renderChatsSection}
|
||||||
/>
|
/>
|
||||||
) : null,
|
) : null,
|
||||||
[activitySections, alwaysShowSidebarActions, editingId, handleOpenNewSessionDraftFromHeader, hasActivitySectionItems, hasSessionSearchQuery, isDesktopShellRuntime, isVSCode, openSidebarMenuKey, recentExpandedParents, renderSessionNode],
|
[activitySections, alwaysShowSidebarActions, editingId, handleOpenNewSessionDraftFromHeader, hasActivitySectionItems, hasSessionSearchQuery, isDesktopShellRuntime, isVSCode, openSidebarMenuKey, recentExpandedParents, renderChatsSection, renderSessionNode],
|
||||||
);
|
);
|
||||||
const isInlineEditing = Boolean(renamingFolderId || editingId || editingProjectDialogId);
|
const isInlineEditing = Boolean(renamingFolderId || editingId || editingProjectDialogId);
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,10 @@
|
|||||||
- Scheduled tasks (`ScheduledTasksDialog`, now a full-page surface on web/desktop) and per-project worktree management (`WorktreesView`, opened from the project menu) render as overlays inside `<main>` in `MainLayout`; the sidebar no longer mounts them.
|
- Scheduled tasks (`ScheduledTasksDialog`, now a full-page surface on web/desktop) and per-project worktree management (`WorktreesView`, opened from the project menu) render as overlays inside `<main>` in `MainLayout`; the sidebar no longer mounts them.
|
||||||
- Group-level PR-status polling/indicators and worktree-group drag-to-reorder were removed together with the worktree grouping level; `oc.sessions.groupOrder` is no longer read or written. Worktree PR/branch context lives in the Worktrees surface.
|
- Group-level PR-status polling/indicators and worktree-group drag-to-reorder were removed together with the worktree grouping level; `oc.sessions.groupOrder` is no longer read or written. Worktree PR/branch context lives in the Worktrees surface.
|
||||||
- Root session menus can quickly create a worktree from the session directory's current branch and move the full session subtree there while idle.
|
- Root session menus can quickly create a worktree from the session directory's current branch and move the full session subtree there while idle.
|
||||||
|
- Managed Chats never offer the worktree-move action in either the sidebar row menu or the active-session header menu because their directories are not project repositories.
|
||||||
|
- Managed Chats use the shared Chats root as their folder scope. Their activity section renders the normal folder tree, and sessions created from a Chats folder are assigned back to that root-scoped folder after their date/session directory materializes. Per-session folder scopes created by older builds remain visible for compatibility.
|
||||||
|
- The New session keyboard command inherits the active materialized session directory. Explicit sidebar entry points, including the top New session row and the Chats `+`, open a fresh managed Chat draft instead.
|
||||||
|
- The new-worktree keyboard command is a silent no-op while a managed Chat draft is open. It must not retarget that draft to the active project or show a Git/worktree error because Chats never participate in worktrees.
|
||||||
- Directory loading is demand-driven: the sidebar publishes one complete priority plan for all known project/worktree directories, while the sync layer owns bounded execution.
|
- Directory loading is demand-driven: the sidebar publishes one complete priority plan for all known project/worktree directories, while the sync layer owns bounded execution.
|
||||||
- When multiple configured projects are checkouts of the same Git repository, exactly one project owns the shared worktree topology: the configured canonical primary root when present, otherwise the first configured source for that repository. Any worktree path that is also a configured project is omitted from subordinate worktree groups, so every directory has one sidebar location while remaining part of bootstrap demand.
|
- When multiple configured projects are checkouts of the same Git repository, exactly one project owns the shared worktree topology: the configured canonical primary root when present, otherwise the first configured source for that repository. Any worktree path that is also a configured project is omitted from subordinate worktree groups, so every directory has one sidebar location while remaining part of bootstrap demand.
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ type Props = {
|
|||||||
setActiveProjectIdOnly: (id: string) => void;
|
setActiveProjectIdOnly: (id: string) => void;
|
||||||
setActiveMainTab: (tab: MainTab) => void;
|
setActiveMainTab: (tab: MainTab) => void;
|
||||||
setSessionSwitcherOpen: (open: boolean) => void;
|
setSessionSwitcherOpen: (open: boolean) => void;
|
||||||
openNewSessionDraft: (options?: { selectedProjectId?: string | null; directoryOverride?: string | null; targetFolderId?: string }) => void;
|
openNewSessionDraft: (options?: { selectedProjectId?: string | null; directoryOverride?: string | null; targetFolderId?: string; target?: 'chat' | 'project' }) => void;
|
||||||
addSessionToFolder: (scopeKey: string, folderId: string, sessionId: string) => void;
|
addSessionToFolder: (scopeKey: string, folderId: string, sessionId: string) => void;
|
||||||
createFolderAndStartRename: (scopeKey: string, parentId?: string | null) => { id: string } | null;
|
createFolderAndStartRename: (scopeKey: string, parentId?: string | null) => { id: string } | null;
|
||||||
renamingFolderId: string | null;
|
renamingFolderId: string | null;
|
||||||
@@ -881,7 +881,12 @@ function SessionGroupSectionBase(props: Props): React.ReactNode {
|
|||||||
if (projectId && projectId !== activeProjectId) setActiveProjectIdOnly(projectId);
|
if (projectId && projectId !== activeProjectId) setActiveProjectIdOnly(projectId);
|
||||||
setActiveMainTab('chat');
|
setActiveMainTab('chat');
|
||||||
if (mobileVariant) setSessionSwitcherOpen(false);
|
if (mobileVariant) setSessionSwitcherOpen(false);
|
||||||
openNewSessionDraft({ selectedProjectId: projectId, directoryOverride: scopeDirectory ?? group.directory, targetFolderId: folder.id });
|
openNewSessionDraft({
|
||||||
|
selectedProjectId: projectId,
|
||||||
|
directoryOverride: scopeDirectory ?? group.directory,
|
||||||
|
targetFolderId: folder.id,
|
||||||
|
target: group.draftTarget,
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
hideActions={false}
|
hideActions={false}
|
||||||
archivedBucket={group.isArchivedBucket === true}
|
archivedBucket={group.isArchivedBucket === true}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import { getSessionGoal } from '@/lib/sessionGoalMetadata';
|
|||||||
import { sessionGoalStatusColor, sessionGoalStatusLabelKey } from '@/lib/sessionGoalPresentation';
|
import { sessionGoalStatusColor, sessionGoalStatusLabelKey } from '@/lib/sessionGoalPresentation';
|
||||||
import { getRuntimeBearerTokenSync } from '@/lib/runtime-auth';
|
import { getRuntimeBearerTokenSync } from '@/lib/runtime-auth';
|
||||||
import { getRuntimeApiBaseUrl } from '@/lib/runtime-switch';
|
import { getRuntimeApiBaseUrl } from '@/lib/runtime-switch';
|
||||||
|
import { getChatsRootFromDirectory, isChatDirectoryPath } from '@/lib/chatDirectories';
|
||||||
import { parseMultiRunSessionTitle } from '@/lib/multirun/title';
|
import { parseMultiRunSessionTitle } from '@/lib/multirun/title';
|
||||||
import { MultiRunFusionDialog } from '@/components/multirun/MultiRunFusionDialog';
|
import { MultiRunFusionDialog } from '@/components/multirun/MultiRunFusionDialog';
|
||||||
import { FusionIcon } from '@/components/icons/FusionIcon';
|
import { FusionIcon } from '@/components/icons/FusionIcon';
|
||||||
@@ -957,7 +958,7 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
|
|||||||
<Icon name="download" className="mr-1 h-4 w-4" />
|
<Icon name="download" className="mr-1 h-4 w-4" />
|
||||||
{t('sessions.sidebar.session.menu.exportMarkdown')}
|
{t('sessions.sidebar.session.menu.exportMarkdown')}
|
||||||
</Item>
|
</Item>
|
||||||
{!isSubtaskSession && !archivedBucket && !isVSCode ? (
|
{!isSubtaskSession && !archivedBucket && !isVSCode && !isChatDirectoryPath(sessionDirectory) ? (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<span className="block">
|
<span className="block">
|
||||||
@@ -1015,6 +1016,7 @@ function SessionNodeItemComponent(props: Props): React.ReactNode {
|
|||||||
.forEach((worktree) => pushScope(worktree.path));
|
.forEach((worktree) => pushScope(worktree.path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pushScope(getChatsRootFromDirectory(sessionDirectory));
|
||||||
pushScope(sessionDirectory);
|
pushScope(sessionDirectory);
|
||||||
const folderEntries = scopes.flatMap((scope) =>
|
const folderEntries = scopes.flatMap((scope) =>
|
||||||
getFoldersForScope(scope).map((folder) => ({ scope, folder })));
|
getFoldersForScope(scope).map((folder) => ({ scope, folder })));
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {
|
|||||||
import type { SessionNodeRenderExtras } from './sessionNodeItemUtils';
|
import type { SessionNodeRenderExtras } from './sessionNodeItemUtils';
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
||||||
|
|
||||||
type ActivityItem = {
|
export type ActivityItem = {
|
||||||
node: SessionNode;
|
node: SessionNode;
|
||||||
projectId: string | null;
|
projectId: string | null;
|
||||||
groupDirectory: string | null;
|
groupDirectory: string | null;
|
||||||
@@ -49,6 +49,7 @@ type Props = {
|
|||||||
isDesktopShellRuntime: boolean;
|
isDesktopShellRuntime: boolean;
|
||||||
onNewChat?: () => void;
|
onNewChat?: () => void;
|
||||||
alwaysShowActions?: boolean;
|
alwaysShowActions?: boolean;
|
||||||
|
renderChatsSection?: (items: ActivityItem[]) => React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
type RenderExtras = SessionNodeRenderExtras;
|
type RenderExtras = SessionNodeRenderExtras;
|
||||||
@@ -151,7 +152,8 @@ export function SidebarActivitySections(props: Props): React.ReactNode {
|
|||||||
);
|
);
|
||||||
const visibleItems = section.items.slice(0, visibleLimit);
|
const visibleItems = section.items.slice(0, visibleLimit);
|
||||||
const remainingCount = section.items.length - visibleItems.length;
|
const remainingCount = section.items.length - visibleItems.length;
|
||||||
const canShowFewer = !flatVariant && section.items.length > initialVisibleCount && remainingCount === 0;
|
const usesCustomRenderer = section.key === 'chats' && Boolean(props.renderChatsSection);
|
||||||
|
const canShowFewer = !usesCustomRenderer && !flatVariant && section.items.length > initialVisibleCount && remainingCount === 0;
|
||||||
const getRenderExtras = buildRenderExtras(visibleItems.map((item) => item.node));
|
const getRenderExtras = buildRenderExtras(visibleItems.map((item) => item.node));
|
||||||
const renderItem = (item: ActivityItem) => renderSessionNode(
|
const renderItem = (item: ActivityItem) => renderSessionNode(
|
||||||
item.node,
|
item.node,
|
||||||
@@ -240,8 +242,10 @@ export function SidebarActivitySections(props: Props): React.ReactNode {
|
|||||||
</div>
|
</div>
|
||||||
{!isCollapsed ? (
|
{!isCollapsed ? (
|
||||||
<div className={cn('space-y-0.5')}>
|
<div className={cn('space-y-0.5')}>
|
||||||
{visibleItems.map(renderItem)}
|
{section.key === 'chats' && props.renderChatsSection
|
||||||
{remainingCount > 0 ? (
|
? props.renderChatsSection(section.items)
|
||||||
|
: visibleItems.map(renderItem)}
|
||||||
|
{!usesCustomRenderer && remainingCount > 0 ? (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => showMoreSessions(section.key, visibleItems.length, section.items.length)}
|
onClick={() => showMoreSessions(section.key, visibleItems.length, section.items.length)}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ export type SessionGroup = {
|
|||||||
* instead of reading the single folderScopeKey.
|
* instead of reading the single folderScopeKey.
|
||||||
*/
|
*/
|
||||||
folderScopes?: SessionGroupFolderScope[];
|
folderScopes?: SessionGroupFolderScope[];
|
||||||
|
draftTarget?: 'chat' | 'project';
|
||||||
sessions: SessionNode[];
|
sessions: SessionNode[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -316,7 +316,9 @@ export const useKeyboardShortcuts = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
openNewSessionDraft();
|
openNewSessionDraft(currentSessionId && currentDirectory
|
||||||
|
? { directoryOverride: currentDirectory }
|
||||||
|
: undefined);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -193,7 +193,13 @@ export const useMenuActions = (
|
|||||||
case 'new-session':
|
case 'new-session':
|
||||||
setActiveMainTab('chat');
|
setActiveMainTab('chat');
|
||||||
setSessionSwitcherOpen(false);
|
setSessionSwitcherOpen(false);
|
||||||
openNewSessionDraft();
|
{
|
||||||
|
const sessionState = useSessionUIStore.getState();
|
||||||
|
const directory = useDirectoryStore.getState().currentDirectory;
|
||||||
|
openNewSessionDraft(sessionState.currentSessionId && directory
|
||||||
|
? { directoryOverride: directory }
|
||||||
|
: undefined);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'new-worktree-session':
|
case 'new-worktree-session':
|
||||||
|
|||||||
@@ -34,7 +34,10 @@ export const useMiniChatKeyboardShortcuts = () => {
|
|||||||
|
|
||||||
if (eventMatchesShortcut(event, combo('new_chat'))) {
|
if (eventMatchesShortcut(event, combo('new_chat'))) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
openNewSessionDraft();
|
const sessionState = useSessionUIStore.getState();
|
||||||
|
openNewSessionDraft(sessionState.currentSessionId && sessionState.currentSessionDirectory
|
||||||
|
? { directoryOverride: sessionState.currentSessionDirectory }
|
||||||
|
: undefined);
|
||||||
focusChatInput();
|
focusChatInput();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,11 @@ const createInstantWorktreeDraft = async (options?: {
|
|||||||
initialPrompt?: string;
|
initialPrompt?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
}): Promise<string | null> => {
|
}): Promise<string | null> => {
|
||||||
|
const currentDraft = useSessionUIStore.getState().newSessionDraft;
|
||||||
|
if (currentDraft.open && currentDraft.target === 'chat') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (isCreatingWorktreeSession) {
|
if (isCreatingWorktreeSession) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import { useSkillsStore } from "@/stores/useSkillsStore"
|
|||||||
import { getDeferredSafeStorage } from "@/stores/utils/safeStorage"
|
import { getDeferredSafeStorage } from "@/stores/utils/safeStorage"
|
||||||
import { markPendingUserSendAnimation } from "@/lib/userSendAnimation"
|
import { markPendingUserSendAnimation } from "@/lib/userSendAnimation"
|
||||||
import { normalizePath } from "@/lib/pathNormalization"
|
import { normalizePath } from "@/lib/pathNormalization"
|
||||||
import { CHAT_DRAFT_PROJECT_ID, createChatDirectory, deleteChatDirectory, warmChatsRootDirectory } from "@/lib/chatDirectories"
|
import { CHAT_DRAFT_PROJECT_ID, createChatDirectory, deleteChatDirectory, getChatsRootFromDirectory, warmChatsRootDirectory } from "@/lib/chatDirectories"
|
||||||
import { isVSCodeRuntime } from "@/lib/desktop"
|
import { isVSCodeRuntime } from "@/lib/desktop"
|
||||||
import { flattenAssistantTextParts } from "@/lib/messages/messageText"
|
import { flattenAssistantTextParts } from "@/lib/messages/messageText"
|
||||||
import { composeForkSessionMessage } from "@/lib/messages/executionMeta"
|
import { composeForkSessionMessage } from "@/lib/messages/executionMeta"
|
||||||
@@ -1677,7 +1677,8 @@ export const useSessionUIStore = create<SessionUIState>()((set, get) => ({
|
|||||||
get().closeNewSessionDraft()
|
get().closeNewSessionDraft()
|
||||||
|
|
||||||
if (targetFolderId) {
|
if (targetFolderId) {
|
||||||
const scopeKey = dir || get().lastLoadedDirectory || session.directory
|
const scopeDirectory = dir || get().lastLoadedDirectory || session.directory
|
||||||
|
const scopeKey = getChatsRootFromDirectory(scopeDirectory) ?? scopeDirectory
|
||||||
if (scopeKey) {
|
if (scopeKey) {
|
||||||
useSessionFoldersStore.getState().addSessionToFolder(scopeKey, targetFolderId, session.id)
|
useSessionFoldersStore.getState().addSessionToFolder(scopeKey, targetFolderId, session.id)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user