import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode, } from 'react'; import type { DaemonClient } from '@qwen-code/sdk/daemon'; import type { DaemonSessionGroup, DaemonSessionSummary, DaemonWorkspaceCapability, DaemonWorkspaceGitStatus, } from '@qwen-code/sdk/daemon'; import { FolderClosedIcon, FolderOpenIcon } from 'lucide-react'; import { GitBranchIndicator } from '../GitBranchIndicator'; import { BranchPickerPopover } from '../BranchPickerPopover'; import { useI18n } from '../../i18n'; import { SESSION_LIST_PAGE_SIZE } from '../../constants/sessions'; import { readWorkspaceCollapsedGroupIds, writeWorkspaceCollapsedGroupIds, } from './collapsedSessionSections'; import { workspaceLabel } from '../../utils/workspace'; import { SessionGroupSection } from './SessionGroupSection'; import styles from './WorkspaceSection.module.css'; function cx(...classes: Array): string { return classes.filter(Boolean).join(' '); } // The cwd-qualified daemon route only accepts a workspace id or absolute path. // A synthetic fallback workspace (daemon reports no workspaces and the // connection has no cwd) carries a display name in `cwd`, which is neither, so // qualifying a request with it would only ever 400. function isAbsolutePath(cwd: string): boolean { return ( cwd.startsWith('/') || cwd.startsWith('\\') || /^[a-zA-Z]:[\\/]/.test(cwd) ); } function getSessionLabel(session: DaemonSessionSummary): string { const displayName = session.displayName?.trim(); return displayName || session.sessionId.slice(0, 8); } function WorkspaceFolderIcon({ open }: { open: boolean }) { const Icon = open ? FolderOpenIcon : FolderClosedIcon; return (