@tutti-os/workspace-file-manager 0.0.230 → 0.0.232

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1505,15 +1505,29 @@ var DefaultWorkspaceFileManagerSession = class {
1505
1505
  }
1506
1506
  async copyToClipboard(entry) {
1507
1507
  if (this.isExternalLocationSelected()) {
1508
- return;
1508
+ return false;
1509
1509
  }
1510
1510
  if (!this.host.copyEntriesToClipboard) {
1511
- return;
1511
+ return false;
1512
+ }
1513
+ try {
1514
+ await this.host.copyEntriesToClipboard({
1515
+ paths: [entry.path],
1516
+ workspaceID: this.store.workspaceID
1517
+ });
1518
+ return true;
1519
+ } catch (error) {
1520
+ const message = this.resolveErrorMessage(error);
1521
+ const handled = this.onMutationErrorMessage?.({
1522
+ actionKind: "copy",
1523
+ error,
1524
+ message
1525
+ });
1526
+ if (!handled) {
1527
+ this.store.error = message;
1528
+ }
1529
+ return false;
1512
1530
  }
1513
- await this.host.copyEntriesToClipboard({
1514
- paths: [entry.path],
1515
- workspaceID: this.store.workspaceID
1516
- });
1517
1531
  }
1518
1532
  getCachedOpenWithApplications(entry) {
1519
1533
  if (!this.host.listOpenWithApplications) {
@@ -2255,4 +2269,4 @@ export {
2255
2269
  sortWorkspaceFileEntriesForArrangeMode,
2256
2270
  resolveWorkspaceFileEntryArrangeDateMs
2257
2271
  };
2258
- //# sourceMappingURL=chunk-KCYTFKPY.js.map
2272
+ //# sourceMappingURL=chunk-GYODJICC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/services/workspaceFileManagerTypes.ts","../src/services/internal/model/paths.ts","../src/services/workspaceFileManagerLocations.ts","../src/services/internal/model/openWithApplicationsCache.ts","../src/services/internal/workspaceFileManagerStore.ts","../src/services/internal/model/fileKinds.ts","../src/services/internal/model/formatters.ts","../src/services/internal/model/searchEntries.ts","../src/services/internal/model/validation.ts","../src/services/internal/workspaceFileManagerSession.ts","../src/services/internal/workspaceFileManagerActivationController.ts","../src/services/internal/model/entryLookup.ts","../src/services/internal/workspaceFileManagerMutationController.ts","../src/services/internal/workspaceFileManagerNavigationController.ts","../src/services/internal/workspaceFileManagerPreviewController.ts","../src/services/internal/workspaceFileManagerTreeController.ts","../src/services/internal/workspaceFileManagerService.ts","../src/services/createWorkspaceFileManagerService.ts","../src/services/workspaceFileEntryIconPolicy.ts","../src/ui/workspaceFileManagerArrangeMode.ts"],"sourcesContent":["import type { WorkspaceFileManagerHostFallbackAction } from \"./workspaceFileManagerHostTypes.ts\";\nimport type {\n WorkspaceFilePreviewKind as SharedWorkspaceFilePreviewKind,\n WorkspaceFilePreviewTarget\n} from \"@tutti-os/workspace-file-preview\";\n\nexport const workspaceFileManagerLogicalRoot = \"/\" as const;\n\nexport type WorkspaceFileEntryKind = \"file\" | \"directory\" | \"unknown\";\nexport type WorkspaceFileSearchMatchTarget = \"basename\" | \"path\";\nexport type WorkspaceFilePreviewKind = SharedWorkspaceFilePreviewKind;\nexport type WorkspaceFileLocationKind = \"directory\" | \"external\" | \"recent\";\nexport type WorkspaceFileManagerFileDefaultOpener =\n | \"appBrowser\"\n | \"defaultBrowser\"\n | \"fileViewer\"\n | \"system\";\nexport const workspaceFileManagerPersistedStateSchemaVersion = 3 as const;\nexport const workspaceFileManagerPreviousPersistedStateSchemaVersion =\n 2 as const;\n\nexport interface WorkspaceFileEntry {\n hasChildren: boolean;\n kind: WorkspaceFileEntryKind;\n createdTimeMs?: number | null;\n lastOpenedMs?: number | null;\n mtimeMs: number | null;\n name: string;\n path: string;\n sizeBytes: number | null;\n}\n\n/**\n * File-manager activation payload. Reuses the shared preview target shape\n * (`previewKind`) so hosts can decide whether to open an in-app preview, while\n * open / reveal / open-with stay outside `@tutti-os/workspace-file-preview`.\n */\nexport interface WorkspaceFileActivationTarget extends WorkspaceFilePreviewTarget {\n mtimeMs: number | null;\n sizeBytes: number | null;\n}\n\nexport type WorkspaceFilePreviewState =\n | { status: \"empty\" }\n | { entry: WorkspaceFileEntry; status: \"directory\" }\n | {\n entry: WorkspaceFileActivationTarget;\n previewKind: WorkspaceFilePreviewKind;\n status: \"loading\";\n }\n | {\n content: string;\n entry: WorkspaceFileActivationTarget;\n previewKind: WorkspaceFilePreviewKind;\n status: \"text\";\n }\n | {\n entry: WorkspaceFileActivationTarget;\n objectUrl: string;\n previewKind: \"image\";\n status: \"image\";\n }\n | {\n entry: WorkspaceFileActivationTarget;\n objectUrl: string;\n previewKind: \"video\";\n status: \"video\";\n }\n | { entry: WorkspaceFileEntry; message: string; status: \"unsupported\" }\n | { entry: WorkspaceFileEntry; message: string; status: \"readonly\" }\n | { entry: WorkspaceFileEntry; message: string; status: \"error\" };\n\nexport interface WorkspaceFileDirectoryListing {\n directoryPath: string;\n entries: WorkspaceFileEntry[];\n root: string;\n workspaceID: string;\n}\n\nexport interface WorkspaceFileDirectoryExpansionState {\n entries: WorkspaceFileEntry[];\n error: string | null;\n isLoading: boolean;\n loaded: boolean;\n}\n\nexport interface WorkspaceFileSearchEntry {\n directoryPath: string;\n kind: WorkspaceFileEntryKind;\n matchIndices: number[];\n matchTarget: WorkspaceFileSearchMatchTarget;\n name: string;\n path: string;\n score: number;\n}\n\nexport interface WorkspaceFileSearchResult {\n entries: WorkspaceFileSearchEntry[];\n root: string;\n workspaceID: string;\n}\n\nexport interface WorkspaceFileLocationSection {\n id: string;\n label: string;\n locations: WorkspaceFileLocation[];\n}\n\nexport type WorkspaceFileLocation =\n | WorkspaceFileDirectoryLocation\n | WorkspaceFileExternalLocation\n | WorkspaceFileRecentLocation;\n\nexport interface WorkspaceFileDirectoryLocation {\n contextLabel?: string | null;\n id: string;\n kind: \"directory\";\n label: string;\n path: string;\n referenceNodeId: string;\n}\n\nexport interface WorkspaceFileExternalLocation {\n contextLabel?: string | null;\n externalType: string;\n iconUrl?: string | null;\n id: string;\n kind: \"external\";\n label: string;\n metadata: Record<string, string>;\n}\n\nexport interface WorkspaceFileRecentLocation {\n contextLabel?: string | null;\n id: string;\n kind: \"recent\";\n label: string;\n}\n\nexport interface WorkspaceFileManagerPersistedState {\n currentDirectoryPath: string;\n navigationBackStack: string[];\n navigationForwardStack: string[];\n selectedLocationId: string | null;\n schemaVersion: typeof workspaceFileManagerPersistedStateSchemaVersion;\n}\n\nexport interface WorkspaceFileSearchInput {\n includeKinds?: Extract<WorkspaceFileEntryKind, \"file\" | \"directory\">[];\n limit?: number;\n query: string;\n within?: string;\n}\n\nexport interface WorkspaceFileOpenWithApplication {\n applicationPath: string;\n iconDataUrl?: string | null;\n name: string;\n}\n\nexport interface WorkspaceFileManagerCapabilities {\n canCopy: boolean;\n canCreateDirectory: boolean;\n canCreateFile: boolean;\n canDelete: boolean;\n canMove: boolean;\n canOpenInAppBrowser: boolean;\n canOpenInDefaultBrowser: boolean;\n canOpenWith: boolean;\n canPickOtherOpenWithApplication: boolean;\n canRevealInFolder: boolean;\n canRename: boolean;\n canSearch: boolean;\n}\n\nexport type WorkspaceFileManagerBusyAction =\n | \"create\"\n | \"delete\"\n | \"move\"\n | \"rename\"\n | \"view\";\n\nexport interface WorkspaceFileManagerCreateDialogState {\n errorMessage: string | null;\n kind: \"directory\" | \"file\";\n name: string;\n}\n\nexport type WorkspaceFileManagerInlineRenameValidation = \"invalid\" | \"required\";\n\nexport interface WorkspaceFileManagerDeleteDialogState {\n entryPath: string;\n}\n\nexport interface WorkspaceFileManagerContextMenuState {\n entryPath: string | null;\n x: number;\n y: number;\n}\n\nexport interface WorkspaceFileManagerUnsupportedDialogState {\n actions?: WorkspaceFileManagerHostFallbackAction[] | null;\n entryPath?: string | null;\n kind: \"view\";\n message?: string | null;\n title?: string | null;\n}\n\nexport interface WorkspaceFileManagerState {\n busyAction: WorkspaceFileManagerBusyAction | null;\n capabilities: WorkspaceFileManagerCapabilities;\n contextMenu: WorkspaceFileManagerContextMenuState | null;\n contextMenuEntryPath: string | null;\n createDialog: WorkspaceFileManagerCreateDialogState | null;\n currentDirectoryPath: string;\n deleteDialog: WorkspaceFileManagerDeleteDialogState | null;\n directoryExpansionByPath: Record<\n string,\n WorkspaceFileDirectoryExpansionState\n >;\n inlineRenameEntryPath: string | null;\n inlineRenameValidation: WorkspaceFileManagerInlineRenameValidation | null;\n entries: WorkspaceFileEntry[];\n error: string | null;\n expandedDirectoryPaths: Record<string, boolean>;\n isLoading: boolean;\n isMutating: boolean;\n isSearching: boolean;\n locationSections: WorkspaceFileLocationSection[];\n navigationBackStack: string[];\n navigationForwardStack: string[];\n pendingDirectoryPath: string | null;\n previewState: WorkspaceFilePreviewState;\n root: string;\n searchEntries: WorkspaceFileSearchEntry[];\n searchError: string | null;\n searchQuery: string;\n selectedLocationId: string | null;\n selectedPath: string | null;\n unsupportedDialog: WorkspaceFileManagerUnsupportedDialogState | null;\n workspaceID: string;\n}\n","import {\n workspaceFileManagerLogicalRoot,\n type WorkspaceFileEntry\n} from \"../../workspaceFileManagerTypes.ts\";\n\nexport function normalizeWorkspaceFilePath(\n value?: string | null,\n rootPath?: string | null\n): string {\n const root = normalizeWorkspaceFileAbsolutePath(rootPath);\n const raw = String(value ?? \"\")\n .trim()\n .replaceAll(\"\\\\\", \"/\");\n if (!raw) {\n return root;\n }\n\n if (!isWorkspaceFileAbsolutePath(raw) && root) {\n return normalizeWorkspaceFileAbsolutePath(`${root}/${raw}`);\n }\n\n return normalizeWorkspaceFileAbsolutePath(raw);\n}\n\nfunction normalizeWorkspaceFileAbsolutePath(value?: string | null): string {\n const raw = String(value ?? \"\")\n .trim()\n .replaceAll(\"\\\\\", \"/\");\n if (!raw) {\n return workspaceFileManagerLogicalRoot;\n }\n\n const drive = readWindowsDrive(raw);\n const startsWithSlash = raw.startsWith(\"/\");\n const body = drive\n ? raw.slice(drive.length).replace(/^\\/+/, \"\")\n : startsWithSlash\n ? raw.slice(1)\n : raw;\n const segments = body\n .split(\"/\")\n .filter(Boolean)\n .filter((segment) => segment !== \".\");\n const result: string[] = [];\n for (const segment of segments) {\n if (segment === \"..\") {\n result.pop();\n continue;\n }\n result.push(segment);\n }\n\n if (result.length === 0) {\n return drive ? `${drive}/` : workspaceFileManagerLogicalRoot;\n }\n if (drive) {\n return `${drive}/${result.join(\"/\")}`;\n }\n return `/${result.join(\"/\")}`;\n}\n\nexport function workspaceFileName(path: string): string {\n return (\n normalizeWorkspaceFilePath(path).split(\"/\").filter(Boolean).at(-1) ??\n \"workspace\"\n );\n}\n\nexport function workspaceFileDirectory(\n path: string,\n rootPath?: string | null\n): string {\n const root = normalizeWorkspaceFilePath(rootPath);\n const rawPath = String(path ?? \"\")\n .trim()\n .replaceAll(\"\\\\\", \"/\");\n const normalized = normalizeWorkspaceFilePath(path, root);\n if (normalized === root) {\n return root;\n }\n\n const drive = readWindowsDrive(normalized);\n const body = drive ? normalized.slice(drive.length) : normalized;\n const parts = body.split(\"/\").filter(Boolean);\n parts.pop();\n const directory = drive\n ? parts.length === 0\n ? `${drive}/`\n : `${drive}/${parts.join(\"/\")}`\n : parts.length === 0\n ? workspaceFileManagerLogicalRoot\n : `/${parts.join(\"/\")}`;\n if (root !== workspaceFileManagerLogicalRoot) {\n if (isWorkspaceFilePathWithinRoot(directory, root)) {\n return directory;\n }\n return isWorkspaceFileAbsolutePath(rawPath) ? directory : root;\n }\n return directory;\n}\n\nexport function isHiddenWorkspaceDirectoryEntry(\n entry: WorkspaceFileEntry\n): boolean {\n return entry.kind === \"directory\" && entry.name.startsWith(\".\");\n}\n\nexport function workspaceFilePathHasHiddenSegment(path: string): boolean {\n return normalizeWorkspaceFilePath(path)\n .split(\"/\")\n .filter(Boolean)\n .some((segment) => segment.startsWith(\".\"));\n}\n\nexport function filterVisibleWorkspaceEntries(\n entries: WorkspaceFileEntry[]\n): WorkspaceFileEntry[] {\n return entries.filter((entry) => !isHiddenWorkspaceDirectoryEntry(entry));\n}\n\nexport function sortWorkspaceEntries(\n entries: WorkspaceFileEntry[]\n): WorkspaceFileEntry[] {\n return [...entries].sort((left, right) => {\n if (left.kind !== right.kind) {\n return left.kind === \"directory\" ? -1 : 1;\n }\n return left.name.localeCompare(right.name, undefined, {\n sensitivity: \"base\"\n });\n });\n}\n\nexport function buildWorkspaceFileBreadcrumbs(\n path: string,\n rootLabel: string,\n rootPath?: string | null\n): Array<{ label: string; path: string }> {\n const root = normalizeWorkspaceFilePath(rootPath);\n const current = normalizeWorkspaceFilePath(path, root);\n\n // Package placeholder root is \"/\". Hosts like TSH keep logical paths under\n // \"/workspace\" before listing.root arrives. Splitting \"/workspace\" under\n // \"/\" yields a duplicate crumb: \"workspace\" / \"workspace\".\n if (\n root === workspaceFileManagerLogicalRoot &&\n current !== workspaceFileManagerLogicalRoot\n ) {\n return [{ label: rootLabel, path: current }];\n }\n\n const relative =\n current === root ? \"\" : current.slice(root.length).replace(/^\\//, \"\");\n const breadcrumbs: Array<{ label: string; path: string }> = [\n { label: rootLabel, path: root }\n ];\n let cursor = root;\n for (const segment of relative.split(\"/\").filter(Boolean)) {\n cursor = `${cursor}/${segment}`.replace(/\\/+/g, \"/\");\n breadcrumbs.push({ label: segment, path: cursor });\n }\n return breadcrumbs;\n}\n\nexport function isWorkspaceFilePathWithinRoot(\n path: string,\n rootPath?: string | null\n): boolean {\n const root = normalizeWorkspaceFilePath(rootPath);\n const normalized = normalizeWorkspaceFilePath(path, root);\n const comparison =\n readWindowsDrive(root) || readWindowsDrive(normalized)\n ? { normalized: normalized.toLowerCase(), root: root.toLowerCase() }\n : { normalized, root };\n return (\n comparison.root === workspaceFileManagerLogicalRoot ||\n comparison.normalized === comparison.root ||\n comparison.normalized.startsWith(`${comparison.root}/`)\n );\n}\n\nfunction isWorkspaceFileAbsolutePath(path: string): boolean {\n return path.startsWith(\"/\") || readWindowsDrive(path) !== \"\";\n}\n\nfunction readWindowsDrive(path: string): string {\n return /^[A-Za-z]:/.exec(path)?.[0] ?? \"\";\n}\n","import type {\n WorkspaceFileLocation,\n WorkspaceFileLocationSection\n} from \"./workspaceFileManagerTypes.ts\";\n\nexport function flattenWorkspaceFileLocations(\n sections: readonly WorkspaceFileLocationSection[]\n): WorkspaceFileLocation[] {\n return sections.flatMap((section) => section.locations);\n}\n\nexport function findWorkspaceFileLocationById(\n sections: readonly WorkspaceFileLocationSection[],\n locationId: string | null | undefined\n): WorkspaceFileLocation | null {\n if (!locationId) {\n return null;\n }\n return (\n flattenWorkspaceFileLocations(sections).find(\n (location) => location.id === locationId\n ) ?? null\n );\n}\n\nexport function resolveWorkspaceFileLocationDefaultId(input: {\n defaultLocationId?: string | null;\n persistedLocationId?: string | null;\n sections: readonly WorkspaceFileLocationSection[];\n}): string | null {\n const { sections } = input;\n const persisted = findWorkspaceFileLocationById(\n sections,\n input.persistedLocationId\n );\n if (persisted) {\n return persisted.id;\n }\n\n const preferred = findWorkspaceFileLocationById(\n sections,\n input.defaultLocationId\n );\n if (preferred) {\n return preferred.id;\n }\n return flattenWorkspaceFileLocations(sections)[0]?.id ?? null;\n}\n\nexport function isWorkspaceFileRecentLocation(\n location: WorkspaceFileLocation | null | undefined\n): boolean {\n return location?.kind === \"recent\";\n}\n\nexport function isWorkspaceFileExternalLocation(\n location: WorkspaceFileLocation | null | undefined\n): boolean {\n return location?.kind === \"external\";\n}\n","import { resolveWorkspaceFileExtension } from \"@tutti-os/workspace-file-preview\";\nimport type {\n WorkspaceFileEntry,\n WorkspaceFileOpenWithApplication\n} from \"../../workspaceFileManagerTypes.ts\";\n\nconst openWithWarmupLimit = 8;\n\nexport function resolveWorkspaceFileOpenWithCacheKey(\n entry: Pick<WorkspaceFileEntry, \"kind\" | \"name\" | \"path\">\n): string {\n const extension = resolveWorkspaceFileExtension(\n entry.path || entry.name || \"\"\n );\n return `${entry.kind}:${extension || \"(no-ext)\"}`;\n}\n\nexport class WorkspaceFileOpenWithApplicationsCache {\n private readonly applicationsByKey = new Map<\n string,\n WorkspaceFileOpenWithApplication[]\n >();\n private readonly inflightByKey = new Map<\n string,\n Promise<WorkspaceFileOpenWithApplication[]>\n >();\n private readonly warmupScheduledKeys = new Set<string>();\n\n get(key: string): WorkspaceFileOpenWithApplication[] | null {\n return this.applicationsByKey.get(key) ?? null;\n }\n\n async resolve(\n key: string,\n load: () => Promise<WorkspaceFileOpenWithApplication[]>\n ): Promise<WorkspaceFileOpenWithApplication[]> {\n const cached = this.applicationsByKey.get(key);\n if (cached) {\n return cached;\n }\n\n const inflight = this.inflightByKey.get(key);\n if (inflight) {\n return inflight;\n }\n\n const promise = load()\n .then((applications) => {\n this.applicationsByKey.set(key, applications);\n this.inflightByKey.delete(key);\n return applications;\n })\n .catch((error) => {\n this.inflightByKey.delete(key);\n throw error;\n });\n this.inflightByKey.set(key, promise);\n return promise;\n }\n\n scheduleWarmup(\n entries: readonly WorkspaceFileEntry[],\n load: (\n entry: WorkspaceFileEntry\n ) => Promise<WorkspaceFileOpenWithApplication[]>\n ): void {\n let scheduled = 0;\n const seenKeys = new Set<string>();\n\n for (const entry of entries) {\n if (entry.kind !== \"file\" || scheduled >= openWithWarmupLimit) {\n continue;\n }\n\n const key = resolveWorkspaceFileOpenWithCacheKey(entry);\n if (\n seenKeys.has(key) ||\n this.applicationsByKey.has(key) ||\n this.inflightByKey.has(key) ||\n this.warmupScheduledKeys.has(key)\n ) {\n continue;\n }\n\n seenKeys.add(key);\n this.warmupScheduledKeys.add(key);\n scheduled += 1;\n void load(entry).finally(() => {\n this.warmupScheduledKeys.delete(key);\n });\n }\n }\n}\n","// Must share the same valtio module instance as subscribe() in the session.\n// Mixing \"valtio\" with \"valtio/vanilla\" under Vite can create two proxyStateMaps\n// and crash subscribe with: Cannot read properties of undefined (reading '2').\nimport { proxy } from \"valtio/vanilla\";\nimport {\n workspaceFileManagerPersistedStateSchemaVersion,\n workspaceFileManagerLogicalRoot,\n workspaceFileManagerPreviousPersistedStateSchemaVersion,\n type WorkspaceFileManagerCapabilities,\n type WorkspaceFileLocationSection,\n type WorkspaceFileManagerPersistedState,\n type WorkspaceFileManagerState\n} from \"../workspaceFileManagerTypes.ts\";\nimport { normalizeWorkspaceFilePath } from \"../workspaceFileManagerModel.ts\";\nimport { resolveWorkspaceFileLocationDefaultId } from \"../workspaceFileManagerLocations.ts\";\n\nexport function createWorkspaceFileManagerStore(input: {\n capabilities: WorkspaceFileManagerCapabilities;\n defaultLocationId?: string | null;\n initialDirectoryPath?: string;\n locationSections?: WorkspaceFileLocationSection[];\n persistedState?: WorkspaceFileManagerPersistedState | null;\n workspaceID: string;\n}): WorkspaceFileManagerState {\n const persistedState = normalizeWorkspaceFileManagerPersistedState(\n input.persistedState\n );\n const initialDirectoryPath = normalizeWorkspaceFilePath(\n input.initialDirectoryPath\n );\n const locationSections = input.locationSections ?? [];\n const selectedLocationId = resolveWorkspaceFileLocationDefaultId({\n defaultLocationId: input.defaultLocationId,\n persistedLocationId: persistedState?.selectedLocationId,\n sections: locationSections\n });\n return proxy<WorkspaceFileManagerState>({\n busyAction: null,\n capabilities: input.capabilities,\n contextMenu: null,\n contextMenuEntryPath: null,\n createDialog: null,\n currentDirectoryPath:\n persistedState?.currentDirectoryPath ??\n initialDirectoryPath ??\n workspaceFileManagerLogicalRoot,\n deleteDialog: null,\n directoryExpansionByPath: {},\n inlineRenameEntryPath: null,\n inlineRenameValidation: null,\n entries: [],\n error: null,\n expandedDirectoryPaths: {},\n isLoading: false,\n isMutating: false,\n isSearching: false,\n locationSections,\n navigationBackStack: persistedState?.navigationBackStack ?? [],\n navigationForwardStack: persistedState?.navigationForwardStack ?? [],\n pendingDirectoryPath: null,\n previewState: { status: \"empty\" },\n root: workspaceFileManagerLogicalRoot,\n searchEntries: [],\n searchError: null,\n searchQuery: \"\",\n selectedLocationId,\n selectedPath: null,\n unsupportedDialog: null,\n workspaceID: input.workspaceID\n });\n}\n\nexport function getWorkspaceFileManagerPersistedState(\n state: WorkspaceFileManagerState\n): WorkspaceFileManagerPersistedState {\n return {\n currentDirectoryPath: normalizeWorkspaceFilePath(\n state.currentDirectoryPath,\n state.root\n ),\n navigationBackStack: normalizePersistedStack(\n state.navigationBackStack,\n state.root\n ),\n navigationForwardStack: normalizePersistedStack(\n state.navigationForwardStack,\n state.root\n ),\n selectedLocationId: state.selectedLocationId ?? null,\n schemaVersion: workspaceFileManagerPersistedStateSchemaVersion\n };\n}\n\nexport function normalizeWorkspaceFileManagerPersistedState(\n value: unknown\n): WorkspaceFileManagerPersistedState | null {\n if (\n !isPersistedStateRecord(value) ||\n typeof value.currentDirectoryPath !== \"string\" ||\n !isStringArray(value.navigationBackStack) ||\n !isStringArray(value.navigationForwardStack)\n ) {\n return null;\n }\n if (\n value.schemaVersion !== workspaceFileManagerPersistedStateSchemaVersion &&\n value.schemaVersion !==\n workspaceFileManagerPreviousPersistedStateSchemaVersion\n ) {\n return null;\n }\n const selectedLocationId =\n value.schemaVersion === workspaceFileManagerPersistedStateSchemaVersion\n ? readOptionalString(value.selectedLocationId)\n : null;\n\n return {\n currentDirectoryPath: normalizeWorkspaceFilePath(\n value.currentDirectoryPath\n ),\n navigationBackStack: normalizePersistedStack(value.navigationBackStack),\n navigationForwardStack: normalizePersistedStack(\n value.navigationForwardStack\n ),\n selectedLocationId,\n schemaVersion: workspaceFileManagerPersistedStateSchemaVersion\n };\n}\n\nfunction isPersistedStateRecord(\n value: unknown\n): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isStringArray(value: unknown): value is string[] {\n return (\n Array.isArray(value) && value.every((item) => typeof item === \"string\")\n );\n}\n\nfunction readOptionalString(value: unknown): string | null {\n return typeof value === \"string\" && value.trim() ? value : null;\n}\n\nfunction normalizePersistedStack(\n values: readonly string[] | undefined,\n root?: string | null\n): string[] {\n if (!Array.isArray(values)) {\n return [];\n }\n return values\n .map((value) =>\n typeof value === \"string\" ? normalizeWorkspaceFilePath(value, root) : null\n )\n .filter((value): value is string => value !== null);\n}\n","import { resolveWorkspaceFilePreviewTarget } from \"@tutti-os/workspace-file-preview\";\nimport type {\n WorkspaceFileActivationTarget,\n WorkspaceFileEntry\n} from \"../../workspaceFileManagerTypes.ts\";\n\n/**\n * Host activation adapter over the shared preview target vocabulary.\n * Open / reveal / open-with remain file-manager / desktop concerns.\n */\nexport function resolveWorkspaceFileActivationTarget(\n entry: WorkspaceFileEntry\n): WorkspaceFileActivationTarget | null {\n const target = resolveWorkspaceFilePreviewTarget(entry);\n if (!target) {\n return null;\n }\n\n return {\n previewKind: target.previewKind,\n mtimeMs: target.mtimeMs ?? null,\n name: target.name,\n path: target.path,\n sizeBytes: target.sizeBytes ?? null\n };\n}\n","import { formatTuttiShortDateTime } from \"@tutti-os/ui-system/date-format\";\nimport type { TuttiDateLocale } from \"@tutti-os/ui-system/date-format\";\n\nexport function formatWorkspaceFileBytes(sizeBytes: number | null): string {\n if (sizeBytes === null || !Number.isFinite(sizeBytes)) {\n return \"--\";\n }\n if (sizeBytes < 1024) {\n return `${sizeBytes} B`;\n }\n const units = [\"KB\", \"MB\", \"GB\", \"TB\"];\n let value = sizeBytes / 1024;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n return `${value >= 10 ? value.toFixed(1) : value.toFixed(2)} ${units[unitIndex]}`;\n}\n\nexport function formatWorkspaceFileModifiedTime(\n mtimeMs: number | null,\n locale?: TuttiDateLocale\n): string {\n if (mtimeMs === null || !Number.isFinite(mtimeMs) || mtimeMs <= 0) {\n return \"--\";\n }\n return formatTuttiShortDateTime(mtimeMs, locale);\n}\n\nexport function splitWorkspaceFileName(name: string): {\n end: string;\n start: string;\n} {\n const extensionIndex = name.lastIndexOf(\".\");\n const hasExtension = extensionIndex > 0 && extensionIndex < name.length - 1;\n if (hasExtension) {\n return {\n end: name.slice(extensionIndex),\n start: name.slice(0, extensionIndex)\n };\n }\n if (name.length <= 24) {\n return { end: \"\", start: name };\n }\n return {\n end: name.slice(-10),\n start: name.slice(0, -10)\n };\n}\n","import type {\n WorkspaceFileEntry,\n WorkspaceFileSearchEntry\n} from \"../../workspaceFileManagerTypes.ts\";\n\nexport function workspaceFileSearchEntryToEntry(\n entry: WorkspaceFileSearchEntry\n): WorkspaceFileEntry {\n return {\n hasChildren: entry.kind === \"directory\",\n kind: entry.kind,\n mtimeMs: null,\n name: entry.name,\n path: entry.path,\n sizeBytes: null\n };\n}\n","export function validateWorkspaceFileEntryName(\n name: string\n): \"invalid\" | \"required\" | null {\n const trimmed = name.trim();\n if (!trimmed) {\n return \"required\";\n }\n if (\n trimmed.includes(\"/\") ||\n trimmed.includes(\"\\\\\") ||\n trimmed === \".\" ||\n trimmed === \"..\"\n ) {\n return \"invalid\";\n }\n return null;\n}\n","import { subscribe } from \"valtio/vanilla\";\nimport {\n normalizeWorkspaceFilePath,\n validateWorkspaceFileEntryName,\n workspaceFileDirectory\n} from \"../workspaceFileManagerModel.ts\";\nimport { getWorkspaceFileManagerPersistedState } from \"./workspaceFileManagerStore.ts\";\nimport {\n findWorkspaceFileLocationById,\n isWorkspaceFileExternalLocation,\n isWorkspaceFileRecentLocation,\n resolveWorkspaceFileLocationDefaultId\n} from \"../workspaceFileManagerLocations.ts\";\nimport type { WorkspaceFileManagerI18nRuntime } from \"../../i18n/workspaceFileManagerI18n.ts\";\nimport type {\n CreateWorkspaceFileManagerSessionInput,\n WorkspaceFileManagerHost,\n WorkspaceFileManagerMutationErrorMessage\n} from \"../workspaceFileManagerHost.interface.ts\";\nimport type {\n WorkspaceFileManagerFileActivationRequest,\n WorkspaceFileManagerHostFallbackAction\n} from \"../workspaceFileManagerHostTypes.ts\";\nimport type { WorkspaceFileManagerSession } from \"../workspaceFileManagerService.interface.ts\";\nimport type {\n WorkspaceFileEntry,\n WorkspaceFileLocation,\n WorkspaceFileLocationSection,\n WorkspaceFileOpenWithApplication,\n WorkspaceFileManagerPersistedState,\n WorkspaceFileSearchEntry,\n WorkspaceFileManagerState\n} from \"../workspaceFileManagerTypes.ts\";\nimport { WorkspaceFileManagerActivationController } from \"./workspaceFileManagerActivationController.ts\";\nimport { WorkspaceFileManagerMutationController } from \"./workspaceFileManagerMutationController.ts\";\nimport { WorkspaceFileManagerNavigationController } from \"./workspaceFileManagerNavigationController.ts\";\nimport { WorkspaceFileManagerPreviewController } from \"./workspaceFileManagerPreviewController.ts\";\nimport { WorkspaceFileManagerTreeController } from \"./workspaceFileManagerTreeController.ts\";\nimport { findWorkspaceFileEntry } from \"./model/entryLookup.ts\";\nimport {\n resolveWorkspaceFileOpenWithCacheKey,\n WorkspaceFileOpenWithApplicationsCache\n} from \"./model/openWithApplicationsCache.ts\";\n\nexport interface WorkspaceFileManagerSessionInput {\n copy: WorkspaceFileManagerI18nRuntime;\n host: WorkspaceFileManagerHost;\n onMutationErrorMessage?: (\n message: WorkspaceFileManagerMutationErrorMessage\n ) => boolean | void;\n persistence?: CreateWorkspaceFileManagerSessionInput[\"persistence\"];\n resolveFileDefaultOpener?: CreateWorkspaceFileManagerSessionInput[\"resolveFileDefaultOpener\"];\n store: WorkspaceFileManagerState;\n}\n\nexport class DefaultWorkspaceFileManagerSession implements WorkspaceFileManagerSession {\n readonly store: WorkspaceFileManagerState;\n private readonly host: WorkspaceFileManagerHost;\n private hasInitialized = false;\n /**\n * True after a directory listing attempt finished without leaving the session\n * mid-flight. Empty folders set this too — \"no entries\" is not \"not loaded\".\n */\n private hasSettledDirectoryListing = false;\n private initializePromise: Promise<void> | null = null;\n private isActive = false;\n private isDisposed = false;\n private lastObservedEntries: WorkspaceFileManagerState[\"entries\"];\n private lastObservedPersistedState: string;\n private lastObservedSelectedPath: WorkspaceFileManagerState[\"selectedPath\"];\n private lastRevealRequestID: string | null = null;\n private readonly onMutationErrorMessage?: (\n message: WorkspaceFileManagerMutationErrorMessage\n ) => boolean | void;\n private searchRequestSeq = 0;\n private readonly activationController: WorkspaceFileManagerActivationController;\n private copy: WorkspaceFileManagerI18nRuntime;\n private readonly mutationController: WorkspaceFileManagerMutationController;\n private readonly navigationController: WorkspaceFileManagerNavigationController;\n private readonly previewController: WorkspaceFileManagerPreviewController;\n private readonly treeController: WorkspaceFileManagerTreeController;\n private readonly persistence?: CreateWorkspaceFileManagerSessionInput[\"persistence\"];\n private unsubscribeStore: (() => void) | null = null;\n private readonly openWithApplicationsCache =\n new WorkspaceFileOpenWithApplicationsCache();\n\n constructor(input: WorkspaceFileManagerSessionInput) {\n this.copy = input.copy;\n this.host = input.host;\n this.onMutationErrorMessage = input.onMutationErrorMessage;\n this.persistence = input.persistence;\n this.store = input.store;\n this.navigationController = new WorkspaceFileManagerNavigationController({\n host: input.host,\n resolveErrorMessage: (error) => this.resolveErrorMessage(error),\n store: this.store\n });\n this.treeController = new WorkspaceFileManagerTreeController({\n host: input.host,\n resolveErrorMessage: (error) => this.resolveErrorMessage(error),\n store: this.store\n });\n this.activationController = new WorkspaceFileManagerActivationController({\n copy: () => this.copy,\n host: input.host,\n loadDirectory: (path) => this.loadDirectory(path),\n resolveErrorMessage: (error, overrides) =>\n this.resolveErrorMessage(error, overrides),\n resolveFileDefaultOpener: input.resolveFileDefaultOpener,\n store: this.store\n });\n this.mutationController = new WorkspaceFileManagerMutationController({\n host: input.host,\n onErrorMessage: (message) => this.onMutationErrorMessage?.(message),\n refresh: () => this.refresh(),\n resolveErrorMessage: (error) => this.resolveErrorMessage(error),\n store: this.store\n });\n this.previewController = new WorkspaceFileManagerPreviewController({\n copy: () => this.copy,\n host: input.host,\n resolveErrorMessage: (error, overrides) =>\n this.resolveErrorMessage(error, overrides),\n store: this.store\n });\n this.lastObservedEntries = this.store.entries;\n this.lastObservedPersistedState = serializePersistedState(\n this.getPersistedState()\n );\n this.lastObservedSelectedPath = this.store.selectedPath;\n }\n\n async activateFile(request: WorkspaceFileManagerFileActivationRequest) {\n return this.activationController.activateFile(request);\n }\n\n async applyRevealIntent(\n intent: {\n mode?: \"select\" | \"open\";\n path: string;\n requestID: string;\n } | null\n ): Promise<void> {\n if (!intent?.path || !intent.requestID) {\n return;\n }\n if (intent.requestID === this.lastRevealRequestID) {\n return;\n }\n this.lastRevealRequestID = intent.requestID;\n if (intent.mode === \"open\") {\n await this.loadDirectory(intent.path);\n return;\n }\n await this.revealPath(intent.path);\n }\n\n closeContextMenu(): void {\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n }\n\n closeCreateDialog(): void {\n if (this.store.busyAction === \"create\") {\n return;\n }\n this.store.createDialog = null;\n }\n\n closeDeleteDialog(): void {\n if (this.store.busyAction === \"delete\") {\n return;\n }\n this.store.deleteDialog = null;\n }\n\n cancelInlineRename(): void {\n if (this.store.busyAction === \"rename\") {\n return;\n }\n this.store.inlineRenameEntryPath = null;\n this.store.inlineRenameValidation = null;\n }\n\n closeTransientUi(): void {\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n if (this.store.busyAction !== null) {\n return;\n }\n this.store.createDialog = null;\n this.store.deleteDialog = null;\n this.store.inlineRenameEntryPath = null;\n this.store.inlineRenameValidation = null;\n this.store.unsupportedDialog = null;\n }\n\n closeUnsupportedDialog(): void {\n if (this.store.busyAction === \"view\") {\n return;\n }\n this.store.unsupportedDialog = null;\n }\n\n async confirmCreateDialog(): Promise<void> {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n const createDialog = this.store.createDialog;\n if (!createDialog) {\n return;\n }\n const validation = validateWorkspaceFileEntryName(createDialog.name);\n if (validation) {\n this.store.createDialog = {\n ...createDialog,\n errorMessage:\n validation === \"required\"\n ? this.copy.t(\"createNameRequired\")\n : this.copy.t(\"createNameInvalid\")\n };\n return;\n }\n\n const path =\n `${this.store.currentDirectoryPath}/${createDialog.name.trim()}`.replaceAll(\n /\\/+/g,\n \"/\"\n );\n this.store.busyAction = \"create\";\n try {\n if (createDialog.kind === \"directory\") {\n await this.createDirectory(path);\n } else {\n await this.createFile(path);\n }\n this.store.createDialog = null;\n } finally {\n this.store.busyAction = null;\n }\n }\n\n async confirmDeleteDialog(): Promise<void> {\n const deleteDialog = this.store.deleteDialog;\n if (!deleteDialog) {\n return;\n }\n this.store.busyAction = \"delete\";\n try {\n this.store.selectedPath = deleteDialog.entryPath;\n await this.deleteSelected();\n this.store.deleteDialog = null;\n } finally {\n this.store.busyAction = null;\n }\n }\n\n async confirmInlineRename(newName: string): Promise<boolean> {\n const inlineRenameEntryPath = this.store.inlineRenameEntryPath;\n if (!inlineRenameEntryPath) {\n return true;\n }\n const entry = findWorkspaceFileEntry(this.store, inlineRenameEntryPath);\n if (!entry) {\n this.store.inlineRenameEntryPath = null;\n this.store.inlineRenameValidation = null;\n return true;\n }\n\n const trimmedName = newName.trim();\n if (trimmedName === entry.name) {\n this.store.inlineRenameEntryPath = null;\n this.store.inlineRenameValidation = null;\n return true;\n }\n\n const validation = validateWorkspaceFileEntryName(trimmedName);\n if (validation) {\n this.store.inlineRenameValidation = validation;\n return false;\n }\n\n this.store.inlineRenameValidation = null;\n this.store.busyAction = \"rename\";\n try {\n await this.mutationController.renameEntry(entry, trimmedName);\n this.store.inlineRenameEntryPath = null;\n return true;\n } finally {\n this.store.busyAction = null;\n }\n }\n\n async createDirectory(path: string): Promise<void> {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n await this.mutationController.createDirectory(path);\n }\n\n async createFile(path: string): Promise<void> {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n await this.mutationController.createFile(path);\n }\n\n async deleteSelected(): Promise<void> {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n await this.mutationController.deleteSelected();\n }\n\n dispose(): void {\n this.isDisposed = true;\n this.hasInitialized = false;\n this.hasSettledDirectoryListing = false;\n this.initializePromise = null;\n this.isActive = false;\n this.searchRequestSeq += 1;\n this.store.isSearching = false;\n this.unsubscribeStore?.();\n this.unsubscribeStore = null;\n this.previewController.dispose();\n }\n\n async goBack(): Promise<void> {\n await this.navigationController.goBack();\n this.syncSelectedDirectoryLocation();\n }\n\n async goForward(): Promise<void> {\n await this.navigationController.goForward();\n this.syncSelectedDirectoryLocation();\n }\n\n getPersistedState(): WorkspaceFileManagerPersistedState {\n return getWorkspaceFileManagerPersistedState(this.store);\n }\n\n async handleActivationFallbackAction(\n action: WorkspaceFileManagerHostFallbackAction\n ): Promise<void> {\n await this.activationController.handleFallbackAction(action);\n }\n\n async initialize(): Promise<void> {\n if (this.hasInitialized) {\n return;\n }\n if (this.initializePromise) {\n await this.initializePromise;\n return;\n }\n this.isDisposed = false;\n this.initializePromise = (async () => {\n this.observeStore();\n if (!this.hasLoadedDirectoryState()) {\n // loadDirectory owns isLoading true→false. Do not latch isLoading here:\n // a host that primes loading and then aborts initialize would stick.\n await this.loadSelectedLocationOrDirectory();\n }\n await this.previewController.syncPreviewState();\n this.hasInitialized = true;\n })();\n try {\n await this.initializePromise;\n } finally {\n this.initializePromise = null;\n // If init aborted/failed before a listing settled, never leave the UI\n // spinning on a stale loading latch.\n if (!this.hasSettledDirectoryListing && this.store.isLoading) {\n this.store.isLoading = false;\n }\n }\n }\n\n async loadDirectory(path = this.store.currentDirectoryPath): Promise<void> {\n this.clearSearchState();\n await this.navigationController.loadDirectory(path);\n if (!this.store.isLoading) {\n this.hasSettledDirectoryListing = true;\n }\n this.syncSelectedDirectoryLocation();\n }\n\n openContextMenu(input: {\n entryPath: string | null;\n x: number;\n y: number;\n }): void {\n this.store.contextMenuEntryPath = input.entryPath;\n this.store.contextMenu = input;\n }\n\n openCreateDirectoryDialog(): void {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n this.store.createDialog = {\n errorMessage: null,\n kind: \"directory\",\n name: \"\"\n };\n }\n\n openCreateFileDialog(): void {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n this.store.createDialog = {\n errorMessage: null,\n kind: \"file\",\n name: \"\"\n };\n }\n\n openDeleteDialog(entry: WorkspaceFileEntry): void {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n this.store.deleteDialog = {\n entryPath: entry.path\n };\n }\n\n startInlineRename(entry: WorkspaceFileEntry): void {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n this.store.inlineRenameEntryPath = entry.path;\n this.store.inlineRenameValidation = null;\n this.store.selectedPath = entry.path;\n }\n\n async toggleDirectoryExpanded(entry: WorkspaceFileEntry): Promise<void> {\n await this.treeController.toggleDirectoryExpanded(entry);\n }\n\n async copyToClipboard(entry: WorkspaceFileEntry): Promise<boolean> {\n if (this.isExternalLocationSelected()) {\n return false;\n }\n if (!this.host.copyEntriesToClipboard) {\n return false;\n }\n\n try {\n await this.host.copyEntriesToClipboard({\n paths: [entry.path],\n workspaceID: this.store.workspaceID\n });\n return true;\n } catch (error) {\n // Copy is triggered from visible affordances, so a rejection must reach\n // the user instead of becoming an unhandled rejection.\n const message = this.resolveErrorMessage(error);\n const handled = this.onMutationErrorMessage?.({\n actionKind: \"copy\",\n error,\n message\n });\n if (!handled) {\n this.store.error = message;\n }\n return false;\n }\n }\n\n getCachedOpenWithApplications(\n entry: WorkspaceFileEntry\n ): WorkspaceFileOpenWithApplication[] | null {\n if (!this.host.listOpenWithApplications) {\n return null;\n }\n return this.openWithApplicationsCache.get(\n resolveWorkspaceFileOpenWithCacheKey(entry)\n );\n }\n\n async listOpenWithApplications(\n entry: WorkspaceFileEntry\n ): Promise<WorkspaceFileOpenWithApplication[]> {\n if (!this.host.listOpenWithApplications) {\n return [];\n }\n return this.openWithApplicationsCache.resolve(\n resolveWorkspaceFileOpenWithCacheKey(entry),\n () =>\n this.host.listOpenWithApplications!({\n path: entry.path,\n workspaceID: this.store.workspaceID\n })\n );\n }\n\n async openEntry(entry: WorkspaceFileEntry): Promise<void> {\n await this.activationController.openEntry(entry);\n }\n\n async openFileWithApplication(\n entry: WorkspaceFileEntry,\n applicationPath: string\n ): Promise<void> {\n if (!this.host.openFileWithApplication) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n await this.host.openFileWithApplication({\n applicationPath,\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n }\n\n async openFileInAppBrowser(entry: WorkspaceFileEntry): Promise<void> {\n if (!this.host.openFileInAppBrowser) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n await this.host.openFileInAppBrowser({\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n }\n\n async openFileInDefaultBrowser(entry: WorkspaceFileEntry): Promise<void> {\n if (!this.host.openFileInDefaultBrowser) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n await this.host.openFileInDefaultBrowser({\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n }\n\n async openFileInFileViewer(entry: WorkspaceFileEntry): Promise<void> {\n await this.activationController.openFileInFileViewer(entry);\n }\n\n async openFileInSystemDefault(entry: WorkspaceFileEntry): Promise<void> {\n if (!this.host.openFileInSystemDefault) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n await this.host.openFileInSystemDefault({\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n }\n\n async openFileWithOtherApplication(entry: WorkspaceFileEntry): Promise<void> {\n if (!this.host.openFileWithOtherApplication) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n await this.host.openFileWithOtherApplication({\n applicationPickerPrompt: this.copy.t(\"openWithOtherPickerPrompt\"),\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n }\n\n async revealEntry(entry: WorkspaceFileEntry): Promise<void> {\n if (!this.host.revealEntry) {\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n await this.host.revealEntry({\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n }\n\n async moveEntry(\n entry: WorkspaceFileEntry,\n targetDirectoryPath: string\n ): Promise<void> {\n if (this.isReadOnlyLocationSelected()) {\n return;\n }\n this.store.busyAction = \"move\";\n try {\n await this.mutationController.moveEntry(entry, targetDirectoryPath);\n } finally {\n this.store.busyAction = null;\n }\n }\n\n async refresh(): Promise<void> {\n const selectedLocation = this.selectedLocation();\n if (isWorkspaceFileExternalLocation(selectedLocation)) {\n return;\n }\n if (selectedLocation?.kind === \"recent\") {\n await this.loadRecentLocation(selectedLocation);\n return;\n }\n await this.navigationController.refresh();\n }\n\n async revealPath(path: string): Promise<void> {\n await this.navigationController.revealPath(path);\n this.syncSelectedDirectoryLocation();\n }\n\n async search(query: string): Promise<void> {\n const requestID = ++this.searchRequestSeq;\n this.store.searchQuery = query;\n this.store.searchError = null;\n const trimmedQuery = query.trim();\n if (trimmedQuery === \"\") {\n this.store.searchEntries = [];\n this.store.isSearching = false;\n return;\n }\n\n this.store.isSearching = true;\n try {\n const selectedLocation = this.selectedLocation();\n const entries = isWorkspaceFileRecentLocation(selectedLocation)\n ? await this.searchRecentEntries(trimmedQuery)\n : await this.searchDirectoryEntries(query, selectedLocation);\n if (this.isDisposed || requestID !== this.searchRequestSeq) {\n return;\n }\n this.store.searchEntries = entries;\n } catch (error) {\n if (!this.isDisposed && requestID === this.searchRequestSeq) {\n this.store.searchError = this.resolveErrorMessage(error);\n }\n } finally {\n if (!this.isDisposed && requestID === this.searchRequestSeq) {\n this.store.isSearching = false;\n }\n }\n }\n\n select(path: string | null): void {\n const nextSelectedPath = path\n ? normalizeWorkspaceFilePath(path, this.store.root)\n : null;\n if (this.store.selectedPath === nextSelectedPath) {\n if (\n nextSelectedPath !== null &&\n !isPreviewStateForPath(this.store.previewState, nextSelectedPath)\n ) {\n void this.previewController.syncPreviewState();\n }\n return;\n }\n this.store.selectedPath = nextSelectedPath;\n }\n\n async selectLocation(locationId: string): Promise<void> {\n const location = findWorkspaceFileLocationById(\n this.store.locationSections,\n locationId\n );\n if (!location) {\n return;\n }\n this.store.selectedLocationId = location.id;\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n this.store.createDialog = null;\n this.store.deleteDialog = null;\n this.store.inlineRenameEntryPath = null;\n this.store.inlineRenameValidation = null;\n this.clearSearchState();\n if (location.kind === \"external\") {\n this.store.selectedPath = null;\n this.store.previewState = { status: \"empty\" };\n return;\n }\n if (location.kind === \"recent\") {\n await this.loadRecentLocation(location);\n return;\n }\n await this.loadDirectory(location.path);\n }\n\n setActive(active: boolean): void {\n if (this.isActive === active) {\n return;\n }\n this.isActive = active;\n if (active) {\n // Recover only when initialize finished without ever settling a listing\n // (superseded/remount race). A settled empty folder must not reload.\n if (\n this.hasInitialized &&\n !this.hasSettledDirectoryListing &&\n !this.store.isLoading\n ) {\n void this.loadSelectedLocationOrDirectory();\n }\n return;\n }\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n }\n\n setI18nRuntime(copy: WorkspaceFileManagerI18nRuntime): void {\n if (this.copy === copy) {\n return;\n }\n this.copy = copy;\n void this.previewController.syncPreviewState();\n }\n\n async setLocations(input: {\n defaultLocationId?: string | null;\n sections: WorkspaceFileLocationSection[];\n }): Promise<void> {\n const previousLocationId = this.store.selectedLocationId;\n const previousLocation = findWorkspaceFileLocationById(\n this.store.locationSections,\n previousLocationId\n );\n this.store.locationSections = input.sections;\n const nextLocationId = resolveWorkspaceFileLocationDefaultId({\n defaultLocationId: input.defaultLocationId,\n persistedLocationId: previousLocationId,\n sections: input.sections\n });\n const nextLocation = findWorkspaceFileLocationById(\n input.sections,\n nextLocationId\n );\n this.store.selectedLocationId = nextLocationId;\n if (!this.hasInitialized || !nextLocationId) {\n return;\n }\n const selectedLocationChanged =\n previousLocationId !== nextLocationId ||\n previousLocation?.kind !== nextLocation?.kind ||\n (previousLocation?.kind === \"directory\" &&\n nextLocation?.kind === \"directory\" &&\n !areWorkspaceFilePathsEqual(\n previousLocation.path,\n nextLocation.path\n )) ||\n (previousLocation?.kind === \"external\" &&\n nextLocation?.kind === \"external\" &&\n previousLocation.externalType !== nextLocation.externalType);\n if (selectedLocationChanged) {\n await this.selectLocation(nextLocationId);\n }\n }\n\n updateCreateDialogName(name: string): void {\n if (!this.store.createDialog) {\n return;\n }\n this.store.createDialog = {\n ...this.store.createDialog,\n errorMessage: null,\n name\n };\n }\n\n clearInlineRenameValidation(): void {\n this.store.inlineRenameValidation = null;\n }\n\n private hasLoadedDirectoryState(): boolean {\n // selectedPath alone is not a listing — persistence can restore a selection\n // before any directory.list runs. Skipping load left the panel empty/stuck.\n return (\n this.hasSettledDirectoryListing ||\n this.store.error !== null ||\n this.store.entries.length > 0\n );\n }\n\n private async loadSelectedLocationOrDirectory(): Promise<void> {\n const selectedLocation = this.selectedLocation();\n if (isWorkspaceFileExternalLocation(selectedLocation)) {\n this.hasSettledDirectoryListing = true;\n this.store.isLoading = false;\n return;\n }\n if (selectedLocation?.kind === \"recent\") {\n await this.loadRecentLocation(selectedLocation);\n return;\n }\n await this.loadDirectory(\n this.resolveInitialDirectoryPath(selectedLocation)\n );\n }\n\n private async loadRecentLocation(\n location: Extract<WorkspaceFileLocation, { kind: \"recent\" }>\n ): Promise<void> {\n this.store.isLoading = true;\n this.store.error = null;\n try {\n const listing = await this.host.listRecentEntries?.({\n workspaceID: this.store.workspaceID\n });\n this.store.root = normalizeWorkspaceFilePath(\n listing?.root ?? this.store.root\n );\n this.store.currentDirectoryPath =\n listing?.directoryPath ?? this.store.root;\n this.store.entries = listing?.entries ?? [];\n this.store.directoryExpansionByPath = {};\n this.store.expandedDirectoryPaths = {};\n this.store.navigationBackStack = [];\n this.store.navigationForwardStack = [];\n this.store.selectedLocationId = location.id;\n this.store.selectedPath = null;\n } catch (error) {\n this.store.error = this.resolveErrorMessage(error);\n } finally {\n this.store.isLoading = false;\n this.hasSettledDirectoryListing = true;\n }\n }\n\n private selectedLocation(): WorkspaceFileLocation | null {\n return findWorkspaceFileLocationById(\n this.store.locationSections,\n this.store.selectedLocationId\n );\n }\n\n private isRecentLocationSelected(): boolean {\n return isWorkspaceFileRecentLocation(this.selectedLocation());\n }\n\n private isExternalLocationSelected(): boolean {\n return isWorkspaceFileExternalLocation(this.selectedLocation());\n }\n\n private isReadOnlyLocationSelected(): boolean {\n const selectedLocation = this.selectedLocation();\n return (\n isWorkspaceFileRecentLocation(selectedLocation) ||\n isWorkspaceFileExternalLocation(selectedLocation)\n );\n }\n\n private resolveInitialDirectoryPath(\n selectedLocation: WorkspaceFileLocation | null\n ): string {\n if (selectedLocation?.kind !== \"directory\") {\n return this.store.currentDirectoryPath;\n }\n return isWorkspaceFilePathWithinDirectory(\n this.store.currentDirectoryPath,\n selectedLocation.path\n )\n ? this.store.currentDirectoryPath\n : selectedLocation.path;\n }\n\n private syncSelectedDirectoryLocation(): void {\n if (this.store.error) {\n return;\n }\n this.store.selectedLocationId = this.resolveDirectoryLocationIdForPath(\n this.store.currentDirectoryPath\n );\n }\n\n private resolveDirectoryLocationIdForPath(path: string): string | null {\n let bestLocation: {\n id: string;\n path: string;\n } | null = null;\n for (const section of this.store.locationSections) {\n for (const location of section.locations) {\n if (location.kind !== \"directory\") {\n continue;\n }\n const normalizedLocationPath = normalizeWorkspaceFilePath(\n location.path,\n this.store.root\n );\n if (!isWorkspaceFilePathWithinDirectory(path, normalizedLocationPath)) {\n continue;\n }\n if (\n !bestLocation ||\n normalizedLocationPath.length > bestLocation.path.length\n ) {\n bestLocation = {\n id: location.id,\n path: normalizedLocationPath\n };\n }\n }\n }\n return bestLocation?.id ?? null;\n }\n\n private clearSearchState(): void {\n if (\n this.store.searchQuery === \"\" &&\n this.store.searchEntries.length === 0 &&\n this.store.searchError === null &&\n !this.store.isSearching\n ) {\n return;\n }\n this.searchRequestSeq += 1;\n this.store.searchEntries = [];\n this.store.searchError = null;\n this.store.searchQuery = \"\";\n this.store.isSearching = false;\n }\n\n private async searchDirectoryEntries(\n query: string,\n selectedLocation: WorkspaceFileLocation | null\n ): Promise<WorkspaceFileSearchEntry[]> {\n if (!this.host.search) {\n return [];\n }\n const result = await this.host.search({\n query,\n workspaceID: this.store.workspaceID,\n ...(selectedLocation?.kind === \"directory\"\n ? { within: selectedLocation.path }\n : {})\n });\n return result.entries;\n }\n\n private async searchRecentEntries(\n query: string\n ): Promise<WorkspaceFileSearchEntry[]> {\n if (!this.host.listRecentEntries) {\n return [];\n }\n const listing = await this.host.listRecentEntries({\n limit: 100,\n workspaceID: this.store.workspaceID\n });\n const normalizedQuery = query.trim().toLowerCase();\n return listing.entries\n .filter((entry) => {\n const name = entry.name.toLowerCase();\n return name.includes(normalizedQuery);\n })\n .map((entry, index) => ({\n directoryPath: workspaceFileDirectory(entry.path, listing.root),\n kind: entry.kind,\n matchIndices: [],\n matchTarget: \"basename\",\n name: entry.name,\n path: entry.path,\n score: listing.entries.length - index\n }));\n }\n\n private observeStore(): void {\n if (this.unsubscribeStore) {\n return;\n }\n\n this.lastObservedEntries = this.store.entries;\n this.lastObservedSelectedPath = this.store.selectedPath;\n this.unsubscribeStore = subscribe(this.store, () => {\n if (this.isDisposed) {\n return;\n }\n if (\n this.lastObservedEntries === this.store.entries &&\n this.lastObservedSelectedPath === this.store.selectedPath\n ) {\n this.savePersistedStateIfChanged();\n return;\n }\n this.lastObservedEntries = this.store.entries;\n this.lastObservedSelectedPath = this.store.selectedPath;\n this.savePersistedStateIfChanged();\n void this.previewController.syncPreviewState();\n this.warmOpenWithApplicationsCache(this.store.entries);\n });\n }\n\n private warmOpenWithApplicationsCache(\n entries: WorkspaceFileManagerState[\"entries\"]\n ): void {\n if (!this.host.listOpenWithApplications || this.store.isLoading) {\n return;\n }\n this.openWithApplicationsCache.scheduleWarmup(entries, (entry) =>\n this.listOpenWithApplications(entry)\n );\n }\n\n private savePersistedStateIfChanged(): void {\n if (!this.persistence?.save) {\n return;\n }\n const nextState = this.getPersistedState();\n const serialized = serializePersistedState(nextState);\n if (serialized === this.lastObservedPersistedState) {\n return;\n }\n this.lastObservedPersistedState = serialized;\n this.persistence.save(nextState);\n }\n\n private resolveErrorMessage(\n error: unknown,\n overrides: Record<string, string | undefined> = {}\n ): string {\n const filteredOverrides = Object.fromEntries(\n Object.entries(overrides).filter((entry) => entry[1] !== undefined)\n ) as Record<string, string>;\n if (this.host.resolveErrorMessage) {\n return this.host.resolveErrorMessage(error, filteredOverrides);\n }\n\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n typeof (error as { code?: unknown }).code === \"string\"\n ) {\n const override = filteredOverrides[(error as { code: string }).code];\n if (override) {\n return override;\n }\n }\n\n return this.copy.t(\"unknownErrorMessage\");\n }\n}\n\nfunction isPreviewStateForPath(\n previewState: WorkspaceFileManagerState[\"previewState\"],\n path: string\n): boolean {\n return \"entry\" in previewState && previewState.entry.path === path;\n}\n\nfunction serializePersistedState(\n state: WorkspaceFileManagerPersistedState\n): string {\n return JSON.stringify(state);\n}\n\nfunction areWorkspaceFilePathsEqual(left: string, right: string): boolean {\n return normalizeWorkspaceFilePath(left) === normalizeWorkspaceFilePath(right);\n}\n\nfunction isWorkspaceFilePathWithinDirectory(\n path: string,\n directoryPath: string\n): boolean {\n const normalizedPath = normalizeWorkspaceFilePath(path);\n const normalizedDirectoryPath = normalizeWorkspaceFilePath(directoryPath);\n return (\n normalizedPath === normalizedDirectoryPath ||\n normalizedDirectoryPath === \"/\" ||\n normalizedPath.startsWith(`${normalizedDirectoryPath}/`)\n );\n}\n","import { resolveWorkspaceFileActivationTarget } from \"../workspaceFileManagerModel.ts\";\nimport type { WorkspaceFileManagerI18nRuntime } from \"../../i18n/workspaceFileManagerI18n.ts\";\nimport type { WorkspaceFileManagerHost } from \"../workspaceFileManagerHost.interface.ts\";\nimport type {\n WorkspaceFileManagerFileActivationRequest,\n WorkspaceFileManagerHostFallbackAction,\n WorkspaceFileManagerHostFileActivationResult\n} from \"../workspaceFileManagerHostTypes.ts\";\nimport type {\n WorkspaceFileEntry,\n WorkspaceFileManagerFileDefaultOpener,\n WorkspaceFileManagerState\n} from \"../workspaceFileManagerTypes.ts\";\n\nexport interface WorkspaceFileManagerActivationControllerInput {\n copy: () => WorkspaceFileManagerI18nRuntime;\n host: WorkspaceFileManagerHost;\n loadDirectory: (path: string) => Promise<void>;\n resolveErrorMessage: (\n error: unknown,\n overrides?: Record<string, string | undefined>\n ) => string;\n resolveFileDefaultOpener?: (\n entry: WorkspaceFileEntry\n ) => WorkspaceFileManagerFileDefaultOpener | null | undefined;\n store: WorkspaceFileManagerState;\n}\n\nexport class WorkspaceFileManagerActivationController {\n private readonly copy: () => WorkspaceFileManagerI18nRuntime;\n private readonly host: WorkspaceFileManagerHost;\n private readonly loadDirectory: (path: string) => Promise<void>;\n private readonly resolveErrorMessage: (\n error: unknown,\n overrides?: Record<string, string | undefined>\n ) => string;\n private readonly resolveFileDefaultOpener?: (\n entry: WorkspaceFileEntry\n ) => WorkspaceFileManagerFileDefaultOpener | null | undefined;\n private readonly store: WorkspaceFileManagerState;\n\n constructor(input: WorkspaceFileManagerActivationControllerInput) {\n this.copy = input.copy;\n this.host = input.host;\n this.loadDirectory = input.loadDirectory;\n this.resolveErrorMessage = input.resolveErrorMessage;\n this.resolveFileDefaultOpener = input.resolveFileDefaultOpener;\n this.store = input.store;\n }\n\n async activateFile(\n request: WorkspaceFileManagerFileActivationRequest\n ): Promise<WorkspaceFileManagerHostFileActivationResult> {\n const copy = this.copy();\n if (!this.host.activateFile) {\n return {\n disposition: \"unsupported\",\n message: copy.t(\"unsupportedViewBody\", { name: request.entry.name }),\n title: copy.t(\"unsupportedViewTitle\")\n } as const;\n }\n\n try {\n const result = await this.host.activateFile(\n request,\n this.store.workspaceID\n );\n if (result.disposition !== \"fallback\" || !result.actions) {\n return result;\n }\n\n const fallbackActionKinds = new Set(\n result.actions.map((action) => action.kind)\n );\n return {\n ...result,\n actions: result.actions.map((action) =>\n this.wrapFallbackAction(action, copy)\n ),\n message:\n result.message ??\n (fallbackActionKinds.has(\"download\")\n ? copy.t(\"previewUnavailableDownloadBody\", {\n name: request.entry.name\n })\n : copy.t(\"previewUnavailableOpenBody\", {\n name: request.entry.name\n })),\n title: result.title ?? copy.t(\"previewUnavailableTitle\")\n };\n } catch (error) {\n return {\n actions: [\n {\n kind: \"open\",\n label: copy.t(\"retryLabel\"),\n onSelect: async () => this.activateFile(request)\n }\n ],\n disposition: \"unsupported\",\n message: this.resolveErrorMessage(error),\n title: copy.t(\"openFailedTitle\")\n } as const;\n }\n }\n\n async handleFallbackAction(\n action: WorkspaceFileManagerHostFallbackAction\n ): Promise<void> {\n if (action.kind === \"none\" || !action.onSelect) {\n return;\n }\n\n const entryPath = this.store.unsupportedDialog?.entryPath ?? null;\n const entry = entryPath ? this.findEntry(entryPath) : null;\n this.store.busyAction = \"view\";\n try {\n const result = await action.onSelect();\n if (!entry) {\n this.store.unsupportedDialog = null;\n return;\n }\n this.applyActivationResult(result, entry);\n } finally {\n this.store.busyAction = null;\n }\n }\n\n async openEntry(entry: WorkspaceFileEntry): Promise<void> {\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n\n if (entry.kind === \"directory\") {\n this.store.pendingDirectoryPath = entry.path;\n try {\n await this.loadDirectory(entry.path);\n } finally {\n if (this.store.pendingDirectoryPath === entry.path) {\n this.store.pendingDirectoryPath = null;\n }\n }\n return;\n }\n\n const opener = this.resolveFileDefaultOpener?.(entry) ?? null;\n if (opener && opener !== \"fileViewer\") {\n const handled = await this.openFileWithConfiguredOpener(entry, opener);\n if (handled) {\n return;\n }\n }\n\n await this.openFileInFileViewer(entry);\n }\n\n async openFileInFileViewer(entry: WorkspaceFileEntry): Promise<void> {\n this.store.contextMenu = null;\n this.store.contextMenuEntryPath = null;\n this.store.busyAction = \"view\";\n try {\n const result = await this.activateFile({\n entry,\n target: resolveWorkspaceFileActivationTarget(entry)\n });\n this.applyActivationResult(result, entry);\n } finally {\n this.store.busyAction = null;\n }\n }\n\n private async openFileWithConfiguredOpener(\n entry: WorkspaceFileEntry,\n opener: WorkspaceFileManagerFileDefaultOpener\n ): Promise<boolean> {\n switch (opener) {\n case \"appBrowser\":\n if (!this.host.openFileInAppBrowser) {\n return false;\n }\n await this.host.openFileInAppBrowser({\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n return true;\n case \"defaultBrowser\":\n if (!this.host.openFileInDefaultBrowser) {\n return false;\n }\n await this.host.openFileInDefaultBrowser({\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n return true;\n case \"system\":\n if (!this.host.openFileInSystemDefault) {\n return false;\n }\n await this.host.openFileInSystemDefault({\n path: entry.path,\n workspaceID: this.store.workspaceID\n });\n return true;\n case \"fileViewer\":\n return false;\n }\n }\n\n private applyActivationResult(\n result: WorkspaceFileManagerHostFileActivationResult | void,\n entry: WorkspaceFileEntry\n ): void {\n if (!result || result.disposition === \"handled\") {\n this.store.unsupportedDialog = null;\n return;\n }\n\n this.store.unsupportedDialog = {\n actions: result.actions ?? null,\n entryPath: entry.path,\n kind: \"view\",\n message: result.message,\n title: result.title\n };\n }\n\n private findEntry(entryPath: string): WorkspaceFileEntry | null {\n return this.store.entries.find((entry) => entry.path === entryPath) ?? null;\n }\n\n private wrapFallbackAction(\n action: WorkspaceFileManagerHostFallbackAction,\n copy: WorkspaceFileManagerI18nRuntime\n ): WorkspaceFileManagerHostFallbackAction {\n if (action.kind === \"none\" || !action.onSelect) {\n return action;\n }\n\n return {\n ...action,\n onSelect: async () => {\n try {\n return await action.onSelect();\n } catch (error) {\n return {\n actions: [\n this.wrapFallbackAction(\n {\n ...action,\n label: copy.t(\"retryLabel\")\n },\n copy\n )\n ],\n disposition: \"unsupported\",\n message: this.resolveErrorMessage(error),\n title:\n action.kind === \"download\"\n ? copy.t(\"downloadFailedTitle\")\n : copy.t(\"openFailedTitle\")\n } as const;\n }\n }\n };\n }\n}\n","import type {\n WorkspaceFileEntry,\n WorkspaceFileManagerState\n} from \"../../workspaceFileManagerTypes.ts\";\nimport { workspaceFileSearchEntryToEntry } from \"./searchEntries.ts\";\n\nexport function findWorkspaceFileEntry(\n state: WorkspaceFileManagerState,\n entryPath: string | null | undefined\n): WorkspaceFileEntry | null {\n if (!entryPath) {\n return null;\n }\n\n const directEntry = state.entries.find((entry) => entry.path === entryPath);\n if (directEntry) {\n return directEntry;\n }\n\n for (const directoryState of Object.values(state.directoryExpansionByPath)) {\n const nestedEntry = directoryState.entries.find(\n (entry) => entry.path === entryPath\n );\n if (nestedEntry) {\n return nestedEntry;\n }\n }\n\n const searchEntry = state.searchEntries.find(\n (entry) => entry.path === entryPath\n );\n if (searchEntry) {\n return workspaceFileSearchEntryToEntry(searchEntry);\n }\n\n return null;\n}\n","import {\n normalizeWorkspaceFilePath,\n workspaceFileDirectory\n} from \"../workspaceFileManagerModel.ts\";\nimport type {\n WorkspaceFileManagerHost,\n WorkspaceFileManagerMutationErrorMessage\n} from \"../workspaceFileManagerHost.interface.ts\";\nimport type {\n WorkspaceFileEntry,\n WorkspaceFileEntryKind,\n WorkspaceFileManagerState\n} from \"../workspaceFileManagerTypes.ts\";\nimport { findWorkspaceFileEntry } from \"./model/entryLookup.ts\";\n\nexport interface WorkspaceFileManagerMutationControllerInput {\n host: WorkspaceFileManagerHost;\n onErrorMessage?: (\n message: WorkspaceFileManagerMutationErrorMessage\n ) => boolean | void;\n refresh: () => Promise<void>;\n resolveErrorMessage: (error: unknown) => string;\n store: WorkspaceFileManagerState;\n}\n\nexport class WorkspaceFileManagerMutationController {\n private readonly host: WorkspaceFileManagerHost;\n private readonly onErrorMessage?: (\n message: WorkspaceFileManagerMutationErrorMessage\n ) => boolean | void;\n private readonly refresh: () => Promise<void>;\n private readonly resolveErrorMessage: (error: unknown) => string;\n private readonly store: WorkspaceFileManagerState;\n\n constructor(input: WorkspaceFileManagerMutationControllerInput) {\n this.host = input.host;\n this.onErrorMessage = input.onErrorMessage;\n this.refresh = input.refresh;\n this.resolveErrorMessage = input.resolveErrorMessage;\n this.store = input.store;\n }\n\n async createDirectory(path: string): Promise<void> {\n if (!this.host.createDirectory) {\n return;\n }\n await this.mutate(\n \"create\",\n () =>\n this.host.createDirectory?.({\n path: normalizeWorkspaceFilePath(path, this.store.root),\n workspaceID: this.store.workspaceID\n }) ?? Promise.resolve()\n );\n }\n\n async createFile(path: string): Promise<void> {\n if (!this.host.createFile) {\n return;\n }\n await this.mutate(\n \"create\",\n () =>\n this.host.createFile?.({\n path: normalizeWorkspaceFilePath(path, this.store.root),\n workspaceID: this.store.workspaceID\n }) ?? Promise.resolve()\n );\n }\n\n async deleteSelected(): Promise<void> {\n if (!this.host.deleteEntry || !this.store.selectedPath) {\n return;\n }\n\n const entry = findWorkspaceFileEntry(this.store, this.store.selectedPath);\n await this.mutate(\n \"delete\",\n () =>\n this.host.deleteEntry?.({\n kind: entryKindForDelete(entry?.kind),\n path: this.store.selectedPath ?? \"\",\n workspaceID: this.store.workspaceID\n }) ?? Promise.resolve()\n );\n this.store.selectedPath = null;\n }\n\n async moveEntry(\n entry: WorkspaceFileEntry,\n targetDirectoryPath: string\n ): Promise<void> {\n if (!this.host.moveEntry || entry.kind === \"unknown\") {\n return;\n }\n\n const entryKind = entry.kind;\n const normalizedTargetDirectoryPath = normalizeWorkspaceFilePath(\n targetDirectoryPath,\n this.store.root\n );\n if (entry.path === normalizedTargetDirectoryPath) {\n return;\n }\n if (\n entry.kind === \"directory\" &&\n normalizedTargetDirectoryPath.startsWith(`${entry.path}/`)\n ) {\n return;\n }\n if (\n workspaceFileDirectory(entry.path, this.store.root) ===\n normalizedTargetDirectoryPath\n ) {\n return;\n }\n\n let movedPath: string | null = null;\n await this.mutate(\"move\", async () => {\n const movedEntry =\n (await this.host.moveEntry?.({\n kind: entryKind,\n path: entry.path,\n targetDirectoryPath: normalizedTargetDirectoryPath,\n workspaceID: this.store.workspaceID\n })) ?? null;\n movedPath = movedEntry?.path ?? null;\n });\n this.store.selectedPath = movedPath;\n }\n\n async renameEntry(entry: WorkspaceFileEntry, newName: string): Promise<void> {\n if (!this.host.renameEntry) {\n return;\n }\n\n let renamedPath: string | null = null;\n await this.mutate(\"rename\", async () => {\n const renamedEntry =\n (await this.host.renameEntry?.({\n newName: newName.trim(),\n path: entry.path,\n workspaceID: this.store.workspaceID\n })) ?? null;\n renamedPath = renamedEntry?.path ?? null;\n });\n this.store.selectedPath = renamedPath;\n }\n\n private async mutate(\n actionKind: WorkspaceFileManagerMutationErrorMessage[\"actionKind\"],\n operation: () => Promise<unknown>\n ): Promise<void> {\n this.store.isMutating = true;\n this.store.error = null;\n try {\n await operation();\n await this.refresh();\n } catch (error) {\n const message = this.resolveErrorMessage(error);\n const handled = this.onErrorMessage?.({\n actionKind,\n error,\n message\n });\n if (!handled) {\n this.store.error = message;\n }\n } finally {\n this.store.isMutating = false;\n }\n }\n}\n\nfunction entryKindForDelete(\n kind: WorkspaceFileEntryKind | undefined\n): \"file\" | \"directory\" | null {\n if (kind === \"file\" || kind === \"directory\") {\n return kind;\n }\n return null;\n}\n","import {\n normalizeWorkspaceFilePath,\n sortWorkspaceEntries,\n workspaceFileDirectory,\n workspaceFilePathHasHiddenSegment\n} from \"../workspaceFileManagerModel.ts\";\nimport type { WorkspaceFileManagerHost } from \"../workspaceFileManagerHost.interface.ts\";\nimport type { WorkspaceFileManagerState } from \"../workspaceFileManagerTypes.ts\";\n\nexport interface WorkspaceFileManagerNavigationControllerInput {\n host: WorkspaceFileManagerHost;\n resolveErrorMessage: (error: unknown) => string;\n store: WorkspaceFileManagerState;\n}\n\nexport class WorkspaceFileManagerNavigationController {\n private readonly host: WorkspaceFileManagerHost;\n private readonly resolveErrorMessage: (error: unknown) => string;\n private readonly store: WorkspaceFileManagerState;\n private requestSeq = 0;\n /** Counts performLoad/reveal/replace calls so superseded requests cannot leave isLoading latched. */\n private activeLoadCount = 0;\n /**\n * Same-path loads share one in-flight promise. Concurrent initialize/reveal/\n * remount callers used to bump requestSeq and let a faster empty response\n * discard a slower successful listing.\n */\n private readonly inFlightLoadByPath = new Map<string, Promise<void>>();\n\n constructor(input: WorkspaceFileManagerNavigationControllerInput) {\n this.host = input.host;\n this.resolveErrorMessage = input.resolveErrorMessage;\n this.store = input.store;\n }\n\n private beginLoad(): number {\n const requestID = ++this.requestSeq;\n this.activeLoadCount += 1;\n this.store.isLoading = true;\n this.store.error = null;\n return requestID;\n }\n\n private endLoad(requestID: number): void {\n this.activeLoadCount = Math.max(0, this.activeLoadCount - 1);\n if (requestID === this.requestSeq || this.activeLoadCount === 0) {\n this.store.isLoading = false;\n }\n }\n\n async goBack(): Promise<void> {\n const previous = this.store.navigationBackStack.pop();\n if (!previous) {\n return;\n }\n this.store.navigationForwardStack.push(this.store.currentDirectoryPath);\n await this.replaceDirectory(previous);\n }\n\n async goForward(): Promise<void> {\n const next = this.store.navigationForwardStack.pop();\n if (!next) {\n return;\n }\n this.store.navigationBackStack.push(this.store.currentDirectoryPath);\n await this.replaceDirectory(next);\n }\n\n async loadDirectory(path = this.store.currentDirectoryPath): Promise<void> {\n const normalizedPath = normalizeWorkspaceFilePath(path, this.store.root);\n const existing = this.inFlightLoadByPath.get(normalizedPath);\n if (existing) {\n await existing;\n return;\n }\n\n const run = this.performLoadDirectory(normalizedPath);\n this.inFlightLoadByPath.set(normalizedPath, run);\n try {\n await run;\n } finally {\n if (this.inFlightLoadByPath.get(normalizedPath) === run) {\n this.inFlightLoadByPath.delete(normalizedPath);\n }\n }\n }\n\n async refresh(): Promise<void> {\n await this.loadDirectory(this.store.currentDirectoryPath);\n }\n\n private async performLoadDirectory(normalizedPath: string): Promise<void> {\n const requestID = this.beginLoad();\n\n try {\n const listing = await this.host.listDirectory({\n includeHidden: workspaceFilePathHasHiddenSegment(normalizedPath),\n path: this.resolveRequestPath(normalizedPath),\n workspaceID: this.store.workspaceID\n });\n if (requestID !== this.requestSeq) {\n // Same-path coalescing covers the common remount race. Still recover\n // when a superseded response has entries and the store is empty for\n // that directory (e.g. empty prefetch won, then network returned data).\n if (\n listing.entries.length > 0 &&\n this.store.entries.length === 0 &&\n this.store.error === null &&\n normalizeWorkspaceFilePath(listing.directoryPath, listing.root) ===\n normalizeWorkspaceFilePath(\n this.store.currentDirectoryPath,\n this.store.root\n )\n ) {\n this.store.root = normalizeWorkspaceFilePath(listing.root);\n this.store.currentDirectoryPath = listing.directoryPath;\n this.store.entries = sortWorkspaceEntries(listing.entries);\n this.store.directoryExpansionByPath = {};\n this.store.expandedDirectoryPaths = {};\n }\n return;\n }\n\n const previousDirectoryPath = this.store.currentDirectoryPath;\n if (\n previousDirectoryPath !== listing.directoryPath &&\n previousDirectoryPath !== \"/\"\n ) {\n this.store.navigationBackStack.push(this.store.currentDirectoryPath);\n this.store.navigationForwardStack = [];\n }\n this.store.root = normalizeWorkspaceFilePath(listing.root);\n this.store.currentDirectoryPath = listing.directoryPath;\n this.store.entries = sortWorkspaceEntries(listing.entries);\n this.store.directoryExpansionByPath = {};\n this.store.expandedDirectoryPaths = {};\n this.store.selectedPath = null;\n } catch (error) {\n if (requestID === this.requestSeq) {\n this.store.error = this.resolveErrorMessage(error);\n }\n } finally {\n this.endLoad(requestID);\n }\n }\n\n async revealPath(path: string): Promise<void> {\n const normalizedPath = normalizeWorkspaceFilePath(path, this.store.root);\n const directoryPath = workspaceFileDirectory(\n normalizedPath,\n this.store.root\n );\n const requestID = this.beginLoad();\n\n try {\n const listing = await this.host.listDirectory({\n includeHidden: workspaceFilePathHasHiddenSegment(normalizedPath),\n path: this.resolveRequestPath(directoryPath),\n workspaceID: this.store.workspaceID\n });\n if (requestID !== this.requestSeq) {\n return;\n }\n\n const previousDirectoryPath = this.store.currentDirectoryPath;\n if (\n previousDirectoryPath !== listing.directoryPath &&\n previousDirectoryPath !== \"/\"\n ) {\n this.store.navigationBackStack.push(this.store.currentDirectoryPath);\n this.store.navigationForwardStack = [];\n }\n this.store.root = normalizeWorkspaceFilePath(listing.root);\n this.store.currentDirectoryPath = listing.directoryPath;\n this.store.entries = sortWorkspaceEntries(listing.entries);\n this.store.directoryExpansionByPath = {};\n this.store.expandedDirectoryPaths = {};\n this.store.selectedPath = normalizedPath;\n } catch (error) {\n if (requestID === this.requestSeq) {\n this.store.error = this.resolveErrorMessage(error);\n }\n } finally {\n this.endLoad(requestID);\n }\n }\n\n private async replaceDirectory(path: string): Promise<void> {\n const normalizedPath = normalizeWorkspaceFilePath(path, this.store.root);\n const requestID = this.beginLoad();\n try {\n const listing = await this.host.listDirectory({\n includeHidden: workspaceFilePathHasHiddenSegment(normalizedPath),\n path: this.resolveRequestPath(normalizedPath),\n workspaceID: this.store.workspaceID\n });\n if (requestID !== this.requestSeq) {\n return;\n }\n this.store.root = normalizeWorkspaceFilePath(listing.root);\n this.store.currentDirectoryPath = listing.directoryPath;\n this.store.entries = sortWorkspaceEntries(listing.entries);\n this.store.directoryExpansionByPath = {};\n this.store.expandedDirectoryPaths = {};\n this.store.selectedPath = null;\n } catch (error) {\n if (requestID === this.requestSeq) {\n this.store.error = this.resolveErrorMessage(error);\n }\n } finally {\n this.endLoad(requestID);\n }\n }\n\n private resolveRequestPath(path: string): string {\n if (this.store.root === \"/\" && path === \"/\") {\n return \"\";\n }\n return path;\n }\n}\n","import {\n createWorkspaceFilePreviewController,\n formatWorkspacePreviewByteLimit,\n workspaceFilePreviewMaxBytes,\n type WorkspaceFilePreviewController,\n type WorkspaceFilePreviewControllerState,\n type WorkspaceFilePreviewReadonlyReason\n} from \"@tutti-os/workspace-file-preview\";\nimport { resolveWorkspaceFileActivationTarget } from \"../workspaceFileManagerModel.ts\";\nimport type { WorkspaceFileManagerI18nRuntime } from \"../../i18n/workspaceFileManagerI18n.ts\";\nimport type { WorkspaceFileManagerHost } from \"../workspaceFileManagerHost.interface.ts\";\nimport type {\n WorkspaceFileEntry,\n WorkspaceFileManagerState\n} from \"../workspaceFileManagerTypes.ts\";\nimport { findWorkspaceFileEntry } from \"./model/entryLookup.ts\";\n\nexport interface WorkspaceFileManagerPreviewControllerInput {\n copy: () => WorkspaceFileManagerI18nRuntime;\n host: WorkspaceFileManagerHost;\n resolveErrorMessage: (\n error: unknown,\n overrides?: Record<string, string | undefined>\n ) => string;\n store: WorkspaceFileManagerState;\n}\n\nexport class WorkspaceFileManagerPreviewController {\n private readonly copy: () => WorkspaceFileManagerI18nRuntime;\n private readonly resolveErrorMessage: (\n error: unknown,\n overrides?: Record<string, string | undefined>\n ) => string;\n private readonly store: WorkspaceFileManagerState;\n private readonly previewController: WorkspaceFilePreviewController<WorkspaceFileEntry>;\n private readonly unsubscribePreview: () => void;\n\n constructor(input: WorkspaceFileManagerPreviewControllerInput) {\n this.copy = input.copy;\n this.resolveErrorMessage = input.resolveErrorMessage;\n this.store = input.store;\n this.previewController = createWorkspaceFilePreviewController({\n read: input.host.readPreviewFile\n ? async ({ entry }) => {\n const bytes = await input.host.readPreviewFile!(\n input.store.workspaceID,\n entry.path\n );\n return bytes == null ? null : { bytes };\n }\n : undefined,\n toPreviewEntry: (entry: WorkspaceFileEntry) => entry\n });\n this.unsubscribePreview = this.previewController.subscribe(() => {\n this.applyPreviewState(this.previewController.getSnapshot());\n });\n }\n\n dispose(): void {\n this.unsubscribePreview();\n this.previewController.dispose();\n }\n\n async syncPreviewState(): Promise<void> {\n const selectedEntry = findWorkspaceFileEntry(\n this.store,\n this.store.selectedPath\n );\n const settled = this.previewController.setEntry(selectedEntry);\n await settled;\n this.applyPreviewState(this.previewController.getSnapshot());\n }\n\n private applyPreviewState(\n state: WorkspaceFilePreviewControllerState<WorkspaceFileEntry>\n ): void {\n const copy = this.copy();\n switch (state.status) {\n case \"empty\":\n this.store.previewState = state;\n return;\n case \"directory\":\n this.store.previewState = state;\n return;\n case \"loading\":\n case \"text\":\n case \"image\":\n case \"video\": {\n const target = resolveWorkspaceFileActivationTarget(state.entry);\n if (!target) {\n this.store.previewState = {\n entry: state.entry,\n message: copy.t(\"previewUnsupported\"),\n status: \"unsupported\"\n };\n return;\n }\n if (state.status === \"loading\") {\n this.store.previewState = {\n entry: target,\n previewKind: state.previewKind,\n status: \"loading\"\n };\n return;\n }\n if (state.status === \"text\") {\n this.store.previewState = {\n content: state.content,\n entry: target,\n previewKind: state.previewKind,\n status: \"text\"\n };\n return;\n }\n if (state.status === \"image\") {\n this.store.previewState = {\n entry: target,\n objectUrl: state.objectUrl,\n previewKind: \"image\",\n status: \"image\"\n };\n return;\n }\n this.store.previewState = {\n entry: target,\n objectUrl: state.objectUrl,\n previewKind: \"video\",\n status: \"video\"\n };\n return;\n }\n case \"bytes\":\n this.store.previewState = {\n entry: state.entry,\n message: copy.t(\"previewUnsupported\"),\n status: \"unsupported\"\n };\n return;\n case \"readonly\":\n this.store.previewState = {\n entry: state.entry,\n message: resolveWorkspaceFileManagerPreviewReadonlyMessage(\n copy,\n state.reason,\n state.maxSizeBytes\n ),\n status: \"readonly\"\n };\n return;\n case \"unsupported\":\n this.store.previewState = {\n entry: state.entry,\n message: copy.t(\"previewUnsupported\"),\n status: \"unsupported\"\n };\n return;\n case \"error\":\n this.store.previewState = {\n entry: state.entry,\n message: this.resolveErrorMessage(state.error, {\n preview_file_too_large: copy.t(\"previewFileTooLarge\", {\n maxSize: formatWorkspacePreviewByteLimit(\n workspaceFilePreviewMaxBytes\n )\n })\n }),\n status: \"error\"\n };\n }\n }\n}\n\nfunction resolveWorkspaceFileManagerPreviewReadonlyMessage(\n copy: WorkspaceFileManagerI18nRuntime,\n reason: WorkspaceFilePreviewReadonlyReason,\n maxSizeBytes?: number\n): string {\n switch (reason) {\n case \"binary\":\n return copy.t(\"previewBinary\");\n case \"decode_failed\":\n return copy.t(\"previewDecodeFailed\");\n case \"file_too_large\":\n return copy.t(\"previewFileTooLarge\", {\n maxSize: formatWorkspacePreviewByteLimit(maxSizeBytes ?? 0)\n });\n case \"text_too_large\":\n return copy.t(\"previewTooLarge\", {\n maxSize: formatWorkspacePreviewByteLimit(maxSizeBytes ?? 0)\n });\n }\n}\n","import {\n normalizeWorkspaceFilePath,\n sortWorkspaceEntries,\n workspaceFilePathHasHiddenSegment\n} from \"../workspaceFileManagerModel.ts\";\nimport type { WorkspaceFileManagerHost } from \"../workspaceFileManagerHost.interface.ts\";\nimport type {\n WorkspaceFileEntry,\n WorkspaceFileManagerState\n} from \"../workspaceFileManagerTypes.ts\";\n\nexport interface WorkspaceFileManagerTreeControllerInput {\n host: WorkspaceFileManagerHost;\n resolveErrorMessage: (error: unknown) => string;\n store: WorkspaceFileManagerState;\n}\n\nexport class WorkspaceFileManagerTreeController {\n private readonly host: WorkspaceFileManagerHost;\n private readonly resolveErrorMessage: (error: unknown) => string;\n private readonly requestSeqByPath = new Map<string, number>();\n private readonly store: WorkspaceFileManagerState;\n\n constructor(input: WorkspaceFileManagerTreeControllerInput) {\n this.host = input.host;\n this.resolveErrorMessage = input.resolveErrorMessage;\n this.store = input.store;\n }\n\n clear(): void {\n this.requestSeqByPath.clear();\n this.store.directoryExpansionByPath = {};\n this.store.expandedDirectoryPaths = {};\n }\n\n async toggleDirectoryExpanded(entry: WorkspaceFileEntry): Promise<void> {\n if (entry.kind !== \"directory\" || !entry.hasChildren) {\n return;\n }\n\n const directoryPath = normalizeWorkspaceFilePath(\n entry.path,\n this.store.root\n );\n if (this.store.expandedDirectoryPaths[directoryPath]) {\n this.store.expandedDirectoryPaths = {\n ...this.store.expandedDirectoryPaths,\n [directoryPath]: false\n };\n return;\n }\n\n this.store.expandedDirectoryPaths = {\n ...this.store.expandedDirectoryPaths,\n [directoryPath]: true\n };\n\n const currentState = this.store.directoryExpansionByPath[directoryPath];\n if (currentState?.loaded || currentState?.isLoading) {\n return;\n }\n\n await this.loadDirectoryChildren(directoryPath);\n }\n\n private async loadDirectoryChildren(directoryPath: string): Promise<void> {\n const requestSeq = (this.requestSeqByPath.get(directoryPath) ?? 0) + 1;\n this.requestSeqByPath.set(directoryPath, requestSeq);\n\n const previousState = this.store.directoryExpansionByPath[directoryPath];\n this.store.directoryExpansionByPath = {\n ...this.store.directoryExpansionByPath,\n [directoryPath]: {\n entries: previousState?.entries ?? [],\n error: null,\n isLoading: true,\n loaded: previousState?.loaded ?? false\n }\n };\n\n try {\n const listing = await this.host.listDirectory({\n includeHidden: workspaceFilePathHasHiddenSegment(directoryPath),\n path: this.resolveRequestPath(directoryPath),\n workspaceID: this.store.workspaceID\n });\n if (this.requestSeqByPath.get(directoryPath) !== requestSeq) {\n return;\n }\n\n this.store.directoryExpansionByPath = {\n ...this.store.directoryExpansionByPath,\n [directoryPath]: {\n entries: sortWorkspaceEntries(listing.entries),\n error: null,\n isLoading: false,\n loaded: true\n }\n };\n } catch (error) {\n if (this.requestSeqByPath.get(directoryPath) !== requestSeq) {\n return;\n }\n\n this.store.directoryExpansionByPath = {\n ...this.store.directoryExpansionByPath,\n [directoryPath]: {\n entries: previousState?.entries ?? [],\n error: this.resolveErrorMessage(error),\n isLoading: false,\n loaded: false\n }\n };\n }\n }\n\n private resolveRequestPath(path: string): string {\n if (this.store.root === \"/\" && path === \"/\") {\n return \"\";\n }\n return path;\n }\n}\n","import {\n createWorkspaceFileManagerStore,\n normalizeWorkspaceFileManagerPersistedState\n} from \"./workspaceFileManagerStore.ts\";\nimport { DefaultWorkspaceFileManagerSession } from \"./workspaceFileManagerSession.ts\";\nimport type { WorkspaceFileManagerService } from \"../workspaceFileManagerService.interface.ts\";\nimport type { CreateWorkspaceFileManagerSessionInput } from \"../workspaceFileManagerHost.interface.ts\";\nimport type { WorkspaceFileManagerCapabilities } from \"../workspaceFileManagerTypes.ts\";\n\nexport class DefaultWorkspaceFileManagerService implements WorkspaceFileManagerService {\n createSession(input: CreateWorkspaceFileManagerSessionInput) {\n const capabilities = capabilitiesFromHost(input);\n const store = createWorkspaceFileManagerStore({\n capabilities,\n defaultLocationId: input.defaultLocationId,\n initialDirectoryPath: input.initialDirectoryPath,\n locationSections: input.locationSections,\n persistedState: normalizeWorkspaceFileManagerPersistedState(\n input.persistedState ?? input.persistence?.load?.()\n ),\n workspaceID: input.workspaceID\n });\n\n return new DefaultWorkspaceFileManagerSession({\n copy: input.i18n,\n host: input.host,\n onMutationErrorMessage: input.onMutationErrorMessage,\n persistence: input.persistence,\n resolveFileDefaultOpener: input.resolveFileDefaultOpener,\n store\n });\n }\n}\n\nfunction capabilitiesFromHost(\n input: CreateWorkspaceFileManagerSessionInput\n): WorkspaceFileManagerCapabilities {\n return {\n canCopy: input.host.copyEntriesToClipboard !== undefined,\n canCreateDirectory: input.host.createDirectory !== undefined,\n canCreateFile: input.host.createFile !== undefined,\n canDelete: input.host.deleteEntry !== undefined,\n canMove: input.host.moveEntry !== undefined,\n canOpenInAppBrowser: input.host.openFileInAppBrowser !== undefined,\n canOpenInDefaultBrowser: input.host.openFileInDefaultBrowser !== undefined,\n canOpenWith: input.host.listOpenWithApplications !== undefined,\n canPickOtherOpenWithApplication:\n input.host.openFileWithOtherApplication !== undefined,\n canRevealInFolder: input.host.revealEntry !== undefined,\n canRename: input.host.renameEntry !== undefined,\n canSearch: input.host.search !== undefined\n };\n}\n","import { DefaultWorkspaceFileManagerService } from \"./internal/workspaceFileManagerService.ts\";\nimport type { WorkspaceFileManagerService } from \"./workspaceFileManagerService.interface.ts\";\n\nexport function createWorkspaceFileManagerService(): WorkspaceFileManagerService {\n return new DefaultWorkspaceFileManagerService();\n}\n","import {\n classifyWorkspaceFilePreviewKind,\n isTextDegradablePreviewKind,\n resolveWorkspaceFileExtension,\n resolveWorkspaceFileVisualKind\n} from \"@tutti-os/workspace-file-preview\";\nimport type { WorkspaceFileEntry } from \"./workspaceFileManagerTypes.ts\";\n\nconst defaultApplicationIconExtensions = new Set([\n \"ai\",\n \"dmg\",\n \"doc\",\n \"docx\",\n \"eps\",\n \"fig\",\n \"indd\",\n \"key\",\n \"numbers\",\n \"odp\",\n \"ods\",\n \"odt\",\n \"pages\",\n \"pkg\",\n \"ppt\",\n \"pptx\",\n \"psd\",\n \"rtf\",\n \"sketch\",\n \"xd\",\n \"xls\",\n \"xlsx\"\n]);\n\nconst archiveIconExtensions = new Set([\n \"7z\",\n \"gz\",\n \"rar\",\n \"tar\",\n \"tgz\",\n \"xz\",\n \"zip\"\n]);\n\nconst extensionDocumentIconExtensions = new Set([\"pdf\"]);\n\nexport interface WorkspaceFileEntryIconPolicyOptions {\n includeImageThumbnails?: boolean;\n}\n\nexport function shouldResolveWorkspaceFileEntryIcon(\n entry: WorkspaceFileEntry,\n options: WorkspaceFileEntryIconPolicyOptions = {}\n): boolean {\n return (\n (options.includeImageThumbnails &&\n shouldResolveWorkspaceFileImageThumbnail(entry)) ||\n isWorkspaceApplicationBundle(entry) ||\n resolveWorkspaceFileDefaultApplicationIconExtension(entry) !== null\n );\n}\n\nexport function shouldUseWorkspaceFileExtensionDocumentIcon(\n entry: WorkspaceFileEntry\n): boolean {\n if (entry.kind !== \"file\") {\n return false;\n }\n\n const visualKind = resolveWorkspaceFileVisualKind(entry);\n const extension = resolveWorkspaceFileExtension(entry.name).toLowerCase();\n return (\n visualKind === \"code\" ||\n visualKind === \"markdown\" ||\n extensionDocumentIconExtensions.has(extension) ||\n isTextDegradablePreviewKind(classifyWorkspaceFilePreviewKind(entry))\n );\n}\n\nexport function shouldUseWorkspaceFileArchiveIcon(\n entry: WorkspaceFileEntry\n): boolean {\n return (\n entry.kind === \"file\" &&\n archiveIconExtensions.has(\n resolveWorkspaceFileExtension(entry.name).toLowerCase()\n )\n );\n}\n\nexport function isWorkspaceApplicationBundle(entry: {\n kind: string;\n name: string;\n}): boolean {\n return (\n entry.kind !== \"file\" && entry.name.trim().toLowerCase().endsWith(\".app\")\n );\n}\n\nexport function resolveWorkspaceFileDefaultApplicationIconExtension(entry: {\n kind: string;\n name: string;\n}): string | null {\n if (entry.kind !== \"file\") {\n return null;\n }\n\n const extension = resolveWorkspaceFileExtension(entry.name).toLowerCase();\n return defaultApplicationIconExtensions.has(extension) ? extension : null;\n}\n\nexport function resolveWorkspaceFileEntryIconCacheKey(\n entry: WorkspaceFileEntry\n): string {\n if (shouldResolveWorkspaceFileImageThumbnail(entry)) {\n return `image-thumbnail:${entry.path}:${entry.mtimeMs ?? 0}`;\n }\n\n if (isWorkspaceApplicationBundle(entry)) {\n return `application:${entry.path}:${entry.mtimeMs ?? 0}`;\n }\n\n const fileTypeExtension =\n resolveWorkspaceFileDefaultApplicationIconExtension(entry);\n if (fileTypeExtension) {\n return `file-type-default-application:${fileTypeExtension}`;\n }\n\n return `default:${entry.path}:${entry.mtimeMs ?? 0}`;\n}\n\nfunction shouldResolveWorkspaceFileImageThumbnail(\n entry: WorkspaceFileEntry\n): boolean {\n return (\n entry.kind === \"file\" && resolveWorkspaceFileVisualKind(entry) === \"image\"\n );\n}\n","import {\n resolveWorkspaceFileExtension,\n resolveWorkspaceFileVisualKind\n} from \"@tutti-os/workspace-file-preview\";\nimport type { WorkspaceFileEntry } from \"../services/workspaceFileManagerTypes.ts\";\n\nexport type WorkspaceFileManagerArrangeMode =\n | \"none\"\n | \"name\"\n | \"kind\"\n | \"application\"\n | \"lastOpened\"\n | \"dateAdded\"\n | \"modified\"\n | \"created\"\n | \"size\";\n\nexport const workspaceFileManagerArrangeModeStorageKey =\n \"tutti.workspace-file-manager.arrange-mode\";\n\nconst workspaceFileManagerArrangeModes =\n new Set<WorkspaceFileManagerArrangeMode>([\n \"none\",\n \"name\",\n \"kind\",\n \"application\",\n \"lastOpened\",\n \"dateAdded\",\n \"modified\",\n \"created\",\n \"size\"\n ]);\n\nexport function readWorkspaceFileManagerArrangeMode(): WorkspaceFileManagerArrangeMode {\n if (typeof window === \"undefined\") {\n return \"none\";\n }\n\n const stored = window.localStorage.getItem(\n workspaceFileManagerArrangeModeStorageKey\n );\n return isWorkspaceFileManagerArrangeMode(stored) ? stored : \"none\";\n}\n\nexport function writeWorkspaceFileManagerArrangeMode(\n arrangeMode: WorkspaceFileManagerArrangeMode\n): void {\n if (typeof window === \"undefined\") {\n return;\n }\n\n window.localStorage.setItem(\n workspaceFileManagerArrangeModeStorageKey,\n arrangeMode\n );\n}\n\nexport function sortWorkspaceFileEntriesForArrangeMode(\n entries: readonly WorkspaceFileEntry[],\n arrangeMode: WorkspaceFileManagerArrangeMode\n): readonly WorkspaceFileEntry[] {\n if (arrangeMode === \"none\") {\n return entries;\n }\n\n return [...entries].sort((left, right) => {\n switch (arrangeMode) {\n case \"name\":\n return (\n compareDirectoryFirst(left, right) || compareEntryName(left, right)\n );\n case \"kind\":\n return (\n compareDirectoryFirst(left, right) ||\n compareText(\n resolveEntryKindGroup(left),\n resolveEntryKindGroup(right)\n ) ||\n compareEntryName(left, right)\n );\n case \"application\":\n return (\n compareDirectoryFirst(left, right) ||\n compareText(\n resolveEntryApplicationGroup(left),\n resolveEntryApplicationGroup(right)\n ) ||\n compareEntryName(left, right)\n );\n case \"lastOpened\":\n return (\n compareDateDescending(left, right, \"lastOpened\") ||\n compareEntryName(left, right)\n );\n case \"dateAdded\":\n return (\n compareDateDescending(left, right, \"dateAdded\") ||\n compareEntryName(left, right)\n );\n case \"modified\":\n return (\n compareDateDescending(left, right, \"modified\") ||\n compareEntryName(left, right)\n );\n case \"created\":\n return (\n compareDateDescending(left, right, \"created\") ||\n compareEntryName(left, right)\n );\n case \"size\":\n return (\n compareSizeDescending(left, right) || compareEntryName(left, right)\n );\n }\n });\n}\n\nfunction isWorkspaceFileManagerArrangeMode(\n value: string | null\n): value is WorkspaceFileManagerArrangeMode {\n return workspaceFileManagerArrangeModes.has(\n value as WorkspaceFileManagerArrangeMode\n );\n}\n\nfunction compareDirectoryFirst(\n left: WorkspaceFileEntry,\n right: WorkspaceFileEntry\n): number {\n const leftRank = left.kind === \"directory\" ? 0 : 1;\n const rightRank = right.kind === \"directory\" ? 0 : 1;\n return leftRank - rightRank;\n}\n\nfunction compareEntryName(\n left: WorkspaceFileEntry,\n right: WorkspaceFileEntry\n): number {\n return compareText(left.name, right.name);\n}\n\nfunction compareText(left: string, right: string): number {\n return left.localeCompare(right, undefined, {\n numeric: true,\n sensitivity: \"base\"\n });\n}\n\nexport function resolveWorkspaceFileEntryArrangeDateMs(\n entry: WorkspaceFileEntry,\n arrangeMode: WorkspaceFileManagerArrangeMode\n): number | null {\n switch (arrangeMode) {\n case \"lastOpened\":\n return entry.lastOpenedMs ?? entry.mtimeMs;\n case \"dateAdded\":\n case \"created\":\n return entry.createdTimeMs ?? entry.mtimeMs;\n case \"modified\":\n default:\n return entry.mtimeMs;\n }\n}\n\nfunction compareDateDescending(\n left: WorkspaceFileEntry,\n right: WorkspaceFileEntry,\n arrangeMode: WorkspaceFileManagerArrangeMode\n): number {\n return (\n (resolveWorkspaceFileEntryArrangeDateMs(right, arrangeMode) ?? 0) -\n (resolveWorkspaceFileEntryArrangeDateMs(left, arrangeMode) ?? 0)\n );\n}\n\nfunction compareSizeDescending(\n left: WorkspaceFileEntry,\n right: WorkspaceFileEntry\n): number {\n return (right.sizeBytes ?? 0) - (left.sizeBytes ?? 0);\n}\n\nfunction resolveEntryKindGroup(entry: WorkspaceFileEntry): string {\n if (entry.kind === \"directory\") {\n return \"directory\";\n }\n return resolveWorkspaceFileVisualKind(entry);\n}\n\nfunction resolveEntryApplicationGroup(entry: WorkspaceFileEntry): string {\n if (entry.kind === \"directory\") {\n return \"folder\";\n }\n if (entry.name.trim().toLowerCase().endsWith(\".app\")) {\n return \"application\";\n }\n return (\n resolveWorkspaceFileExtension(entry.name) || resolveEntryKindGroup(entry)\n );\n}\n"],"mappings":"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","names":["resolveWorkspaceFileExtension","resolveWorkspaceFileExtension","resolveWorkspaceFileVisualKind"]}
@@ -62,7 +62,9 @@ var workspaceFileManagerEn = {
62
62
  revealInFileExplorerLabel: "Reveal in File Explorer",
63
63
  revealInFileManagerLabel: "Reveal in File Manager",
64
64
  revealInFinderLabel: "Reveal in Finder",
65
+ shareLabel: "Share",
65
66
  unknownErrorMessage: "Something went wrong. Please try again.",
67
+ previewActionsLabel: "File actions",
66
68
  previewBinary: "This file looks binary, so the preview stays read-only for now.",
67
69
  previewDecodeFailed: "We couldn't decode this file as UTF-8 text for preview.",
68
70
  previewDirectoryLabel: "Folder",
@@ -141,7 +143,9 @@ var workspaceFileManagerZhCN = {
141
143
  revealInFileExplorerLabel: "\u5728\u6587\u4EF6\u8D44\u6E90\u7BA1\u7406\u5668\u4E2D\u663E\u793A",
142
144
  revealInFileManagerLabel: "\u5728\u6587\u4EF6\u7BA1\u7406\u5668\u4E2D\u663E\u793A",
143
145
  revealInFinderLabel: "\u5728 Finder \u4E2D\u663E\u793A",
146
+ shareLabel: "\u5206\u4EAB",
144
147
  unknownErrorMessage: "\u51FA\u4E86\u70B9\u95EE\u9898\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",
148
+ previewActionsLabel: "\u6587\u4EF6\u64CD\u4F5C",
145
149
  previewBinary: "\u8FD9\u4E2A\u6587\u4EF6\u66F4\u50CF\u4E8C\u8FDB\u5236\u5185\u5BB9\uFF0C\u5F53\u524D\u5148\u4FDD\u6301\u53EA\u8BFB\u5360\u4F4D\u3002",
146
150
  previewDecodeFailed: "\u6682\u65F6\u65E0\u6CD5\u6309 UTF-8 \u6587\u672C\u89E3\u7801\u8FD9\u4E2A\u6587\u4EF6\u3002",
147
151
  previewDirectoryLabel: "\u6587\u4EF6\u5939",
@@ -205,4 +209,4 @@ export {
205
209
  createWorkspaceFileManagerI18nRuntime,
206
210
  resolveRevealInFolderLabel
207
211
  };
208
- //# sourceMappingURL=chunk-EI4ICYY4.js.map
212
+ //# sourceMappingURL=chunk-MWVVTZD5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/i18n/workspaceFileManagerI18n.ts"],"sourcesContent":["import {\n createScopedLocaleObjectsI18nModuleManifest,\n createScopedI18nRuntime,\n type I18nDictionary,\n type I18nRuntime\n} from \"@tutti-os/ui-i18n-runtime\";\n\ntype WorkspaceFileManagerI18nLocale = \"en\" | \"zh-CN\";\nexport const workspaceFileManagerI18nNamespace = \"workspaceFileManager\";\nexport const tuttiI18nModule = createScopedLocaleObjectsI18nModuleManifest({\n localeObjectByLocale: {\n en: \"workspaceFileManagerEn\",\n \"zh-CN\": \"workspaceFileManagerZhCN\"\n },\n name: \"workspace-file-manager\",\n namespace: \"workspaceFileManager\",\n sourceRoot: \"packages/workspace/file-manager/src\"\n});\n\nconst workspaceFileManagerEn = {\n backLabel: \"Back\",\n arrangeApplicationLabel: \"Application\",\n arrangeCreatedLabel: \"Created\",\n arrangeDateAddedLabel: \"Date Added\",\n arrangeKindLabel: \"Kind\",\n arrangeLastOpenedLabel: \"Last Opened\",\n arrangeMenuLabel: \"Arrange\",\n arrangeNoneLabel: \"None\",\n breadcrumbRootLabel: \"workspace\",\n cancelLabel: \"Cancel\",\n closeLabel: \"Close\",\n copyLabel: \"Copy\",\n copyPathLabel: \"Copy path\",\n copyPathSuccessTitle: \"Path copied\",\n copySuccessTitle: \"Copied to clipboard\",\n createActionLabel: \"Create\",\n createDirectoryLabel: \"New folder\",\n createDirectoryPlaceholder: \"Folder name\",\n createFileLabel: \"New file\",\n createFilePlaceholder: \"File name\",\n createNameInvalid: \"Use a valid name without path separators\",\n createNameRequired: \"Enter a name to continue\",\n clearSearchLabel: \"Clear search\",\n deleteConfirmDescription: \"Delete {{name}} from this workspace?\",\n deleteLabel: \"Delete\",\n deletingLabel: \"Deleting...\",\n downloadFailedTitle: \"Download failed\",\n downloadLabel: \"Download\",\n emptyDirectory: \"No visible files in this folder\",\n collapseFolderLabel: \"Collapse folder\",\n expandFolderLabel: \"Expand folder\",\n forwardLabel: \"Forward\",\n loading: \"Loading\",\n modifiedLabel: \"Modified\",\n nameLabel: \"Name\",\n noSearchResults: \"No files matched your search\",\n openFailedTitle: \"Open failed\",\n openLabel: \"Open\",\n openInAppBrowserLabel: \"Tutti built-in browser\",\n openInDefaultBrowserLabel: \"Default Browser\",\n openInFileViewerLabel: \"File viewer\",\n openWithLabel: \"Open With\",\n openWithLoadingLabel: \"Loading apps...\",\n openWithOtherLabel: \"Other...\",\n openWithOtherPickerPrompt: \"Choose an application to open this file:\",\n revealInFileExplorerLabel: \"Reveal in File Explorer\",\n revealInFileManagerLabel: \"Reveal in File Manager\",\n revealInFinderLabel: \"Reveal in Finder\",\n shareLabel: \"Share\",\n unknownErrorMessage: \"Something went wrong. Please try again.\",\n previewActionsLabel: \"File actions\",\n previewBinary:\n \"This file looks binary, so the preview stays read-only for now.\",\n previewDecodeFailed:\n \"We couldn't decode this file as UTF-8 text for preview.\",\n previewDirectoryLabel: \"Folder\",\n previewEmptyLabel: \"Select a file or folder to view details\",\n previewFileTooLarge:\n \"This file is larger than {{maxSize}}, so inline preview is disabled.\",\n previewLoadingLabel: \"Loading preview...\",\n previewTooLarge:\n \"This text file is larger than {{maxSize}}, so inline preview is disabled.\",\n previewUnavailableDownloadBody:\n \"Download {{name}} to open it in another environment.\",\n previewUnavailableOpenBody: \"Open {{name}} in your local app instead.\",\n previewUnavailableTitle: \"Can't preview this file\",\n previewUnsupported: \"Inline preview isn't available for this file type yet.\",\n revealFailedTitle: \"Could not reveal in file manager\",\n renameActionLabel: \"Rename\",\n renameLabel: \"Rename\",\n renamePlaceholder: \"New name\",\n refreshLabel: \"Refresh\",\n resizeLocationsSidebar: \"Resize locations sidebar\",\n resizePreviewPanel: \"Resize file details panel\",\n retryLabel: \"Retry\",\n searchPlaceholder: \"Search files\",\n searchResultsLabel: \"Search results\",\n sizeLabel: \"Size\",\n unsupportedViewBody:\n \"Opening {{name}} from the file manager is not supported in this desktop build yet.\",\n unsupportedViewTitle: \"Open not available yet\",\n layoutIconViewLabel: \"Icon view\",\n layoutIconViewTooltipLabel: \"Icon mode\",\n layoutListViewLabel: \"List view\",\n layoutListViewTooltipLabel: \"List mode\"\n} as const satisfies I18nDictionary;\n\nconst workspaceFileManagerZhCN = {\n backLabel: \"后退\",\n arrangeApplicationLabel: \"应用程序\",\n arrangeCreatedLabel: \"创建日期\",\n arrangeDateAddedLabel: \"添加日期\",\n arrangeKindLabel: \"种类\",\n arrangeLastOpenedLabel: \"上次打开日期\",\n arrangeMenuLabel: \"排列方式\",\n arrangeNoneLabel: \"无\",\n breadcrumbRootLabel: \"工作区\",\n cancelLabel: \"取消\",\n closeLabel: \"关闭\",\n copyLabel: \"复制\",\n copyPathLabel: \"复制路径\",\n copyPathSuccessTitle: \"复制成功\",\n copySuccessTitle: \"已复制到剪贴板\",\n createActionLabel: \"创建\",\n createDirectoryLabel: \"新建文件夹\",\n createDirectoryPlaceholder: \"文件夹名称\",\n createFileLabel: \"新建文件\",\n createFilePlaceholder: \"文件名称\",\n createNameInvalid: \"请输入有效名称,且不要包含路径分隔符\",\n createNameRequired: \"请输入名称后再继续\",\n clearSearchLabel: \"清空搜索\",\n deleteConfirmDescription: \"要从这个工作区删除 {{name}} 吗?\",\n deleteLabel: \"删除\",\n deletingLabel: \"删除中...\",\n downloadFailedTitle: \"下载失败\",\n downloadLabel: \"下载\",\n emptyDirectory: \"这个文件夹里没有可见文件\",\n collapseFolderLabel: \"收起文件夹\",\n expandFolderLabel: \"展开文件夹\",\n forwardLabel: \"前进\",\n loading: \"加载中\",\n modifiedLabel: \"修改时间\",\n nameLabel: \"名称\",\n noSearchResults: \"没有匹配的文件\",\n openFailedTitle: \"打开失败\",\n openLabel: \"打开\",\n openInAppBrowserLabel: \"Tutti 内置的浏览器\",\n openInDefaultBrowserLabel: \"默认浏览器\",\n openInFileViewerLabel: \"文件查看器\",\n openWithLabel: \"打开方式\",\n openWithLoadingLabel: \"正在加载应用...\",\n openWithOtherLabel: \"其他...\",\n openWithOtherPickerPrompt: \"选择用来打开此文件的应用程序:\",\n revealInFileExplorerLabel: \"在文件资源管理器中显示\",\n revealInFileManagerLabel: \"在文件管理器中显示\",\n revealInFinderLabel: \"在 Finder 中显示\",\n shareLabel: \"分享\",\n unknownErrorMessage: \"出了点问题,请稍后再试。\",\n previewActionsLabel: \"文件操作\",\n previewBinary: \"这个文件更像二进制内容,当前先保持只读占位。\",\n previewDecodeFailed: \"暂时无法按 UTF-8 文本解码这个文件。\",\n previewDirectoryLabel: \"文件夹\",\n previewEmptyLabel: \"选择文件或文件夹查看详情\",\n previewFileTooLarge: \"这个文件超过了 {{maxSize}},暂时不做内联预览。\",\n previewLoadingLabel: \"正在加载预览...\",\n previewTooLarge: \"这个文本文件超过了 {{maxSize}},暂时不做内联预览。\",\n previewUnavailableDownloadBody: \"下载 {{name}} 后再在其他环境中打开。\",\n previewUnavailableOpenBody: \"改为在本地应用中打开 {{name}}。\",\n previewUnavailableTitle: \"这个文件暂时无法预览\",\n previewUnsupported: \"这种文件类型暂时还不支持内联预览。\",\n revealFailedTitle: \"无法在文件管理器中显示\",\n renameActionLabel: \"重命名\",\n renameLabel: \"重命名\",\n renamePlaceholder: \"新名称\",\n refreshLabel: \"刷新\",\n resizeLocationsSidebar: \"调整位置侧栏宽度\",\n resizePreviewPanel: \"调整文件详情面板宽度\",\n retryLabel: \"重试\",\n searchPlaceholder: \"搜索文件\",\n searchResultsLabel: \"搜索结果\",\n sizeLabel: \"大小\",\n unsupportedViewBody:\n \"这个桌面版本暂时还不支持直接从文件管理器打开 {{name}}。\",\n unsupportedViewTitle: \"暂不支持打开\",\n layoutIconViewLabel: \"图标\",\n layoutIconViewTooltipLabel: \"图标模式\",\n layoutListViewLabel: \"列表\",\n layoutListViewTooltipLabel: \"列表模式\"\n} as const satisfies I18nDictionary;\n\nexport type WorkspaceFileManagerI18nKey = keyof typeof workspaceFileManagerEn;\n\nexport type WorkspaceFileManagerI18nRuntime =\n I18nRuntime<WorkspaceFileManagerI18nKey>;\n\nconst workspaceFileManagerDefaults: Record<\n WorkspaceFileManagerI18nLocale,\n I18nDictionary\n> = {\n en: workspaceFileManagerEn,\n \"zh-CN\": workspaceFileManagerZhCN\n};\n\nexport const workspaceFileManagerI18nResources: Record<\n WorkspaceFileManagerI18nLocale,\n I18nDictionary\n> = {\n en: {\n [workspaceFileManagerI18nNamespace]: workspaceFileManagerDefaults.en\n },\n \"zh-CN\": {\n [workspaceFileManagerI18nNamespace]: workspaceFileManagerDefaults[\"zh-CN\"]\n }\n};\n\nexport function createWorkspaceFileManagerI18nRuntime(\n runtime: I18nRuntime<string>\n): WorkspaceFileManagerI18nRuntime {\n return createScopedI18nRuntime<WorkspaceFileManagerI18nKey>(\n runtime,\n workspaceFileManagerI18nNamespace\n );\n}\n\nexport function resolveRevealInFolderLabel(\n copy: WorkspaceFileManagerI18nRuntime,\n platform: NodeJS.Platform\n): string {\n if (platform === \"darwin\") {\n return copy.t(\"revealInFinderLabel\");\n }\n if (platform === \"win32\") {\n return copy.t(\"revealInFileExplorerLabel\");\n }\n return copy.t(\"revealInFileManagerLabel\");\n}\n"],"mappings":"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","names":[]}
@@ -1,2 +1,2 @@
1
- export { W as WorkspaceFileManagerI18nKey, a as WorkspaceFileManagerI18nRuntime, c as createWorkspaceFileManagerI18nRuntime, w as workspaceFileManagerI18nNamespace, b as workspaceFileManagerI18nResources } from '../index-D0k_jjaw.js';
1
+ export { W as WorkspaceFileManagerI18nKey, a as WorkspaceFileManagerI18nRuntime, c as createWorkspaceFileManagerI18nRuntime, w as workspaceFileManagerI18nNamespace, b as workspaceFileManagerI18nResources } from '../index-BV2DWijX.js';
2
2
  import '@tutti-os/ui-i18n-runtime';
@@ -2,7 +2,7 @@ import {
2
2
  createWorkspaceFileManagerI18nRuntime,
3
3
  workspaceFileManagerI18nNamespace,
4
4
  workspaceFileManagerI18nResources
5
- } from "../chunk-EI4ICYY4.js";
5
+ } from "../chunk-MWVVTZD5.js";
6
6
  export {
7
7
  createWorkspaceFileManagerI18nRuntime,
8
8
  workspaceFileManagerI18nNamespace,
@@ -51,7 +51,9 @@ declare const workspaceFileManagerEn: {
51
51
  readonly revealInFileExplorerLabel: "Reveal in File Explorer";
52
52
  readonly revealInFileManagerLabel: "Reveal in File Manager";
53
53
  readonly revealInFinderLabel: "Reveal in Finder";
54
+ readonly shareLabel: "Share";
54
55
  readonly unknownErrorMessage: "Something went wrong. Please try again.";
56
+ readonly previewActionsLabel: "File actions";
55
57
  readonly previewBinary: "This file looks binary, so the preview stays read-only for now.";
56
58
  readonly previewDecodeFailed: "We couldn't decode this file as UTF-8 text for preview.";
57
59
  readonly previewDirectoryLabel: "Folder";
package/dist/index.d.ts CHANGED
@@ -1,12 +1,32 @@
1
- import { c as WorkspaceFileEntry, f as WorkspaceFileLocation, s as WorkspaceFileManagerSession } from './workspaceFileManagerLocations-BwRMCnUY.js';
2
- export { C as CreateWorkspaceFileManagerSessionInput, W as WorkspaceFileActivationTarget, a as WorkspaceFileDirectoryListing, b as WorkspaceFileDirectoryLocation, d as WorkspaceFileEntryKind, e as WorkspaceFileExternalLocation, g as WorkspaceFileLocationKind, h as WorkspaceFileLocationSection, i as WorkspaceFileManagerCapabilities, j as WorkspaceFileManagerFileActivationRequest, l as WorkspaceFileManagerHost, m as WorkspaceFileManagerHostFallbackAction, n as WorkspaceFileManagerHostFallbackActionKind, o as WorkspaceFileManagerHostFileActivationResult, p as WorkspaceFileManagerMutationErrorMessage, q as WorkspaceFileManagerPersistedState, r as WorkspaceFileManagerService, t as WorkspaceFileManagerState, u as WorkspaceFileOpenWithApplication, v as WorkspaceFilePreviewKind, w as WorkspaceFilePreviewState, x as WorkspaceFileRecentLocation, y as WorkspaceFileSearchEntry, z as WorkspaceFileSearchResult, A as createWorkspaceFileManagerService, B as findWorkspaceFileLocationById, D as flattenWorkspaceFileLocations, E as isWorkspaceFileExternalLocation, F as isWorkspaceFileRecentLocation, G as resolveWorkspaceFileLocationDefaultId } from './workspaceFileManagerLocations-BwRMCnUY.js';
3
- import { a as WorkspaceFileManagerI18nRuntime } from './index-D0k_jjaw.js';
4
- export { W as WorkspaceFileManagerI18nKey, c as createWorkspaceFileManagerI18nRuntime, r as resolveRevealInFolderLabel, w as workspaceFileManagerI18nNamespace, b as workspaceFileManagerI18nResources } from './index-D0k_jjaw.js';
1
+ import { c as WorkspaceFileEntry, f as WorkspaceFileLocation, s as WorkspaceFileManagerSession } from './workspaceFileManagerLocations-CzEKi2T1.js';
2
+ export { C as CreateWorkspaceFileManagerSessionInput, W as WorkspaceFileActivationTarget, a as WorkspaceFileDirectoryListing, b as WorkspaceFileDirectoryLocation, d as WorkspaceFileEntryKind, e as WorkspaceFileExternalLocation, g as WorkspaceFileLocationKind, h as WorkspaceFileLocationSection, i as WorkspaceFileManagerCapabilities, j as WorkspaceFileManagerFileActivationRequest, l as WorkspaceFileManagerHost, m as WorkspaceFileManagerHostFallbackAction, n as WorkspaceFileManagerHostFallbackActionKind, o as WorkspaceFileManagerHostFileActivationResult, p as WorkspaceFileManagerMutationErrorMessage, q as WorkspaceFileManagerPersistedState, r as WorkspaceFileManagerService, t as WorkspaceFileManagerState, u as WorkspaceFileOpenWithApplication, v as WorkspaceFilePreviewKind, w as WorkspaceFilePreviewState, x as WorkspaceFileRecentLocation, y as WorkspaceFileSearchEntry, z as WorkspaceFileSearchResult, A as createWorkspaceFileManagerService, B as findWorkspaceFileLocationById, D as flattenWorkspaceFileLocations, E as isWorkspaceFileExternalLocation, F as isWorkspaceFileRecentLocation, G as resolveWorkspaceFileLocationDefaultId } from './workspaceFileManagerLocations-CzEKi2T1.js';
3
+ import { a as WorkspaceFileManagerI18nRuntime } from './index-BV2DWijX.js';
4
+ export { W as WorkspaceFileManagerI18nKey, c as createWorkspaceFileManagerI18nRuntime, r as resolveRevealInFolderLabel, w as workspaceFileManagerI18nNamespace, b as workspaceFileManagerI18nResources } from './index-BV2DWijX.js';
5
5
  import { ReactElement, RefObject } from 'react';
6
6
  import { TuttiDateLocale } from '@tutti-os/ui-system/date-format';
7
7
  import '@tutti-os/workspace-file-preview';
8
8
  import '@tutti-os/ui-i18n-runtime';
9
9
 
10
+ type WorkspaceFileManagerPreviewActionId = "copy" | "download" | "open" | "share";
11
+ /**
12
+ * Declares which actions the preview panel renders in its bottom action row.
13
+ *
14
+ * Copy and open are backed by session commands the package already owns, so
15
+ * hosts only opt in with a boolean. Download and share have no package-side
16
+ * implementation, so passing a handler is what enables them — the same
17
+ * "capability exists when the method exists" convention the host contract uses.
18
+ */
19
+ interface WorkspaceFileManagerPreviewActionsConfig {
20
+ /** Enables copy. Still requires `capabilities.canCopy`. */
21
+ copy?: boolean;
22
+ /** Enables open. */
23
+ open?: boolean;
24
+ onDownload?: (entry: WorkspaceFileEntry) => Promise<void> | void;
25
+ onShare?: (entry: WorkspaceFileEntry) => Promise<void> | void;
26
+ /** Overrides button order. Defaults to copy, open, download, share. */
27
+ order?: readonly WorkspaceFileManagerPreviewActionId[];
28
+ }
29
+
10
30
  type WorkspaceFileManagerEntryDragMode = "external" | "internal-move";
11
31
 
12
32
  /**
@@ -89,6 +109,13 @@ interface WorkspaceFileManagerProps {
89
109
  renderExternalLocationContent?: (location: Extract<WorkspaceFileLocation, {
90
110
  kind: "external";
91
111
  }>) => ReactElement | null;
112
+ /**
113
+ * Declares the action row rendered at the bottom of the preview panel. Copy
114
+ * and open opt in with a boolean and reuse the package's session commands;
115
+ * download and share are enabled by passing a host handler. Omit the prop to
116
+ * keep the preview panel action-free.
117
+ */
118
+ previewActions?: WorkspaceFileManagerPreviewActionsConfig;
92
119
  /**
93
120
  * Optional host actions rendered in the toolbar trailing cluster, after
94
121
  * Refresh and before Search. Use for product-owned primary affordances such
@@ -106,7 +133,7 @@ interface WorkspaceFileManagerProps {
106
133
  showPreviewPanel?: boolean;
107
134
  surface?: "card" | "embedded";
108
135
  }
109
- declare function WorkspaceFileManager({ className, dateLocale, entryDragMode, i18n, onCopyEntry, onDirectoryExpanded, onEntryDragStart, resolveContextMenu, resolveEntryIconUrl, renderExternalLocationContent, renderToolbarTrailingActions, session, showLocationSidebar, showPreviewPanel, surface }: WorkspaceFileManagerProps): ReactElement;
136
+ declare function WorkspaceFileManager({ className, dateLocale, entryDragMode, i18n, onCopyEntry, onDirectoryExpanded, onEntryDragStart, previewActions, resolveContextMenu, resolveEntryIconUrl, renderExternalLocationContent, renderToolbarTrailingActions, session, showLocationSidebar, showPreviewPanel, surface }: WorkspaceFileManagerProps): ReactElement;
110
137
 
111
138
  interface WorkspaceFileManagerContextMenuProps {
112
139
  contextMenu: {
@@ -156,4 +183,4 @@ declare function useWorkspaceFileEntryIconUrls(input: {
156
183
  reportEntryIconViewportLeave: (entry: WorkspaceFileEntry) => void;
157
184
  };
158
185
 
159
- export { type RenderWorkspaceFileManagerToolbarTrailingActions, type ResolveWorkspaceFileManagerContextMenu, WorkspaceFileEntry, WorkspaceFileEntryIcon, WorkspaceFileLocation, WorkspaceFileManager, WorkspaceFileManagerContextMenu, type WorkspaceFileManagerContextMenuActionItem, type WorkspaceFileManagerContextMenuItem, type WorkspaceFileManagerContextMenuProps, type WorkspaceFileManagerContextMenuRequest, type WorkspaceFileManagerContextMenuSeparatorItem, type WorkspaceFileManagerContextMenuSubmenuItem, type WorkspaceFileManagerContextMenuTarget, WorkspaceFileManagerCreateDialog, type WorkspaceFileManagerEntryDragMode, WorkspaceFileManagerI18nRuntime, type WorkspaceFileManagerProps, WorkspaceFileManagerSession, type WorkspaceFileManagerToolbarTrailingActionsContext, resolveWorkspaceFileManagerContextMenuTarget, useWorkspaceFileEntryIconUrls };
186
+ export { type RenderWorkspaceFileManagerToolbarTrailingActions, type ResolveWorkspaceFileManagerContextMenu, WorkspaceFileEntry, WorkspaceFileEntryIcon, WorkspaceFileLocation, WorkspaceFileManager, WorkspaceFileManagerContextMenu, type WorkspaceFileManagerContextMenuActionItem, type WorkspaceFileManagerContextMenuItem, type WorkspaceFileManagerContextMenuProps, type WorkspaceFileManagerContextMenuRequest, type WorkspaceFileManagerContextMenuSeparatorItem, type WorkspaceFileManagerContextMenuSubmenuItem, type WorkspaceFileManagerContextMenuTarget, WorkspaceFileManagerCreateDialog, type WorkspaceFileManagerEntryDragMode, WorkspaceFileManagerI18nRuntime, type WorkspaceFileManagerPreviewActionId, type WorkspaceFileManagerPreviewActionsConfig, type WorkspaceFileManagerProps, WorkspaceFileManagerSession, type WorkspaceFileManagerToolbarTrailingActionsContext, resolveWorkspaceFileManagerContextMenuTarget, useWorkspaceFileEntryIconUrls };