@tutti-os/workspace-file-manager 0.0.210 → 0.0.212

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.
@@ -79,6 +79,9 @@ function sortWorkspaceEntries(entries) {
79
79
  function buildWorkspaceFileBreadcrumbs(path, rootLabel, rootPath) {
80
80
  const root = normalizeWorkspaceFilePath(rootPath);
81
81
  const current = normalizeWorkspaceFilePath(path, root);
82
+ if (root === workspaceFileManagerLogicalRoot && current !== workspaceFileManagerLogicalRoot) {
83
+ return [{ label: rootLabel, path: current }];
84
+ }
82
85
  const relative = current === root ? "" : current.slice(root.length).replace(/^\//, "");
83
86
  const breadcrumbs = [
84
87
  { label: rootLabel, path: root }
@@ -198,7 +201,7 @@ var WorkspaceFileOpenWithApplicationsCache = class {
198
201
  };
199
202
 
200
203
  // src/services/internal/workspaceFileManagerStore.ts
201
- import { proxy } from "valtio";
204
+ import { proxy } from "valtio/vanilla";
202
205
 
203
206
  // src/services/internal/model/fileKinds.ts
204
207
  import { resolveWorkspaceFilePreviewTarget } from "@tutti-os/workspace-file-preview";
@@ -742,11 +745,32 @@ var WorkspaceFileManagerNavigationController = class {
742
745
  resolveErrorMessage;
743
746
  store;
744
747
  requestSeq = 0;
748
+ /** Counts performLoad/reveal/replace calls so superseded requests cannot leave isLoading latched. */
749
+ activeLoadCount = 0;
750
+ /**
751
+ * Same-path loads share one in-flight promise. Concurrent initialize/reveal/
752
+ * remount callers used to bump requestSeq and let a faster empty response
753
+ * discard a slower successful listing.
754
+ */
755
+ inFlightLoadByPath = /* @__PURE__ */ new Map();
745
756
  constructor(input) {
746
757
  this.host = input.host;
747
758
  this.resolveErrorMessage = input.resolveErrorMessage;
748
759
  this.store = input.store;
749
760
  }
761
+ beginLoad() {
762
+ const requestID = ++this.requestSeq;
763
+ this.activeLoadCount += 1;
764
+ this.store.isLoading = true;
765
+ this.store.error = null;
766
+ return requestID;
767
+ }
768
+ endLoad(requestID) {
769
+ this.activeLoadCount = Math.max(0, this.activeLoadCount - 1);
770
+ if (requestID === this.requestSeq || this.activeLoadCount === 0) {
771
+ this.store.isLoading = false;
772
+ }
773
+ }
750
774
  async goBack() {
751
775
  const previous = this.store.navigationBackStack.pop();
752
776
  if (!previous) {
@@ -765,9 +789,26 @@ var WorkspaceFileManagerNavigationController = class {
765
789
  }
766
790
  async loadDirectory(path = this.store.currentDirectoryPath) {
767
791
  const normalizedPath = normalizeWorkspaceFilePath(path, this.store.root);
768
- const requestID = ++this.requestSeq;
769
- this.store.isLoading = true;
770
- this.store.error = null;
792
+ const existing = this.inFlightLoadByPath.get(normalizedPath);
793
+ if (existing) {
794
+ await existing;
795
+ return;
796
+ }
797
+ const run = this.performLoadDirectory(normalizedPath);
798
+ this.inFlightLoadByPath.set(normalizedPath, run);
799
+ try {
800
+ await run;
801
+ } finally {
802
+ if (this.inFlightLoadByPath.get(normalizedPath) === run) {
803
+ this.inFlightLoadByPath.delete(normalizedPath);
804
+ }
805
+ }
806
+ }
807
+ async refresh() {
808
+ await this.loadDirectory(this.store.currentDirectoryPath);
809
+ }
810
+ async performLoadDirectory(normalizedPath) {
811
+ const requestID = this.beginLoad();
771
812
  try {
772
813
  const listing = await this.host.listDirectory({
773
814
  includeHidden: workspaceFilePathHasHiddenSegment(normalizedPath),
@@ -775,6 +816,16 @@ var WorkspaceFileManagerNavigationController = class {
775
816
  workspaceID: this.store.workspaceID
776
817
  });
777
818
  if (requestID !== this.requestSeq) {
819
+ if (listing.entries.length > 0 && this.store.entries.length === 0 && this.store.error === null && normalizeWorkspaceFilePath(listing.directoryPath, listing.root) === normalizeWorkspaceFilePath(
820
+ this.store.currentDirectoryPath,
821
+ this.store.root
822
+ )) {
823
+ this.store.root = normalizeWorkspaceFilePath(listing.root);
824
+ this.store.currentDirectoryPath = listing.directoryPath;
825
+ this.store.entries = sortWorkspaceEntries(listing.entries);
826
+ this.store.directoryExpansionByPath = {};
827
+ this.store.expandedDirectoryPaths = {};
828
+ }
778
829
  return;
779
830
  }
780
831
  const previousDirectoryPath = this.store.currentDirectoryPath;
@@ -793,23 +844,16 @@ var WorkspaceFileManagerNavigationController = class {
793
844
  this.store.error = this.resolveErrorMessage(error);
794
845
  }
795
846
  } finally {
796
- if (requestID === this.requestSeq) {
797
- this.store.isLoading = false;
798
- }
847
+ this.endLoad(requestID);
799
848
  }
800
849
  }
801
- async refresh() {
802
- await this.loadDirectory(this.store.currentDirectoryPath);
803
- }
804
850
  async revealPath(path) {
805
851
  const normalizedPath = normalizeWorkspaceFilePath(path, this.store.root);
806
852
  const directoryPath = workspaceFileDirectory(
807
853
  normalizedPath,
808
854
  this.store.root
809
855
  );
810
- const requestID = ++this.requestSeq;
811
- this.store.isLoading = true;
812
- this.store.error = null;
856
+ const requestID = this.beginLoad();
813
857
  try {
814
858
  const listing = await this.host.listDirectory({
815
859
  includeHidden: workspaceFilePathHasHiddenSegment(normalizedPath),
@@ -835,16 +879,12 @@ var WorkspaceFileManagerNavigationController = class {
835
879
  this.store.error = this.resolveErrorMessage(error);
836
880
  }
837
881
  } finally {
838
- if (requestID === this.requestSeq) {
839
- this.store.isLoading = false;
840
- }
882
+ this.endLoad(requestID);
841
883
  }
842
884
  }
843
885
  async replaceDirectory(path) {
844
886
  const normalizedPath = normalizeWorkspaceFilePath(path, this.store.root);
845
- const requestID = ++this.requestSeq;
846
- this.store.isLoading = true;
847
- this.store.error = null;
887
+ const requestID = this.beginLoad();
848
888
  try {
849
889
  const listing = await this.host.listDirectory({
850
890
  includeHidden: workspaceFilePathHasHiddenSegment(normalizedPath),
@@ -865,9 +905,7 @@ var WorkspaceFileManagerNavigationController = class {
865
905
  this.store.error = this.resolveErrorMessage(error);
866
906
  }
867
907
  } finally {
868
- if (requestID === this.requestSeq) {
869
- this.store.isLoading = false;
870
- }
908
+ this.endLoad(requestID);
871
909
  }
872
910
  }
873
911
  resolveRequestPath(path) {
@@ -1134,6 +1172,11 @@ var DefaultWorkspaceFileManagerSession = class {
1134
1172
  store;
1135
1173
  host;
1136
1174
  hasInitialized = false;
1175
+ /**
1176
+ * True after a directory listing attempt finished without leaving the session
1177
+ * mid-flight. Empty folders set this too — "no entries" is not "not loaded".
1178
+ */
1179
+ hasSettledDirectoryListing = false;
1137
1180
  initializePromise = null;
1138
1181
  isActive = false;
1139
1182
  isDisposed = false;
@@ -1352,6 +1395,7 @@ var DefaultWorkspaceFileManagerSession = class {
1352
1395
  dispose() {
1353
1396
  this.isDisposed = true;
1354
1397
  this.hasInitialized = false;
1398
+ this.hasSettledDirectoryListing = false;
1355
1399
  this.initializePromise = null;
1356
1400
  this.isActive = false;
1357
1401
  this.searchRequestSeq += 1;
@@ -1395,11 +1439,17 @@ var DefaultWorkspaceFileManagerSession = class {
1395
1439
  await this.initializePromise;
1396
1440
  } finally {
1397
1441
  this.initializePromise = null;
1442
+ if (!this.hasSettledDirectoryListing && this.store.isLoading) {
1443
+ this.store.isLoading = false;
1444
+ }
1398
1445
  }
1399
1446
  }
1400
1447
  async loadDirectory(path = this.store.currentDirectoryPath) {
1401
1448
  this.clearSearchState();
1402
1449
  await this.navigationController.loadDirectory(path);
1450
+ if (!this.store.isLoading) {
1451
+ this.hasSettledDirectoryListing = true;
1452
+ }
1403
1453
  this.syncSelectedDirectoryLocation();
1404
1454
  }
1405
1455
  openContextMenu(input) {
@@ -1648,7 +1698,7 @@ var DefaultWorkspaceFileManagerSession = class {
1648
1698
  await this.loadRecentLocation(location);
1649
1699
  return;
1650
1700
  }
1651
- await this.navigationController.loadDirectory(location.path);
1701
+ await this.loadDirectory(location.path);
1652
1702
  }
1653
1703
  setActive(active) {
1654
1704
  if (this.isActive === active) {
@@ -1656,6 +1706,9 @@ var DefaultWorkspaceFileManagerSession = class {
1656
1706
  }
1657
1707
  this.isActive = active;
1658
1708
  if (active) {
1709
+ if (this.hasInitialized && !this.hasSettledDirectoryListing && !this.store.isLoading) {
1710
+ void this.loadSelectedLocationOrDirectory();
1711
+ }
1659
1712
  return;
1660
1713
  }
1661
1714
  this.store.contextMenu = null;
@@ -1710,18 +1763,20 @@ var DefaultWorkspaceFileManagerSession = class {
1710
1763
  this.store.inlineRenameValidation = null;
1711
1764
  }
1712
1765
  hasLoadedDirectoryState() {
1713
- return this.store.error !== null || this.store.entries.length > 0 || this.store.selectedPath !== null;
1766
+ return this.hasSettledDirectoryListing || this.store.error !== null || this.store.entries.length > 0;
1714
1767
  }
1715
1768
  async loadSelectedLocationOrDirectory() {
1716
1769
  const selectedLocation = this.selectedLocation();
1717
1770
  if (isWorkspaceFileExternalLocation(selectedLocation)) {
1771
+ this.hasSettledDirectoryListing = true;
1772
+ this.store.isLoading = false;
1718
1773
  return;
1719
1774
  }
1720
1775
  if (selectedLocation?.kind === "recent") {
1721
1776
  await this.loadRecentLocation(selectedLocation);
1722
1777
  return;
1723
1778
  }
1724
- await this.navigationController.loadDirectory(
1779
+ await this.loadDirectory(
1725
1780
  this.resolveInitialDirectoryPath(selectedLocation)
1726
1781
  );
1727
1782
  }
@@ -1747,6 +1802,7 @@ var DefaultWorkspaceFileManagerSession = class {
1747
1802
  this.store.error = this.resolveErrorMessage(error);
1748
1803
  } finally {
1749
1804
  this.store.isLoading = false;
1805
+ this.hasSettledDirectoryListing = true;
1750
1806
  }
1751
1807
  }
1752
1808
  selectedLocation() {
@@ -2199,4 +2255,4 @@ export {
2199
2255
  sortWorkspaceFileEntriesForArrangeMode,
2200
2256
  resolveWorkspaceFileEntryArrangeDateMs
2201
2257
  };
2202
- //# sourceMappingURL=chunk-TNFCNCZV.js.map
2258
+ //# sourceMappingURL=chunk-KCYTFKPY.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<void> {\n if (this.isExternalLocationSelected()) {\n return;\n }\n if (!this.host.copyEntriesToClipboard) {\n return;\n }\n\n await this.host.copyEntriesToClipboard({\n paths: [entry.path],\n workspaceID: this.store.workspaceID\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"]}
package/dist/index.d.ts CHANGED
@@ -83,10 +83,16 @@ interface WorkspaceFileManagerProps {
83
83
  }>) => ReactElement | null;
84
84
  i18n: WorkspaceFileManagerI18nRuntime;
85
85
  session: WorkspaceFileManagerSession;
86
+ /**
87
+ * When false, hide the locations sidebar even if the session has location
88
+ * sections. Hosts with a single workspace root (for example TSH embedded
89
+ * Files) can turn this off. Defaults to true.
90
+ */
91
+ showLocationSidebar?: boolean;
86
92
  showPreviewPanel?: boolean;
87
93
  surface?: "card" | "embedded";
88
94
  }
89
- declare function WorkspaceFileManager({ className, dateLocale, entryDragMode, i18n, onCopyEntry, onDirectoryExpanded, onEntryDragStart, resolveContextMenu, resolveEntryIconUrl, renderExternalLocationContent, session, showPreviewPanel, surface }: WorkspaceFileManagerProps): ReactElement;
95
+ declare function WorkspaceFileManager({ className, dateLocale, entryDragMode, i18n, onCopyEntry, onDirectoryExpanded, onEntryDragStart, resolveContextMenu, resolveEntryIconUrl, renderExternalLocationContent, session, showLocationSidebar, showPreviewPanel, surface }: WorkspaceFileManagerProps): ReactElement;
90
96
 
91
97
  interface WorkspaceFileManagerContextMenuProps {
92
98
  contextMenu: {