diff --git a/packages/ui/src/components/layout/RightSidebarTabs.tsx b/packages/ui/src/components/layout/RightSidebarTabs.tsx
index cc25c247..f636fd3b 100644
--- a/packages/ui/src/components/layout/RightSidebarTabs.tsx
+++ b/packages/ui/src/components/layout/RightSidebarTabs.tsx
@@ -1,15 +1,19 @@
import React from 'react';
-import { RiFolder3Line, RiGitBranchLine } from '@remixicon/react';
+import { RiBookletLine, RiFolder3Line, RiGitBranchLine } from '@remixicon/react';
import { SortableTabsStrip } from '@/components/ui/sortable-tabs-strip';
+import { ProjectNotesTodoPanel } from '@/components/session/ProjectNotesTodoPanel';
import { GitView } from '@/components/views';
-import { useUIStore } from '@/stores/useUIStore';
import { useGitStore } from '@/stores/useGitStore';
+import { useProjectsStore } from '@/stores/useProjectsStore';
+import { useDirectoryStore } from '@/stores/useDirectoryStore';
+import { useUIStore } from '@/stores/useUIStore';
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
import { useEffectiveDirectory } from '@/hooks/useEffectiveDirectory';
+import { formatDirectoryName } from '@/lib/utils';
import { SidebarFilesTree } from './SidebarFilesTree';
-type RightTab = 'git' | 'files';
+type RightTab = 'git' | 'files' | 'context';
/**
* Keeps git status fresh while the right sidebar is open.
@@ -35,6 +39,56 @@ function useRightSidebarGitSync(directory: string | undefined, isSidebarOpen: bo
}, [directory, git, isSidebarOpen, ensureStatus]);
}
+const ContextSidebarPanel: React.FC = () => {
+ const activeProjectId = useProjectsStore((state) => state.activeProjectId);
+ const projects = useProjectsStore((state) => state.projects);
+ const homeDirectory = useDirectoryStore((state) => state.homeDirectory);
+ const gitDirectories = useGitStore((state) => state.directories);
+
+ const activeProject = React.useMemo(() => {
+ if (activeProjectId) {
+ return projects.find((project) => project.id === activeProjectId) ?? projects[0] ?? null;
+ }
+ return projects[0] ?? null;
+ }, [activeProjectId, projects]);
+
+ const projectRef = React.useMemo(() => {
+ if (!activeProject) {
+ return null;
+ }
+ return {
+ id: activeProject.id,
+ path: activeProject.path,
+ };
+ }, [activeProject]);
+
+ const projectLabel = React.useMemo(() => {
+ if (!activeProject) {
+ return null;
+ }
+ return activeProject.label?.trim()
+ || formatDirectoryName(activeProject.path, homeDirectory)
+ || activeProject.path;
+ }, [activeProject, homeDirectory]);
+
+ const canCreateWorktree = React.useMemo(() => {
+ if (!activeProject) {
+ return false;
+ }
+ return gitDirectories.get(activeProject.path)?.isGitRepo === true;
+ }, [activeProject, gitDirectories]);
+
+ return (
+
+ );
+};
+
export const RightSidebarTabs: React.FC = () => {
const rightSidebarTab = useUIStore((state) => state.rightSidebarTab);
const setRightSidebarTab = useUIStore((state) => state.setRightSidebarTab);
@@ -54,6 +108,11 @@ export const RightSidebarTabs: React.FC = () => {
label: 'Files',
icon: ,
},
+ {
+ id: 'context',
+ label: 'Context',
+ icon: ,
+ },
], []);
return (
@@ -72,7 +131,8 @@ export const RightSidebarTabs: React.FC = () => {
{rightSidebarTab === 'git' && }
{rightSidebarTab === 'files' && }
+ {rightSidebarTab === 'context' && }
);
-};
\ No newline at end of file
+};
diff --git a/packages/ui/src/components/session/SessionSidebar.tsx b/packages/ui/src/components/session/SessionSidebar.tsx
index fcbbf19c..dc8deafd 100644
--- a/packages/ui/src/components/session/SessionSidebar.tsx
+++ b/packages/ui/src/components/session/SessionSidebar.tsx
@@ -4,7 +4,6 @@ import { RiLayoutLeftLine } from '@remixicon/react';
import { toast } from '@/components/ui';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { isDesktopLocalOriginActive, isDesktopShell, isTauriShell, startDesktopWindowDrag } from '@/lib/desktop';
-import { MobileOverlayPanel } from '@/components/ui/MobileOverlayPanel';
import { sessionEvents } from '@/lib/sessionEvents';
import { formatDirectoryName, cn } from '@/lib/utils';
import { useSessionUIStore } from '@/sync/session-ui-store';
@@ -16,11 +15,9 @@ import { useProjectsStore } from '@/stores/useProjectsStore';
import { useUIStore } from '@/stores/useUIStore';
import { getSafeStorage } from '@/stores/utils/safeStorage';
import { useGitStore, useGitAllBranches, useGitRepoStatusMap } from '@/stores/useGitStore';
-import { useDeviceInfo } from '@/lib/device';
import { isVSCodeRuntime } from '@/lib/desktop';
import { NewWorktreeDialog } from './NewWorktreeDialog';
import { ScheduledTasksDialog } from './ScheduledTasksDialog';
-import { ProjectNotesTodoPanel } from './ProjectNotesTodoPanel';
import { useSessionFoldersStore } from '@/stores/useSessionFoldersStore';
import { useDebouncedValue } from '@/hooks/useDebouncedValue';
import { useArchivedAutoFolders } from './sidebar/hooks/useArchivedAutoFolders';
@@ -142,7 +139,6 @@ export const SessionSidebar: React.FC = ({
const [expandedSessionGroups, setExpandedSessionGroups] = React.useState>(new Set());
const [newWorktreeDialogOpen, setNewWorktreeDialogOpen] = React.useState(false);
const [updateDialogOpen, setUpdateDialogOpen] = React.useState(false);
- const [projectNotesPanelOpen, setProjectNotesPanelOpen] = React.useState(false);
const [openSidebarMenuKey, setOpenSidebarMenuKey] = React.useState(null);
const [renamingFolderId, setRenamingFolderId] = React.useState(null);
const [renameFolderDraft, setRenameFolderDraft] = React.useState('');
@@ -230,7 +226,6 @@ export const SessionSidebar: React.FC = ({
const setSettingsDialogOpen = useUIStore((state) => state.setSettingsDialogOpen);
const toggleHelpDialog = useUIStore((state) => state.toggleHelpDialog);
const setAboutDialogOpen = useUIStore((state) => state.setAboutDialogOpen);
- const deviceInfo = useDeviceInfo();
const setSessionSwitcherOpen = useUIStore((state) => state.setSessionSwitcherOpen);
const setScheduledTasksDialogOpen = useUIStore((state) => state.setScheduledTasksDialogOpen);
const toggleSidebar = useUIStore((state) => state.toggleSidebar);
@@ -893,44 +888,7 @@ export const SessionSidebar: React.FC = ({
);
- const activeProjectForHeader = React.useMemo(
- () => normalizedProjects.find((project) => project.id === activeProjectId) ?? normalizedProjects[0] ?? null,
- [normalizedProjects, activeProjectId],
- );
- const activeProjectRefForHeader = React.useMemo(
- () => (activeProjectForHeader
- ? {
- id: activeProjectForHeader.id,
- path: activeProjectForHeader.normalizedPath,
- }
- : null),
- [activeProjectForHeader],
- );
- const activeProjectLabelForHeader = React.useMemo(
- () => (activeProjectForHeader
- ? activeProjectForHeader.label?.trim()
- || formatDirectoryName(activeProjectForHeader.normalizedPath, homeDirectory)
- || activeProjectForHeader.normalizedPath
- : null),
- [activeProjectForHeader, homeDirectory],
- );
-
- const activeProjectIsRepo = React.useMemo(
- () => (activeProjectForHeader ? Boolean(projectRepoStatus.get(activeProjectForHeader.id)) : false),
- [activeProjectForHeader, projectRepoStatus],
- );
- // Only flip to false once the new project's status is actually resolved (present in map)
- const stableActiveProjectIsRepo = activeProjectForHeader && projectRepoStatus.has(activeProjectForHeader.id)
- ? activeProjectIsRepo
- : lastRepoStatusRef.current;
const reserveHeaderActionsSpace = true;
- const useMobileNotesPanel = mobileVariant || deviceInfo.isMobile;
-
- React.useEffect(() => {
- if (!activeProjectForHeader) {
- setProjectNotesPanelOpen(false);
- }
- }, [activeProjectForHeader]);
const { currentSessionDirectory } = useProjectSessionSelection({
projectSections,
@@ -1479,14 +1437,8 @@ export const SessionSidebar: React.FC = ({
hideDirectoryControls={hideDirectoryControls}
handleOpenDirectoryDialog={handleOpenDirectoryDialog}
handleNewSession={handleSidebarNewSession}
- useMobileNotesPanel={useMobileNotesPanel}
- projectNotesPanelOpen={projectNotesPanelOpen}
- setProjectNotesPanelOpen={setProjectNotesPanelOpen}
- activeProjectRefForHeader={activeProjectRefForHeader}
- activeProjectLabelForHeader={activeProjectLabelForHeader}
canOpenMultiRun={projects.length > 0}
openMultiRunLauncher={handleOpenMultiRunFromHeader}
- stableActiveProjectIsRepo={stableActiveProjectIsRepo}
headerActionIconClass={headerActionIconClass}
reserveHeaderActionsSpace={reserveHeaderActionsSpace}
headerActionButtonClass={headerActionButtonClass}
@@ -1594,22 +1546,6 @@ export const SessionSidebar: React.FC = ({
- {useMobileNotesPanel ? (
- setProjectNotesPanelOpen(false)}
- title={activeProjectLabelForHeader ? `Project notes - ${activeProjectLabelForHeader}` : 'Project notes'}
- >
- setProjectNotesPanelOpen(false)}
- className="p-0"
- />
-
- ) : null}
-
void;
handleNewSession: () => void;
- useMobileNotesPanel: boolean;
- projectNotesPanelOpen: boolean;
- setProjectNotesPanelOpen: (open: boolean) => void;
- activeProjectRefForHeader: ProjectRef | null;
- activeProjectLabelForHeader: string | null;
canOpenMultiRun: boolean;
openMultiRunLauncher: () => void;
- stableActiveProjectIsRepo: boolean;
headerActionIconClass: string;
reserveHeaderActionsSpace: boolean;
headerActionButtonClass: string;
@@ -56,14 +47,8 @@ export function SidebarHeader(props: Props): React.ReactNode {
hideDirectoryControls,
handleOpenDirectoryDialog,
handleNewSession,
- useMobileNotesPanel,
- projectNotesPanelOpen,
- setProjectNotesPanelOpen,
- activeProjectRefForHeader,
- activeProjectLabelForHeader,
canOpenMultiRun,
openMultiRunLauncher,
- stableActiveProjectIsRepo,
headerActionIconClass,
reserveHeaderActionsSpace,
headerActionButtonClass,
@@ -150,49 +135,6 @@ export function SidebarHeader(props: Props): React.ReactNode {
Scheduled tasks
- {useMobileNotesPanel ? (
-
-
-
-
- Project notes
-
- ) : (
-
-
-
-
-
-
-
- Project notes
-
-
- setProjectNotesPanelOpen(false)}
- />
-
-
- )}
-