{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "file-system",
  "title": "File System",
  "description": "A document workspace over a flat object-store manifest with list, grid, columns, lazy folders, generated thumbnails, and FileViewer previews.",
  "dependencies": [
    "lucide-react",
    "@pierre/trees@1.0.0-beta.4"
  ],
  "registryDependencies": [
    "@retab/utils",
    "breadcrumb",
    "button",
    "dialog",
    "@retab/file-size-format",
    "@retab/file-thumbnail",
    "@retab/file-viewer",
    "@retab/input",
    "@retab/scroll-area",
    "@retab/spinner",
    "tabs"
  ],
  "files": [
    {
      "path": "registry/new-york-v4/ui/file-system.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { AlertCircle, FileQuestion, RefreshCw } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { FileViewerPreview } from \"@/components/ui/file-viewer\";\nimport { Spinner } from \"@/components/ui/spinner\";\n\nimport {\n  FileSystemOpenPreview,\n  useFileSystemOpenPreview,\n} from \"./file-system-open-preview-dialog\";\nimport {\n  FileSystemBrowser,\n  FileSystemHeader,\n  FileSystemSelection,\n  useFileSystemBrowser,\n  useFileSystemHeader,\n  useFileSystemSelectedItem,\n  useFileSystemSelectedSource,\n  useFileSystemSelection,\n  type FileSystemSelectionRenderState,\n} from \"./file-system-parts\";\nimport {\n  FILE_SYSTEM_COLUMNS_SIDEBAR_WIDTH,\n  FILE_SYSTEM_SIDEBAR_WIDTH,\n} from \"./file-system-columns-view\";\nimport { FileSystemProvider, useFileSystem } from \"./file-system-provider\";\nimport { FileSystemThumbnail } from \"./file-system-thumbnail\";\nimport type {\n  FileSystemEntry,\n  FileSystemFileItem,\n  FileSystemProps,\n} from \"./file-system-types\";\nimport {\n  ViewerBody,\n  ViewerHeader,\n  ViewerRoot,\n  ViewerSidebar,\n  ViewerSurface,\n} from \"./viewer\";\n\nexport {\n  FileSystemOpenPreview,\n  FileSystemProvider,\n  FileSystemBrowser,\n  FileSystemHeader,\n  FileSystemSelection,\n  useFileSystem,\n  useFileSystemBrowser,\n  useFileSystemHeader,\n  useFileSystemOpenPreview,\n  useFileSystemSelectedItem,\n  useFileSystemSelectedSource,\n  useFileSystemSelection,\n};\n\nexport type {\n  FileSystemFileItem,\n  FileSystemFolderItem,\n  FileSystemItem,\n  FileSystemLoadChildrenArgs,\n  FileSystemLoadChildrenResult,\n  FileSystemProps,\n  FileSystemQueryState,\n  FileSystemResolveSourceArgs,\n  FileSystemView,\n} from \"./file-system-types\";\nexport type { FileSystemProviderProps } from \"./file-system-provider\";\nexport type {\n  FileSystemBrowserPartState,\n  FileSystemHeaderState,\n  FileSystemSelectionRenderState,\n  FileSystemSelectionState,\n} from \"./file-system-parts\";\n\nexport function FileSystem({ className, ...providerProps }: FileSystemProps) {\n  return (\n    <FileSystemProvider {...providerProps}>\n      <FileSystemRoot className={className} />\n    </FileSystemProvider>\n  );\n}\n\nfunction FileSystemRoot({ className }: { className?: string }) {\n  const { browser } = useFileSystem();\n  const sidebarWidth =\n    browser.view === \"columns\"\n      ? FILE_SYSTEM_COLUMNS_SIDEBAR_WIDTH\n      : FILE_SYSTEM_SIDEBAR_WIDTH;\n\n  return (\n    <div data-slot=\"file-system\">\n      <ViewerRoot\n        data-viewer=\"file-system\"\n        defaultOpen\n        className={cn(\n          \"bg-background text-foreground h-[640px] rounded-md border\",\n          className,\n        )}\n      >\n        <ViewerHeader className=\"flex flex-col\">\n          <FileSystemHeader />\n        </ViewerHeader>\n        <ViewerBody>\n          <ViewerSidebar\n            aria-label=\"Files\"\n            width={sidebarWidth}\n            className=\"flex min-w-0 flex-col border-r\"\n          >\n            <FileSystemBrowser />\n          </ViewerSidebar>\n          <ViewerSurface className=\"bg-background\">\n            <FileSystemSelection>\n              {(selection) => (\n                <FileSystemDefaultSelectionContent selection={selection} />\n              )}\n            </FileSystemSelection>\n          </ViewerSurface>\n        </ViewerBody>\n        <FileSystemOpenPreview />\n      </ViewerRoot>\n    </div>\n  );\n}\n\nfunction FileSystemDefaultSelectionContent({\n  selection,\n}: {\n  selection: FileSystemSelectionRenderState;\n}) {\n  const {\n    entry,\n    renderFileActions,\n    renderMetadata,\n    resolveSource,\n    retry,\n    sourceState,\n  } = selection;\n\n  return (\n    <div\n      data-slot=\"file-system-default-selection\"\n      className=\"bg-muted/20 flex size-full min-h-0 min-w-0 flex-col overflow-hidden\"\n    >\n      <div className=\"flex min-h-0 flex-1 flex-col\">\n        <div className=\"bg-background flex min-h-0 flex-1 items-center justify-center overflow-hidden\">\n          {!entry ? (\n            <FileSystemDefaultSelectionMessage\n              title=\"No file selected\"\n              description=\"Select a file to preview it.\"\n            />\n          ) : entry.kind === \"folder\" ? (\n            <FileSystemDefaultSelectionMessage\n              title={entry.name}\n              description=\"Folders show their contents in the browser.\"\n            />\n          ) : sourceState.status === \"loading\" ? (\n            <div className=\"text-muted-foreground flex items-center gap-2 text-sm\">\n              <Spinner className=\"size-4\" />\n              Loading preview\n            </div>\n          ) : sourceState.status === \"error\" ? (\n            <FileSystemDefaultSelectionMessage\n              icon={<AlertCircle className=\"size-5\" aria-hidden />}\n              title=\"Couldn't load preview\"\n              description={sourceState.error}\n              action={\n                <Button size=\"sm\" variant=\"outline\" onClick={retry}>\n                  <RefreshCw className=\"size-3.5\" aria-hidden />\n                  Retry\n                </Button>\n              }\n            />\n          ) : sourceState.status === \"ready\" ? (\n            <FileViewerPreview\n              source={sourceState.source}\n              className=\"size-full min-h-0\"\n            />\n          ) : sourceState.status === \"unavailable\" ? (\n            <FileSystemDefaultSelectionMessage\n              icon={<FileQuestion className=\"size-5\" aria-hidden />}\n              title=\"Preview unavailable\"\n              description=\"This file does not have a resolved source.\"\n            />\n          ) : null}\n        </div>\n        {entry ? (\n          <FileSystemDefaultSelectionFooter\n            entry={entry}\n            renderFileActions={renderFileActions}\n            renderMetadata={renderMetadata}\n            resolveFileSource={resolveSource}\n          />\n        ) : null}\n      </div>\n    </div>\n  );\n}\n\nfunction FileSystemDefaultSelectionFooter({\n  entry,\n  renderFileActions,\n  renderMetadata,\n  resolveFileSource,\n}: {\n  entry: FileSystemEntry;\n  renderFileActions?: (file: FileSystemFileItem) => React.ReactNode;\n  renderMetadata?: (item: FileSystemEntry) => React.ReactNode;\n  resolveFileSource: FileSystemSelectionRenderState[\"resolveSource\"];\n}) {\n  const file = entry.kind === \"file\" ? entry : null;\n\n  return (\n    <div className=\"bg-background shrink-0 border-t p-3\">\n      <div className=\"flex items-start gap-3\">\n        {file ? (\n          <FileSystemThumbnail\n            file={file}\n            resolveFileSource={resolveFileSource}\n            className=\"w-12 shrink-0\"\n          />\n        ) : (\n          <div className=\"bg-muted flex size-12 shrink-0 items-center justify-center rounded-sm text-lg\">\n            {folderInitial(entry.name)}\n          </div>\n        )}\n        <div className=\"min-w-0 flex-1\">\n          <div className=\"text-sm font-medium break-words\">{entry.name}</div>\n          <div className=\"text-muted-foreground mt-0.5 truncate text-xs\">\n            {entry.path}\n          </div>\n        </div>\n        {file ? renderFileActions?.(file) : null}\n      </div>\n      {renderMetadata ? (\n        <div className=\"mt-3\">{renderMetadata(entry)}</div>\n      ) : null}\n    </div>\n  );\n}\n\nfunction FileSystemDefaultSelectionMessage({\n  action,\n  description,\n  icon,\n  title,\n}: {\n  action?: React.ReactNode;\n  description: string;\n  icon?: React.ReactNode;\n  title: string;\n}) {\n  return (\n    <div className=\"flex max-w-xs flex-col items-center gap-2 px-6 text-center\">\n      {icon ? <div className=\"text-muted-foreground\">{icon}</div> : null}\n      <div className=\"text-sm font-medium\">{title}</div>\n      <div className=\"text-muted-foreground text-xs\">{description}</div>\n      {action ? <div className=\"pt-1\">{action}</div> : null}\n    </div>\n  );\n}\n\nfunction folderInitial(name: string) {\n  return name.trim().charAt(0).toUpperCase() || \"/\";\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-provider.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useFileSystemKernelRuntime } from \"./file-system-kernel-runtime\";\nimport {\n  selectFileSystemBrowserState,\n  selectFileSystemSelectionState,\n} from \"./file-system-kernel-selectors\";\nimport {\n  useFileSystemOpenPreviewController,\n  type FileSystemOpenPreviewController,\n} from \"./file-system-open-preview-state\";\nimport { useFileSystemSourceController } from \"./file-system-source-controller\";\nimport type { FileSystemProps } from \"./file-system-types\";\n\nexport type FileSystemProviderProps = Omit<FileSystemProps, \"className\"> & {\n  children: React.ReactNode;\n};\n\nexport type FileSystemRenderers = {\n  renderFileActions?: FileSystemProps[\"renderFileActions\"];\n  renderMetadata?: FileSystemProps[\"renderMetadata\"];\n};\n\nexport type FileSystemCompositionState = {\n  openPreview: FileSystemOpenPreviewController;\n  renderers: FileSystemRenderers;\n  title: string;\n};\n\nexport type FileSystemContextValue = {\n  browser: ReturnType<typeof selectFileSystemBrowserState>;\n  selection: ReturnType<typeof selectFileSystemSelectionState>;\n} & FileSystemCompositionState;\n\nconst FileSystemContext = React.createContext<FileSystemContextValue | null>(\n  null,\n);\n\nexport function useFileSystem() {\n  const context = React.useContext(FileSystemContext);\n  if (!context) {\n    throw new Error(\"useFileSystem must be used within FileSystemProvider.\");\n  }\n  return context;\n}\n\nexport function FileSystemProvider({\n  items,\n  children,\n  defaultPath,\n  defaultQuery,\n  defaultSelectedPath,\n  defaultView = \"list\",\n  loadChildren,\n  onPathChange,\n  onQueryChange,\n  onFileOpen,\n  onSelectionChange,\n  onViewChange,\n  path,\n  query,\n  renderFileActions,\n  renderMetadata,\n  resolveSource,\n  selectedPath,\n  title = \"Files\",\n  view,\n}: FileSystemProviderProps) {\n  const source = useFileSystemSourceController({ items, resolveSource });\n  const openPreview = useFileSystemOpenPreviewController({\n    onFileOpen,\n    resolveFileSource: source.resolveFileSource,\n  });\n  const kernel = useFileSystemKernelRuntime({\n    defaultPath,\n    defaultQuery,\n    defaultSelectedPath,\n    defaultView,\n    items,\n    loadChildren,\n    onFileCommand: openPreview.open,\n    onPathChange,\n    onQueryChange,\n    onSelectionChange,\n    onViewChange,\n    path,\n    query,\n    selectedPath,\n    view,\n  });\n  const browser = React.useMemo(\n    () =>\n      selectFileSystemBrowserState({\n        dispatch: kernel.dispatch,\n        ensureChildren: kernel.ensureChildren,\n        getState: kernel.getState,\n        state: kernel.state,\n      }),\n    [kernel.dispatch, kernel.ensureChildren, kernel.getState, kernel.state],\n  );\n  const selection = React.useMemo(\n    () =>\n      selectFileSystemSelectionState({\n        resolveSource: source.resolveFileSource,\n        state: kernel.state,\n      }),\n    [kernel.state, source.resolveFileSource],\n  );\n  const renderers = React.useMemo<FileSystemRenderers>(\n    () => ({ renderFileActions, renderMetadata }),\n    [renderFileActions, renderMetadata],\n  );\n  const value = React.useMemo<FileSystemContextValue>(\n    () => ({\n      browser,\n      selection,\n      openPreview,\n      renderers,\n      title,\n    }),\n    [browser, openPreview, renderers, selection, title],\n  );\n\n  return (\n    <FileSystemContext.Provider value={value}>\n      {children}\n    </FileSystemContext.Provider>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-provider.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-parts.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  createFileSystemBrowserController,\n  type FileSystemBrowserController,\n} from \"./file-system-browser-controller\";\nimport type {\n  FileSystemHeaderState,\n  FileSystemSelectionState as FileSystemSelectionDomainState,\n} from \"./file-system-browser-state\";\nimport { createFileSystemHeaderState } from \"./file-system-browser-state\";\nimport { FileSystemColumnsView } from \"./file-system-columns-view\";\nimport {\n  FileSystemCommandBar,\n  FileSystemStatusBar,\n  FileSystemToolbar,\n} from \"./file-system-controls\";\nimport { FileSystemGridView } from \"./file-system-grid-view\";\nimport { FileSystemListView } from \"./file-system-list-view\";\nimport { useFileSystem } from \"./file-system-provider\";\nimport {\n  useFileSystemSelectionSourceTask,\n  type FileSystemSelectionSourceTask,\n} from \"./file-system-selection-source-task\";\nimport type {\n  FileSystemEntry,\n  FileSystemFileEntry,\n  FileSystemProps,\n} from \"./file-system-types\";\n\nexport type FileSystemBrowserPartState = FileSystemBrowserController;\n\nexport type { FileSystemHeaderState } from \"./file-system-browser-state\";\n\nexport type FileSystemSelectionState = FileSystemSelectionDomainState & {\n  renderFileActions?: FileSystemProps[\"renderFileActions\"];\n  renderMetadata?: FileSystemProps[\"renderMetadata\"];\n};\n\nexport type FileSystemSelectionRenderState = FileSystemSelectionState & {\n  file: FileSystemFileEntry | null;\n  retry: () => void;\n  source: FileSystemSelectionSourceTask[\"source\"];\n  sourceState: FileSystemSelectionSourceTask;\n};\n\nexport function useFileSystemHeader(): FileSystemHeaderState {\n  const state = useFileSystem();\n\n  return createFileSystemHeaderState({\n    browser: state.browser,\n    title: state.title,\n  });\n}\n\nexport function useFileSystemBrowser(): FileSystemBrowserPartState {\n  const state = useFileSystem();\n\n  return createFileSystemBrowserController({\n    browser: state.browser,\n    openPreview: state.openPreview.open,\n    resolveFileSource: state.selection.resolveSource,\n  });\n}\n\nexport function useFileSystemSelection(): FileSystemSelectionState {\n  const state = useFileSystem();\n\n  return {\n    ...state.selection,\n    renderFileActions: state.renderers.renderFileActions,\n    renderMetadata: state.renderers.renderMetadata,\n  };\n}\n\nexport function useFileSystemSelectedItem(): FileSystemEntry | null {\n  return useFileSystemSelection().entry;\n}\n\nexport function useFileSystemSelectedSource(): FileSystemSelectionSourceTask {\n  const selection = useFileSystemSelection();\n  const file = selection.entry?.kind === \"file\" ? selection.entry : null;\n\n  return useFileSystemSelectionSourceTask(file, selection.resolveSource);\n}\n\nexport function FileSystemHeader() {\n  const header = useFileSystemHeader();\n\n  return (\n    <>\n      <FileSystemToolbar {...header} />\n      <FileSystemCommandBar controller={header} />\n    </>\n  );\n}\n\nexport function FileSystemBrowser() {\n  const controller = useFileSystemBrowser();\n  const { view } = controller.browser;\n\n  return (\n    <div className=\"flex size-full min-h-0 flex-col\">\n      <div className=\"min-h-0 flex-1\">\n        {view === \"list\" ? (\n          <FileSystemListView controller={controller} />\n        ) : view === \"grid\" ? (\n          <FileSystemGridView controller={controller} />\n        ) : (\n          <FileSystemColumnsView controller={controller} />\n        )}\n      </div>\n      <FileSystemStatusBar browser={controller.browser} />\n    </div>\n  );\n}\n\nexport function FileSystemSelection({\n  children,\n}: {\n  children: (state: FileSystemSelectionRenderState) => React.ReactNode;\n}) {\n  const selection = useFileSystemSelection();\n  const file = selection.entry?.kind === \"file\" ? selection.entry : null;\n  const sourceState = useFileSystemSelectionSourceTask(\n    file,\n    selection.resolveSource,\n  );\n\n  return (\n    <>\n      {children({\n        ...selection,\n        file,\n        retry: sourceState.retry,\n        source: sourceState.source,\n        sourceState,\n      })}\n    </>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-parts.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-browser-state.ts",
      "content": "\"use client\";\n\nimport type { FileSystemSourceResolver } from \"./file-system-selection-source-task\";\nimport type {\n  FileSystemEntry,\n  FileSystemIndex,\n  FileSystemQueryState,\n  FileSystemSortKey,\n  FileSystemView,\n} from \"./file-system-types\";\n\nexport type FileSystemBrowserState = {\n  canGoBack: boolean;\n  canGoForward: boolean;\n  currentPath: string;\n  entries: FileSystemEntry[];\n  ensureChildren: (\n    path: string,\n    options?: { retry?: boolean },\n  ) => Promise<FileSystemEntry[]>;\n  folderErrors: ReadonlyMap<string, string>;\n  goBack: () => void;\n  goForward: () => void;\n  index: FileSystemIndex;\n  loadingFolders: ReadonlySet<string>;\n  navigateTo: (path: string) => void;\n  query: FileSystemQueryState;\n  rawIndex: FileSystemIndex;\n  selectEntry: (entry: FileSystemEntry | null) => void;\n  selectedEntry: FileSystemEntry | null;\n  selectedPath: string | null;\n  selectFirstChildAfterEnsure: (\n    path: string,\n  ) => Promise<FileSystemEntry | null>;\n  setSearch: (search: string) => void;\n  setSortKey: (key: FileSystemSortKey) => void;\n  setView: (view: FileSystemView) => void;\n  view: FileSystemView;\n};\n\nexport type FileSystemHeaderState = {\n  canGoBack: boolean;\n  canGoForward: boolean;\n  currentPath: string;\n  goBack: () => void;\n  goForward: () => void;\n  query: FileSystemQueryState;\n  setSearch: (search: string) => void;\n  setSortKey: (key: FileSystemSortKey) => void;\n  setView: (view: FileSystemView) => void;\n  title: string;\n  view: FileSystemView;\n};\n\nexport type FileSystemSelectionState = {\n  entry: FileSystemEntry | null;\n  resolveSource: FileSystemSourceResolver;\n};\n\nexport function createFileSystemHeaderState({\n  browser,\n  title,\n}: {\n  browser: FileSystemBrowserState;\n  title: string;\n}): FileSystemHeaderState {\n  return {\n    canGoBack: browser.canGoBack,\n    canGoForward: browser.canGoForward,\n    currentPath: browser.currentPath,\n    goBack: browser.goBack,\n    goForward: browser.goForward,\n    query: browser.query,\n    setSearch: browser.setSearch,\n    setSortKey: browser.setSortKey,\n    setView: browser.setView,\n    title,\n    view: browser.view,\n  };\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-browser-state.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-browser-controller.ts",
      "content": "\"use client\";\n\nimport type { FileSystemBrowserState } from \"./file-system-browser-state\";\nimport type { FileSystemSourceController } from \"./file-system-source-controller\";\nimport type { FileSystemFileEntry } from \"./file-system-types\";\n\nexport type FileSystemOpenPreviewCommand = (file: FileSystemFileEntry) => void;\n\nexport type FileSystemFileActionController = {\n  openPreview: FileSystemOpenPreviewCommand;\n  resolveFileSource: FileSystemSourceController[\"resolveFileSource\"];\n};\n\nexport type FileSystemBrowserController = {\n  browser: FileSystemBrowserState;\n  fileActions: FileSystemFileActionController;\n};\n\nexport function createFileSystemBrowserController({\n  browser,\n  openPreview,\n  resolveFileSource,\n}: {\n  browser: FileSystemBrowserState;\n  openPreview: FileSystemOpenPreviewCommand;\n  resolveFileSource: FileSystemSourceController[\"resolveFileSource\"];\n}): FileSystemBrowserController {\n  return {\n    browser,\n    fileActions: {\n      openPreview,\n      resolveFileSource,\n    },\n  };\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-browser-controller.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-kernel.ts",
      "content": "\"use client\";\n\nimport {\n  buildFileSystemIndex,\n  normalizeFilePath,\n  normalizeFolderPath,\n} from \"./file-system-index\";\nimport {\n  createFileSystemQueryState,\n  DEFAULT_FILE_SYSTEM_QUERY,\n  deriveVisibleIndex,\n} from \"./file-system-query\";\nimport type {\n  FileSystemEntry,\n  FileSystemFileEntry,\n  FileSystemFolderEntry,\n  FileSystemIndex,\n  FileSystemItem,\n  FileSystemQueryState,\n  FileSystemSortKey,\n  FileSystemView,\n} from \"./file-system-types\";\n\nexport type FileSystemHistoryState = {\n  back: string[];\n  forward: string[];\n};\n\nexport type FileSystemTreeState = {\n  childrenByPath: Map<string, string[]>;\n  entriesByPath: Map<string, FileSystemEntry>;\n};\n\nexport type FileSystemFolderLoadReason =\n  | \"navigate\"\n  | \"expand\"\n  | \"retry\"\n  | \"reveal-selection\";\n\nexport type FileSystemFolderLoadState =\n  | { status: \"loaded\" }\n  | { status: \"loading\"; requestId: string; reason: FileSystemFolderLoadReason }\n  | { status: \"failed\"; error: string };\n\nexport type FileSystemFolderLoadStateByPath = Map<\n  string,\n  FileSystemFolderLoadState\n>;\n\nexport type FileSystemPathChangeSource =\n  | \"controlled-prop\"\n  | \"history\"\n  | \"reveal\"\n  | \"user\";\n\nexport type FileSystemEventSource = \"controlled-prop\" | \"user\";\n\nexport type FileSystemKernelState = {\n  folders: FileSystemFolderLoadStateByPath;\n  history: FileSystemHistoryState;\n  path: string;\n  query: FileSystemQueryState;\n  selectionPath: string | null;\n  tree: FileSystemTreeState;\n  view: FileSystemView;\n};\n\nexport type FileSystemKernelEvent =\n  | { items: readonly FileSystemItem[]; type: \"items.replaced\" }\n  | { type: \"path.changed\"; path: string; source: FileSystemPathChangeSource }\n  | { type: \"history.back\" }\n  | { type: \"history.forward\" }\n  | {\n      type: \"query.changed\";\n      query: FileSystemQueryState;\n      source: FileSystemEventSource;\n    }\n  | { type: \"query.searchChanged\"; search: string }\n  | { type: \"query.sortKeyChanged\"; key: FileSystemSortKey }\n  | {\n      type: \"view.changed\";\n      source: FileSystemEventSource;\n      view: FileSystemView;\n    }\n  | {\n      path: string | null;\n      source: FileSystemEventSource;\n      type: \"entry.selected\";\n    }\n  | { path: string; type: \"entry.openRequested\" }\n  | {\n      path: string;\n      reason: FileSystemFolderLoadReason;\n      requestId: string;\n      type: \"folder.loadRequested\";\n    }\n  | {\n      items: FileSystemItem[];\n      path: string;\n      requestId: string;\n      type: \"folder.loadSucceeded\";\n    }\n  | {\n      error: string;\n      path: string;\n      requestId: string;\n      type: \"folder.loadFailed\";\n    };\n\nexport type FileSystemKernelCommand =\n  | {\n      path: string;\n      reason: FileSystemFolderLoadReason;\n      requestId: string;\n      type: \"folder.ensure\";\n    }\n  | { path: string; type: \"callback.pathChanged\" }\n  | { query: FileSystemQueryState; type: \"callback.queryChanged\" }\n  | { view: FileSystemView; type: \"callback.viewChanged\" }\n  | { entry: FileSystemEntry | null; type: \"callback.selectionChanged\" }\n  | { file: FileSystemFileEntry; type: \"file.open\" };\n\nexport type FileSystemKernelResult = {\n  commands: FileSystemKernelCommand[];\n  state: FileSystemKernelState;\n};\n\nexport function createFileSystemKernelState({\n  defaultPath = \"\",\n  defaultQuery,\n  defaultSelectedPath = null,\n  defaultView = \"list\",\n  items,\n}: {\n  defaultPath?: string;\n  defaultQuery?: Partial<FileSystemQueryState>;\n  defaultSelectedPath?: string | null;\n  defaultView?: FileSystemView;\n  items: readonly FileSystemItem[];\n}): FileSystemKernelState {\n  const tree = createFileSystemTreeState(items);\n  const requestedPath = normalizeFolderPath(defaultPath);\n  const path = isKnownFolderPath(tree, requestedPath) ? requestedPath : \"\";\n  const selectionPath = normalizeSelectionPath(tree, defaultSelectedPath);\n\n  return {\n    folders: new Map(),\n    history: { back: [], forward: [] },\n    path,\n    query: createFileSystemQueryState(defaultQuery),\n    selectionPath,\n    tree,\n    view: defaultView,\n  };\n}\n\nexport function reduceFileSystemKernel(\n  state: FileSystemKernelState,\n  event: FileSystemKernelEvent,\n): FileSystemKernelResult {\n  switch (event.type) {\n    case \"items.replaced\":\n      return reduceItemsReplaced(state, event.items);\n    case \"path.changed\":\n      return reducePathChanged(state, event);\n    case \"history.back\":\n      return reduceHistoryBack(state);\n    case \"history.forward\":\n      return reduceHistoryForward(state);\n    case \"query.changed\":\n      return reduceQueryChanged(state, event.query, event.source);\n    case \"query.searchChanged\":\n      return reduceQueryChanged(\n        state,\n        { ...state.query, search: event.search },\n        \"user\",\n      );\n    case \"query.sortKeyChanged\":\n      return reduceQueryChanged(\n        state,\n        { ...state.query, sort: nextSort(state.query, event.key) },\n        \"user\",\n      );\n    case \"view.changed\":\n      return reduceViewChanged(state, event.view, event.source);\n    case \"entry.selected\":\n      return reduceEntrySelected(state, event.path, event.source);\n    case \"entry.openRequested\":\n      return reduceEntryOpenRequested(state, event.path);\n    case \"folder.loadRequested\":\n      return reduceFolderLoadRequested(state, event);\n    case \"folder.loadSucceeded\":\n      return reduceFolderLoadSucceeded(state, event);\n    case \"folder.loadFailed\":\n      return reduceFolderLoadFailed(state, event);\n  }\n}\n\nfunction reduceItemsReplaced(\n  state: FileSystemKernelState,\n  items: readonly FileSystemItem[],\n): FileSystemKernelResult {\n  const tree = createFileSystemTreeState(items);\n  const path = isKnownFolderPath(tree, state.path) ? state.path : \"\";\n  const selectionPath = normalizeSelectionPath(tree, state.selectionPath);\n\n  return {\n    commands: [],\n    state: {\n      ...state,\n      folders: new Map(),\n      path,\n      selectionPath,\n      tree,\n    },\n  };\n}\n\nexport function createFileSystemTreeState(\n  items: readonly FileSystemItem[],\n): FileSystemTreeState {\n  return fileSystemTreeFromIndex(buildFileSystemIndex(items));\n}\n\nexport function fileSystemTreeToIndex(\n  tree: FileSystemTreeState,\n): FileSystemIndex {\n  const folders = new Map<string, FileSystemFolderEntry>();\n  const files = new Map<string, FileSystemFileEntry>();\n  const children = new Map<string, FileSystemEntry[]>();\n\n  for (const [path, entry] of tree.entriesByPath) {\n    if (entry.kind === \"folder\") {\n      folders.set(path, entry);\n    } else {\n      files.set(path, entry);\n    }\n  }\n\n  for (const [parentPath, childPaths] of tree.childrenByPath) {\n    const entries = childPaths\n      .map((path) => tree.entriesByPath.get(path))\n      .filter((entry): entry is FileSystemEntry => Boolean(entry));\n\n    if (entries.length) children.set(parentPath, entries);\n  }\n\n  return { children, files, folders };\n}\n\nexport function mergeFileSystemTreeItems({\n  items,\n  tree,\n}: {\n  items: readonly FileSystemItem[];\n  tree: FileSystemTreeState;\n}) {\n  return createFileSystemTreeState([...tree.entriesByPath.values(), ...items]);\n}\n\nexport function normalizeFileSystemEntryPath(path: string | null | undefined) {\n  if (!path) return null;\n\n  return path.endsWith(\"/\")\n    ? normalizeFolderPath(path)\n    : normalizeFilePath(path);\n}\n\nfunction fileSystemTreeFromIndex(index: FileSystemIndex): FileSystemTreeState {\n  const entriesByPath = new Map<string, FileSystemEntry>();\n  const childrenByPath = new Map<string, string[]>();\n\n  for (const [path, folder] of index.folders) entriesByPath.set(path, folder);\n  for (const [path, file] of index.files) entriesByPath.set(path, file);\n  for (const [path, children] of index.children) {\n    childrenByPath.set(\n      path,\n      children.map((entry) => entry.path),\n    );\n  }\n\n  return { childrenByPath, entriesByPath };\n}\n\nfunction reducePathChanged(\n  state: FileSystemKernelState,\n  event: Extract<FileSystemKernelEvent, { type: \"path.changed\" }>,\n): FileSystemKernelResult {\n  const path = normalizeFolderPath(event.path);\n  const nextPath = isKnownFolderPath(state.tree, path) ? path : \"\";\n\n  if (nextPath === state.path) return unchanged(state);\n\n  const nextState: FileSystemKernelState = {\n    ...state,\n    history:\n      event.source === \"user\"\n        ? { back: [...state.history.back, state.path], forward: [] }\n        : state.history,\n    path: nextPath,\n    query:\n      event.source === \"user\" || event.source === \"history\"\n        ? { ...state.query, search: \"\" }\n        : state.query,\n    selectionPath: null,\n  };\n  const commands: FileSystemKernelCommand[] =\n    event.source === \"controlled-prop\"\n      ? []\n      : [\n          { path: nextPath, type: \"callback.pathChanged\" },\n          { entry: null, type: \"callback.selectionChanged\" },\n        ];\n\n  return { commands, state: nextState };\n}\n\nfunction reduceHistoryBack(\n  state: FileSystemKernelState,\n): FileSystemKernelResult {\n  const path = state.history.back.at(-1);\n  if (path === undefined) return unchanged(state);\n\n  return {\n    commands: [\n      { path, type: \"callback.pathChanged\" },\n      { entry: null, type: \"callback.selectionChanged\" },\n    ],\n    state: {\n      ...state,\n      history: {\n        back: state.history.back.slice(0, -1),\n        forward: [state.path, ...state.history.forward],\n      },\n      path,\n      query: { ...state.query, search: \"\" },\n      selectionPath: null,\n    },\n  };\n}\n\nfunction reduceHistoryForward(\n  state: FileSystemKernelState,\n): FileSystemKernelResult {\n  const path = state.history.forward[0];\n  if (path === undefined) return unchanged(state);\n\n  return {\n    commands: [\n      { path, type: \"callback.pathChanged\" },\n      { entry: null, type: \"callback.selectionChanged\" },\n    ],\n    state: {\n      ...state,\n      history: {\n        back: [...state.history.back, state.path],\n        forward: state.history.forward.slice(1),\n      },\n      path,\n      query: { ...state.query, search: \"\" },\n      selectionPath: null,\n    },\n  };\n}\n\nfunction reduceQueryChanged(\n  state: FileSystemKernelState,\n  query: FileSystemQueryState,\n  source: FileSystemEventSource,\n): FileSystemKernelResult {\n  const nextSelectionPath = selectionMatchesQuery(state, query)\n    ? state.selectionPath\n    : null;\n  const commands: FileSystemKernelCommand[] = [];\n\n  if (source === \"user\")\n    commands.push({ query, type: \"callback.queryChanged\" });\n  if (nextSelectionPath !== state.selectionPath) {\n    commands.push({ entry: null, type: \"callback.selectionChanged\" });\n  }\n\n  return {\n    commands,\n    state: { ...state, query, selectionPath: nextSelectionPath },\n  };\n}\n\nfunction reduceViewChanged(\n  state: FileSystemKernelState,\n  view: FileSystemView,\n  source: FileSystemEventSource,\n): FileSystemKernelResult {\n  if (view === state.view) return unchanged(state);\n\n  return {\n    commands: source === \"user\" ? [{ type: \"callback.viewChanged\", view }] : [],\n    state: { ...state, view },\n  };\n}\n\nfunction reduceEntrySelected(\n  state: FileSystemKernelState,\n  path: string | null,\n  source: FileSystemEventSource,\n): FileSystemKernelResult {\n  const selectionPath = normalizeSelectionPath(state.tree, path);\n  if (selectionPath === state.selectionPath) return unchanged(state);\n\n  return {\n    commands:\n      source === \"user\"\n        ? [\n            {\n              entry: selectionPath\n                ? (state.tree.entriesByPath.get(selectionPath) ?? null)\n                : null,\n              type: \"callback.selectionChanged\",\n            },\n          ]\n        : [],\n    state: { ...state, selectionPath },\n  };\n}\n\nfunction reduceEntryOpenRequested(\n  state: FileSystemKernelState,\n  path: string,\n): FileSystemKernelResult {\n  const entry = state.tree.entriesByPath.get(\n    normalizeFileSystemEntryPath(path) ?? \"\",\n  );\n\n  if (!entry || entry.kind !== \"file\") return unchanged(state);\n  return { commands: [{ file: entry, type: \"file.open\" }], state };\n}\n\nfunction reduceFolderLoadRequested(\n  state: FileSystemKernelState,\n  event: Extract<FileSystemKernelEvent, { type: \"folder.loadRequested\" }>,\n): FileSystemKernelResult {\n  const path = normalizeFolderPath(event.path);\n\n  return {\n    commands: [\n      {\n        path,\n        reason: event.reason,\n        requestId: event.requestId,\n        type: \"folder.ensure\",\n      },\n    ],\n    state: {\n      ...state,\n      folders: new Map(state.folders).set(path, {\n        reason: event.reason,\n        requestId: event.requestId,\n        status: \"loading\",\n      }),\n    },\n  };\n}\n\nfunction reduceFolderLoadSucceeded(\n  state: FileSystemKernelState,\n  event: Extract<FileSystemKernelEvent, { type: \"folder.loadSucceeded\" }>,\n): FileSystemKernelResult {\n  const path = normalizeFolderPath(event.path);\n  const current = state.folders.get(path);\n\n  if (current?.status !== \"loading\" || current.requestId !== event.requestId) {\n    return unchanged(state);\n  }\n\n  const folders = new Map(state.folders);\n  folders.set(path, { status: \"loaded\" });\n  const tree = mergeFileSystemTreeItems({\n    items: event.items,\n    tree: state.tree,\n  });\n\n  return {\n    commands: [],\n    state: {\n      ...state,\n      folders,\n      selectionPath: normalizeSelectionPath(tree, state.selectionPath),\n      tree,\n    },\n  };\n}\n\nfunction reduceFolderLoadFailed(\n  state: FileSystemKernelState,\n  event: Extract<FileSystemKernelEvent, { type: \"folder.loadFailed\" }>,\n): FileSystemKernelResult {\n  const path = normalizeFolderPath(event.path);\n  const current = state.folders.get(path);\n\n  if (current?.status !== \"loading\" || current.requestId !== event.requestId) {\n    return unchanged(state);\n  }\n\n  return {\n    commands: [],\n    state: {\n      ...state,\n      folders: new Map(state.folders).set(path, {\n        error: event.error,\n        status: \"failed\",\n      }),\n    },\n  };\n}\n\nfunction unchanged(state: FileSystemKernelState): FileSystemKernelResult {\n  return { commands: [], state };\n}\n\nfunction isKnownFolderPath(tree: FileSystemTreeState, path: string) {\n  return path === \"\" || tree.entriesByPath.get(path)?.kind === \"folder\";\n}\n\nfunction normalizeSelectionPath(\n  tree: FileSystemTreeState,\n  path: string | null | undefined,\n) {\n  const entryPath = normalizeFileSystemEntryPath(path);\n\n  return entryPath && tree.entriesByPath.has(entryPath) ? entryPath : null;\n}\n\nfunction selectionMatchesQuery(\n  state: FileSystemKernelState,\n  query: FileSystemQueryState,\n) {\n  if (!state.selectionPath || !query.search) return true;\n\n  const rawIndex = fileSystemTreeToIndex(state.tree);\n  const visibleIndex = buildVisibleIndex(rawIndex, state.path, query);\n\n  return (\n    visibleIndex.files.has(state.selectionPath) ||\n    visibleIndex.folders.has(normalizeFolderPath(state.selectionPath))\n  );\n}\n\nfunction buildVisibleIndex(\n  index: FileSystemIndex,\n  path: string,\n  query: FileSystemQueryState,\n) {\n  return deriveVisibleIndex(index, path, query);\n}\n\nfunction nextSort(query: FileSystemQueryState, key: FileSystemSortKey) {\n  const defaultSort = DEFAULT_FILE_SYSTEM_QUERY.sort;\n\n  if (query.sort.key === key) {\n    return {\n      direction: query.sort.direction === \"asc\" ? \"desc\" : \"asc\",\n      key,\n    } satisfies FileSystemQueryState[\"sort\"];\n  }\n\n  return {\n    direction:\n      key === defaultSort.key || key === \"kind\"\n        ? defaultSort.direction\n        : \"desc\",\n    key,\n  } satisfies FileSystemQueryState[\"sort\"];\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-kernel.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-kernel-runtime.ts",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useFileSystemControlledProps } from \"./file-system-controlled-props\";\nimport { useFileSystemFolderTask } from \"./file-system-folder-task\";\nimport {\n  createFileSystemKernelState,\n  reduceFileSystemKernel,\n  type FileSystemKernelCommand,\n  type FileSystemKernelEvent,\n  type FileSystemKernelResult,\n  type FileSystemKernelState,\n} from \"./file-system-kernel\";\nimport { useFileSystemKernelCommandEffects } from \"./file-system-kernel-command-effects\";\nimport type {\n  FileSystemDispatch,\n  FileSystemEnsureChildren,\n} from \"./file-system-kernel-selectors\";\nimport type { FileSystemFileEntry, FileSystemProps } from \"./file-system-types\";\nimport { useKeyedMountEffect } from \"@/hooks/use-keyed-mount-effect\";\nimport { joinEffectKey } from \"@/lib/effect-key\";\n\ntype FileSystemKernelRuntimeStore = {\n  consumeCommands: () => FileSystemKernelCommand[];\n  dispatch: (event: FileSystemKernelEvent) => FileSystemKernelResult;\n  getState: () => FileSystemKernelState;\n  subscribe: (listener: () => void) => () => void;\n};\n\nexport type FileSystemKernelRuntime = {\n  dispatch: FileSystemDispatch;\n  ensureChildren: FileSystemEnsureChildren;\n  getState: () => FileSystemKernelState;\n  state: FileSystemKernelState;\n};\n\nexport function useFileSystemKernelRuntime({\n  defaultPath,\n  defaultQuery,\n  defaultSelectedPath,\n  defaultView = \"list\",\n  items,\n  loadChildren,\n  onFileCommand,\n  onPathChange,\n  onQueryChange,\n  onSelectionChange,\n  onViewChange,\n  path,\n  query,\n  selectedPath,\n  view,\n}: Pick<\n  FileSystemProps,\n  | \"defaultPath\"\n  | \"defaultQuery\"\n  | \"defaultSelectedPath\"\n  | \"defaultView\"\n  | \"items\"\n  | \"loadChildren\"\n  | \"onPathChange\"\n  | \"onQueryChange\"\n  | \"onSelectionChange\"\n  | \"onViewChange\"\n  | \"path\"\n  | \"query\"\n  | \"selectedPath\"\n  | \"view\"\n> & {\n  onFileCommand: (file: FileSystemFileEntry) => void;\n}): FileSystemKernelRuntime {\n  const [commandFlushVersion, setCommandFlushVersion] = React.useState(0);\n  const storeRef = React.useRef<FileSystemKernelRuntimeStore | null>(null);\n\n  if (!storeRef.current) {\n    storeRef.current = createFileSystemKernelRuntimeStore({\n      initialState: createFileSystemKernelState({\n        defaultPath,\n        defaultQuery,\n        defaultSelectedPath,\n        defaultView,\n        items,\n      }),\n      scheduleCommandFlush: () => {\n        setCommandFlushVersion((version) => version + 1);\n      },\n    });\n  }\n\n  const store = storeRef.current;\n  const state = React.useSyncExternalStore(\n    store.subscribe,\n    store.getState,\n    store.getState,\n  );\n  const dispatch = React.useCallback<FileSystemDispatch>(\n    (event) => {\n      store.dispatch(event);\n    },\n    [store],\n  );\n  const getState = React.useCallback(() => store.getState(), [store]);\n\n  useKeyedMountEffect(joinEffectKey([dispatch, items]), () => {\n    dispatch({ items, type: \"items.replaced\" });\n  });\n\n  useFileSystemControlledProps({\n    dispatch,\n    path,\n    query,\n    selectedPath,\n    view,\n  });\n\n  const folderTask = useFileSystemFolderTask({\n    dispatch,\n    getState,\n    loadChildren,\n  });\n\n  useKeyedMountEffect(joinEffectKey([folderTask, state.path]), () => {\n    void folderTask.ensureChildren(state.path).catch(() => {});\n  });\n\n  const callbacks = React.useMemo(\n    () => ({\n      onFileCommand,\n      onPathChange,\n      onQueryChange,\n      onSelectionChange,\n      onViewChange,\n    }),\n    [\n      onFileCommand,\n      onPathChange,\n      onQueryChange,\n      onSelectionChange,\n      onViewChange,\n    ],\n  );\n\n  useFileSystemKernelCommandEffects({\n    callbacks,\n    consumeCommands: store.consumeCommands,\n    flushVersion: commandFlushVersion,\n    folderTask,\n  });\n\n  return React.useMemo(\n    () => ({\n      dispatch,\n      ensureChildren: folderTask.ensureChildren,\n      getState,\n      state,\n    }),\n    [dispatch, folderTask.ensureChildren, getState, state],\n  );\n}\n\nfunction createFileSystemKernelRuntimeStore({\n  initialState,\n  scheduleCommandFlush,\n}: {\n  initialState: FileSystemKernelState;\n  scheduleCommandFlush: () => void;\n}): FileSystemKernelRuntimeStore {\n  const listeners = new Set<() => void>();\n  let commandQueue: FileSystemKernelCommand[] = [];\n  let state = initialState;\n\n  return {\n    consumeCommands: () => {\n      const commands = commandQueue;\n\n      commandQueue = [];\n      return commands;\n    },\n    dispatch: (event) => {\n      const result = reduceFileSystemKernel(state, event);\n\n      if (result.state !== state) {\n        state = result.state;\n        for (const listener of listeners) listener();\n      }\n\n      if (result.commands.length) {\n        commandQueue = [...commandQueue, ...result.commands];\n        scheduleCommandFlush();\n      }\n\n      return result;\n    },\n    getState: () => state,\n    subscribe: (listener) => {\n      listeners.add(listener);\n      return () => {\n        listeners.delete(listener);\n      };\n    },\n  };\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-kernel-runtime.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-kernel-command-effects.ts",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport type { FileSystemFolderTask } from \"./file-system-folder-task\";\nimport type { FileSystemKernelCommand } from \"./file-system-kernel\";\nimport type { FileSystemFileEntry, FileSystemProps } from \"./file-system-types\";\nimport { useKeyedMountEffect } from \"@/hooks/use-keyed-mount-effect\";\nimport { joinEffectKey } from \"@/lib/effect-key\";\n\nexport type FileSystemKernelCallbacks = {\n  onFileCommand: (file: FileSystemFileEntry) => void;\n  onPathChange: FileSystemProps[\"onPathChange\"];\n  onQueryChange: FileSystemProps[\"onQueryChange\"];\n  onSelectionChange: FileSystemProps[\"onSelectionChange\"];\n  onViewChange: FileSystemProps[\"onViewChange\"];\n};\n\nexport function useFileSystemKernelCommandEffects({\n  callbacks,\n  consumeCommands,\n  flushVersion,\n  folderTask,\n}: {\n  callbacks: FileSystemKernelCallbacks;\n  consumeCommands: () => FileSystemKernelCommand[];\n  flushVersion: number;\n  folderTask: FileSystemFolderTask;\n}) {\n  useKeyedMountEffect(\n    joinEffectKey([callbacks, consumeCommands, flushVersion, folderTask]),\n    () => {\n      const commands = consumeCommands();\n\n      if (!commands.length) return;\n\n      for (const command of commands) {\n        switch (command.type) {\n          case \"callback.pathChanged\":\n            callbacks.onPathChange?.(command.path);\n            break;\n          case \"callback.queryChanged\":\n            callbacks.onQueryChange?.(command.query);\n            break;\n          case \"callback.viewChanged\":\n            callbacks.onViewChange?.(command.view);\n            break;\n          case \"callback.selectionChanged\":\n            callbacks.onSelectionChange?.(command.entry);\n            break;\n          case \"file.open\":\n            callbacks.onFileCommand(command.file);\n            break;\n          case \"folder.ensure\":\n            folderTask.runFolderCommand(command);\n            break;\n        }\n      }\n    },\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-kernel-command-effects.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-async-task.ts",
      "content": "\"use client\";\n\nexport type FileSystemAsyncTaskId = string;\n\nexport type FileSystemAsyncTaskKey = string;\n\nexport type FileSystemAsyncTask<TInput> = {\n  abortController: AbortController;\n  id: FileSystemAsyncTaskId;\n  input: TInput;\n  key: FileSystemAsyncTaskKey;\n};\n\nexport type FileSystemAsyncTaskWaiter<TResult> = {\n  reject: (error: unknown) => void;\n  resolve: (result: TResult) => void;\n};\n\nexport type FileSystemAsyncTaskStart<TInput, TResult> = {\n  promise: Promise<TResult>;\n  started: boolean;\n  task: FileSystemAsyncTask<TInput>;\n};\n\nexport type FileSystemAsyncTaskRuntime<TInput, TResult> = {\n  abort: (key: FileSystemAsyncTaskKey, reason: string) => void;\n  abortAll: (reason: string) => void;\n  fail: (task: FileSystemAsyncTask<TInput>, error: unknown) => boolean;\n  get: (key: FileSystemAsyncTaskKey) => FileSystemAsyncTask<TInput> | null;\n  join: (task: FileSystemAsyncTask<TInput>) => Promise<TResult>;\n  start: (input: TInput) => FileSystemAsyncTaskStart<TInput, TResult>;\n  succeed: (task: FileSystemAsyncTask<TInput>, result: TResult) => boolean;\n};\n\nexport function createFileSystemAsyncTaskRuntime<TInput, TResult>({\n  createTaskId = createDefaultTaskId,\n  keyForInput,\n}: {\n  createTaskId?: () => FileSystemAsyncTaskId;\n  keyForInput: (input: TInput) => FileSystemAsyncTaskKey;\n}): FileSystemAsyncTaskRuntime<TInput, TResult> {\n  const tasksByKey = new Map<\n    FileSystemAsyncTaskKey,\n    FileSystemAsyncTask<TInput>\n  >();\n  const waitersByTaskId = new Map<\n    FileSystemAsyncTaskId,\n    FileSystemAsyncTaskWaiter<TResult>[]\n  >();\n\n  function join(task: FileSystemAsyncTask<TInput>) {\n    const promise = new Promise<TResult>((resolve, reject) => {\n      const currentTask = tasksByKey.get(task.key);\n\n      if (currentTask?.id !== task.id) {\n        reject(createStaleTaskError(task));\n        return;\n      }\n\n      const waiters = waitersByTaskId.get(task.id) ?? [];\n      waiters.push({ reject, resolve });\n      waitersByTaskId.set(task.id, waiters);\n    });\n\n    void promise.catch(() => {});\n    return promise;\n  }\n\n  function start(input: TInput): FileSystemAsyncTaskStart<TInput, TResult> {\n    const key = keyForInput(input);\n    const currentTask = tasksByKey.get(key);\n\n    if (currentTask) {\n      return {\n        promise: join(currentTask),\n        started: false,\n        task: currentTask,\n      };\n    }\n\n    const task = {\n      abortController: new AbortController(),\n      id: createTaskId(),\n      input,\n      key,\n    };\n\n    tasksByKey.set(key, task);\n\n    return {\n      promise: join(task),\n      started: true,\n      task,\n    };\n  }\n\n  function succeed(task: FileSystemAsyncTask<TInput>, result: TResult) {\n    return settle(task, (waiter) => waiter.resolve(result));\n  }\n\n  function fail(task: FileSystemAsyncTask<TInput>, error: unknown) {\n    return settle(task, (waiter) => waiter.reject(error));\n  }\n\n  function abort(key: FileSystemAsyncTaskKey, reason: string) {\n    const task = tasksByKey.get(key);\n\n    if (!task) return;\n\n    task.abortController.abort();\n    fail(task, createAbortTaskError(task, reason));\n  }\n\n  function abortAll(reason: string) {\n    for (const key of [...tasksByKey.keys()]) {\n      abort(key, reason);\n    }\n  }\n\n  function settle(\n    task: FileSystemAsyncTask<TInput>,\n    settleWaiter: (waiter: FileSystemAsyncTaskWaiter<TResult>) => void,\n  ) {\n    const currentTask = tasksByKey.get(task.key);\n\n    if (currentTask?.id !== task.id) return false;\n\n    const waiters = waitersByTaskId.get(task.id) ?? [];\n    tasksByKey.delete(task.key);\n    waitersByTaskId.delete(task.id);\n\n    for (const waiter of waiters) settleWaiter(waiter);\n\n    return true;\n  }\n\n  function get(key: FileSystemAsyncTaskKey) {\n    return tasksByKey.get(key) ?? null;\n  }\n\n  return { abort, abortAll, fail, get, join, start, succeed };\n}\n\nfunction createDefaultTaskId() {\n  return `task:${Math.random().toString(36).slice(2)}`;\n}\n\nfunction createStaleTaskError<TInput>(task: FileSystemAsyncTask<TInput>) {\n  return new Error(`Stale async task: ${task.id}`);\n}\n\nfunction createAbortTaskError<TInput>(\n  task: FileSystemAsyncTask<TInput>,\n  reason: string,\n) {\n  return new Error(`Aborted async task ${task.id}: ${reason}`);\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-async-task.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-folder-task.ts",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useMountEffect } from \"@/hooks/use-mount-effect\";\n\nimport { normalizeFolderPath } from \"./file-system-index\";\nimport type {\n  FileSystemKernelCommand,\n  FileSystemKernelState,\n} from \"./file-system-kernel\";\nimport {\n  selectFileSystemKernel,\n  type FileSystemDispatch,\n  type FileSystemEnsureChildren,\n} from \"./file-system-kernel-selectors\";\nimport type {\n  FileSystemEntry,\n  FileSystemItem,\n  FileSystemProps,\n} from \"./file-system-types\";\n\nexport type FileSystemFolderTask = {\n  abortAll: () => void;\n  ensureChildren: FileSystemEnsureChildren;\n  runFolderCommand: (\n    command: Extract<FileSystemKernelCommand, { type: \"folder.ensure\" }>,\n  ) => void;\n};\n\ntype FolderLoadRequest = {\n  abortController: AbortController;\n  path: string;\n  requestId: string;\n  status: \"queued\" | \"loading\";\n};\n\ntype FolderLoadWaiter = {\n  reject: (error: unknown) => void;\n  resolve: (children: FileSystemEntry[]) => void;\n};\n\nexport function useFileSystemFolderTask({\n  dispatch,\n  getState,\n  loadChildren,\n}: {\n  dispatch: FileSystemDispatch;\n  getState: () => FileSystemKernelState;\n  loadChildren: FileSystemProps[\"loadChildren\"];\n}): FileSystemFolderTask {\n  const nextRequestNumberRef = React.useRef(0);\n  const requestsByPathRef = React.useRef(new Map<string, FolderLoadRequest>());\n  const waitersByRequestIdRef = React.useRef(\n    new Map<string, FolderLoadWaiter[]>(),\n  );\n  const selectVisibleChildren = React.useCallback(\n    (path: string) =>\n      selectFileSystemKernel({ state: getState() }).index.children.get(path) ??\n      [],\n    [getState],\n  );\n\n  const joinRequest = React.useCallback((request: FolderLoadRequest) => {\n    const promise = new Promise<FileSystemEntry[]>((resolve, reject) => {\n      if (!isCurrentFolderRequest(requestsByPathRef.current, request)) {\n        reject(createStaleFolderRequestError(request));\n        return;\n      }\n\n      const waiters =\n        waitersByRequestIdRef.current.get(request.requestId) ?? [];\n      waiters.push({ reject, resolve });\n      waitersByRequestIdRef.current.set(request.requestId, waiters);\n    });\n\n    void promise.catch(() => {});\n    return promise;\n  }, []);\n\n  const createRequest = React.useCallback((path: string) => {\n    const request: FolderLoadRequest = {\n      abortController: new AbortController(),\n      path,\n      requestId: `folder:${++nextRequestNumberRef.current}`,\n      status: \"queued\",\n    };\n\n    requestsByPathRef.current.set(path, request);\n    return request;\n  }, []);\n\n  const settleRequest = React.useCallback(\n    (\n      request: FolderLoadRequest,\n      settleWaiter: (waiter: FolderLoadWaiter) => void,\n    ) => {\n      if (!isCurrentFolderRequest(requestsByPathRef.current, request)) {\n        return false;\n      }\n\n      const waiters =\n        waitersByRequestIdRef.current.get(request.requestId) ?? [];\n      requestsByPathRef.current.delete(request.path);\n      waitersByRequestIdRef.current.delete(request.requestId);\n\n      for (const waiter of waiters) settleWaiter(waiter);\n      return true;\n    },\n    [],\n  );\n\n  const failRequest = React.useCallback(\n    (request: FolderLoadRequest, error: unknown) => {\n      settleRequest(request, (waiter) => waiter.reject(error));\n    },\n    [settleRequest],\n  );\n\n  const settleRequestFromCommittedChildren = React.useCallback(\n    (request: FolderLoadRequest) => {\n      const children = selectVisibleChildren(request.path);\n\n      settleRequest(request, (waiter) => waiter.resolve(children));\n    },\n    [selectVisibleChildren, settleRequest],\n  );\n\n  const abortRequest = React.useCallback(\n    (path: string, reason: string) => {\n      const request = requestsByPathRef.current.get(path);\n\n      if (!request) return;\n\n      request.abortController.abort();\n      failRequest(request, createAbortFolderRequestError(request, reason));\n    },\n    [failRequest],\n  );\n\n  const ensureChildren = React.useCallback<FileSystemEnsureChildren>(\n    (path, options = {}) => {\n      const folderPath = normalizeFolderPath(path);\n      const selectors = selectFileSystemKernel({ state: getState() });\n      const folder = selectors.rawIndex.folders.get(folderPath);\n      const rawChildren = selectors.rawIndex.children.get(folderPath) ?? [];\n      const visibleChildren = selectors.index.children.get(folderPath) ?? [];\n\n      if (!loadChildren || !folder?.hasChildren) {\n        return Promise.resolve(visibleChildren);\n      }\n      if (!options.retry && rawChildren.length > 0) {\n        return Promise.resolve(visibleChildren);\n      }\n      if (options.retry) {\n        abortRequest(folderPath, \"retry\");\n      }\n\n      let request = requestsByPathRef.current.get(folderPath);\n      const started = !request;\n\n      if (!request) {\n        request = createRequest(folderPath);\n      }\n\n      const promise = joinRequest(request);\n\n      if (started) {\n        dispatch({\n          path: folderPath,\n          reason: options.retry ? \"retry\" : \"expand\",\n          requestId: request.requestId,\n          type: \"folder.loadRequested\",\n        });\n      }\n\n      return promise.catch(() => selectVisibleChildren(folderPath));\n    },\n    [\n      abortRequest,\n      createRequest,\n      dispatch,\n      getState,\n      joinRequest,\n      loadChildren,\n      selectVisibleChildren,\n    ],\n  );\n\n  const runFolderCommand = React.useCallback<\n    FileSystemFolderTask[\"runFolderCommand\"]\n  >(\n    (command) => {\n      const path = normalizeFolderPath(command.path);\n      const request = requestsByPathRef.current.get(path);\n\n      if (\n        !request ||\n        request.requestId !== command.requestId ||\n        request.status === \"loading\"\n      ) {\n        return;\n      }\n\n      if (!loadChildren) {\n        settleRequestFromCommittedChildren(request);\n        return;\n      }\n\n      request.status = \"loading\";\n\n      void (async () => {\n        try {\n          let cursor: string | null = null;\n          const items: FileSystemItem[] = [];\n\n          do {\n            const result = await loadChildren({\n              cursor,\n              path: request.path,\n              signal: request.abortController.signal,\n            });\n\n            items.push(...result.items);\n            cursor = result.nextCursor ?? null;\n          } while (cursor && !request.abortController.signal.aborted);\n\n          if (request.abortController.signal.aborted) {\n            failRequest(request, new Error(\"Folder request aborted.\"));\n            return;\n          }\n\n          dispatch({\n            items,\n            path: request.path,\n            requestId: request.requestId,\n            type: \"folder.loadSucceeded\",\n          });\n          settleRequestFromCommittedChildren(request);\n        } catch (error) {\n          if (!request.abortController.signal.aborted) {\n            dispatch({\n              error: errorMessage(error),\n              path: request.path,\n              requestId: request.requestId,\n              type: \"folder.loadFailed\",\n            });\n          }\n          failRequest(request, error);\n        }\n      })();\n    },\n    [dispatch, failRequest, loadChildren, settleRequestFromCommittedChildren],\n  );\n\n  const abortAll = React.useCallback(() => {\n    for (const path of [...requestsByPathRef.current.keys()]) {\n      abortRequest(path, \"file-system folder task unmounted\");\n    }\n  }, [abortRequest]);\n\n  useMountEffect(() => abortAll);\n\n  return React.useMemo(\n    () => ({ abortAll, ensureChildren, runFolderCommand }),\n    [abortAll, ensureChildren, runFolderCommand],\n  );\n}\n\nfunction errorMessage(error: unknown) {\n  return error instanceof Error && error.message\n    ? error.message\n    : \"Unable to load this folder.\";\n}\n\nfunction isCurrentFolderRequest(\n  requestsByPath: Map<string, FolderLoadRequest>,\n  request: FolderLoadRequest,\n) {\n  return requestsByPath.get(request.path)?.requestId === request.requestId;\n}\n\nfunction createStaleFolderRequestError(request: FolderLoadRequest) {\n  return new Error(`Stale folder request: ${request.requestId}`);\n}\n\nfunction createAbortFolderRequestError(\n  request: FolderLoadRequest,\n  reason: string,\n) {\n  return new Error(`Aborted folder request ${request.requestId}: ${reason}`);\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-folder-task.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-controlled-props.ts",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport type { FileSystemDispatch } from \"./file-system-kernel-selectors\";\nimport type { FileSystemQueryState, FileSystemView } from \"./file-system-types\";\nimport { useKeyedMountEffect } from \"@/hooks/use-keyed-mount-effect\";\nimport { joinEffectKey } from \"@/lib/effect-key\";\n\nexport function useFileSystemControlledProps({\n  dispatch,\n  path,\n  query,\n  selectedPath,\n  view,\n}: {\n  dispatch: FileSystemDispatch;\n  path?: string;\n  query?: FileSystemQueryState;\n  selectedPath?: string | null;\n  view?: FileSystemView;\n}) {\n  useKeyedMountEffect(joinEffectKey([dispatch, path]), () => {\n    if (path !== undefined) {\n      dispatch({ path, source: \"controlled-prop\", type: \"path.changed\" });\n    }\n  });\n\n  useKeyedMountEffect(joinEffectKey([dispatch, query]), () => {\n    if (query !== undefined) {\n      dispatch({ query, source: \"controlled-prop\", type: \"query.changed\" });\n    }\n  });\n\n  useKeyedMountEffect(joinEffectKey([dispatch, view]), () => {\n    if (view !== undefined) {\n      dispatch({ source: \"controlled-prop\", type: \"view.changed\", view });\n    }\n  });\n\n  useKeyedMountEffect(joinEffectKey([dispatch, selectedPath]), () => {\n    if (selectedPath !== undefined) {\n      dispatch({\n        path: selectedPath,\n        source: \"controlled-prop\",\n        type: \"entry.selected\",\n      });\n    }\n  });\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-controlled-props.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-kernel-selectors.ts",
      "content": "\"use client\";\n\nimport type {\n  FileSystemBrowserState,\n  FileSystemHeaderState,\n  FileSystemSelectionState,\n} from \"./file-system-browser-state\";\nimport { normalizeFolderPath } from \"./file-system-index\";\nimport {\n  fileSystemTreeToIndex,\n  normalizeFileSystemEntryPath,\n  type FileSystemKernelEvent,\n  type FileSystemKernelState,\n} from \"./file-system-kernel\";\nimport { deriveVisibleIndex } from \"./file-system-query\";\nimport type { FileSystemSourceController } from \"./file-system-source-controller\";\nimport type {\n  FileSystemEntry,\n  FileSystemFileEntry,\n  FileSystemIndex,\n  FileSystemView,\n} from \"./file-system-types\";\n\nconst rawIndexCache = new WeakMap<\n  FileSystemKernelState[\"tree\"],\n  FileSystemIndex\n>();\nconst visibleIndexCache = new WeakMap<\n  FileSystemKernelState[\"tree\"],\n  Map<string, WeakMap<FileSystemKernelState[\"query\"], FileSystemIndex>>\n>();\n\nexport type FileSystemDispatch = (event: FileSystemKernelEvent) => void;\n\nexport type FileSystemEnsureChildren = (\n  path: string,\n  options?: { retry?: boolean },\n) => Promise<FileSystemEntry[]>;\n\nexport type FileSystemKernelSelectors = {\n  index: FileSystemIndex;\n  rawIndex: FileSystemIndex;\n  selectedEntry: FileSystemEntry | null;\n  visibleEntries: FileSystemEntry[];\n};\n\nexport function selectFileSystemKernel({\n  state,\n}: {\n  state: FileSystemKernelState;\n}): FileSystemKernelSelectors {\n  const rawIndex = selectRawIndex(state);\n  const index = selectVisibleIndex(state, rawIndex);\n\n  return {\n    index,\n    rawIndex,\n    selectedEntry: selectSelectedEntry(state),\n    visibleEntries: index.children.get(state.path) ?? [],\n  };\n}\n\nfunction selectRawIndex(state: FileSystemKernelState) {\n  const cached = rawIndexCache.get(state.tree);\n  if (cached) return cached;\n\n  const index = fileSystemTreeToIndex(state.tree);\n\n  rawIndexCache.set(state.tree, index);\n  return index;\n}\n\nfunction selectVisibleIndex(\n  state: FileSystemKernelState,\n  rawIndex: FileSystemIndex,\n) {\n  let pathCache = visibleIndexCache.get(state.tree);\n\n  if (!pathCache) {\n    pathCache = new Map();\n    visibleIndexCache.set(state.tree, pathCache);\n  }\n\n  let queryCache = pathCache.get(state.path);\n\n  if (!queryCache) {\n    queryCache = new WeakMap();\n    pathCache.set(state.path, queryCache);\n  }\n\n  const cached = queryCache.get(state.query);\n  if (cached) return cached;\n\n  const index = deriveVisibleIndex(rawIndex, state.path, state.query);\n\n  queryCache.set(state.query, index);\n  return index;\n}\n\nexport function selectSelectedEntry(state: FileSystemKernelState) {\n  if (!state.selectionPath) return null;\n\n  return state.tree.entriesByPath.get(state.selectionPath) ?? null;\n}\n\nexport function selectFileSystemBrowserState({\n  dispatch,\n  ensureChildren,\n  getState,\n  state,\n}: {\n  dispatch: FileSystemDispatch;\n  ensureChildren: FileSystemEnsureChildren;\n  getState: () => FileSystemKernelState;\n  state: FileSystemKernelState;\n}): FileSystemBrowserState {\n  const selectors = selectFileSystemKernel({ state });\n\n  return {\n    canGoBack: state.history.back.length > 0,\n    canGoForward: state.history.forward.length > 0,\n    currentPath: state.path,\n    entries: selectors.visibleEntries,\n    ensureChildren,\n    folderErrors: selectFolderErrors(state),\n    goBack: () => dispatch({ type: \"history.back\" }),\n    goForward: () => dispatch({ type: \"history.forward\" }),\n    index: selectors.index,\n    loadingFolders: selectLoadingFolders(state),\n    navigateTo: (path) =>\n      dispatch({ path, source: \"user\", type: \"path.changed\" }),\n    query: state.query,\n    rawIndex: selectors.rawIndex,\n    selectEntry: (entry) =>\n      dispatch({\n        path: entry?.path ?? null,\n        source: \"user\",\n        type: \"entry.selected\",\n      }),\n    selectedEntry: selectors.selectedEntry,\n    selectedPath: state.selectionPath,\n    selectFirstChildAfterEnsure: async (path) => {\n      const folderPath = normalizeFolderPath(path);\n      const requestedCurrentPath = state.path;\n      const children = await ensureChildren(path);\n      const entry = children[0] ?? null;\n      const latestState = getState();\n\n      if (latestState.selectionPath !== folderPath) return null;\n      if (latestState.path !== requestedCurrentPath) return null;\n\n      if (entry) {\n        dispatch({ path: entry.path, source: \"user\", type: \"entry.selected\" });\n      }\n\n      return entry;\n    },\n    setSearch: (search) => dispatch({ search, type: \"query.searchChanged\" }),\n    setSortKey: (key) => dispatch({ key, type: \"query.sortKeyChanged\" }),\n    setView: (view: FileSystemView) =>\n      dispatch({ source: \"user\", type: \"view.changed\", view }),\n    view: state.view,\n  };\n}\n\nexport function selectFileSystemHeaderState({\n  browser,\n  title,\n}: {\n  browser: FileSystemBrowserState;\n  title: string;\n}): FileSystemHeaderState {\n  return {\n    canGoBack: browser.canGoBack,\n    canGoForward: browser.canGoForward,\n    currentPath: browser.currentPath,\n    goBack: browser.goBack,\n    goForward: browser.goForward,\n    query: browser.query,\n    setSearch: browser.setSearch,\n    setSortKey: browser.setSortKey,\n    setView: browser.setView,\n    title,\n    view: browser.view,\n  };\n}\n\nexport function selectFileSystemSelectionState({\n  resolveSource,\n  state,\n}: {\n  resolveSource: FileSystemSourceController[\"resolveFileSource\"];\n  state: FileSystemKernelState;\n}): FileSystemSelectionState {\n  return {\n    entry: selectSelectedEntry(state),\n    resolveSource,\n  };\n}\n\nexport function selectFileSystemListInput({\n  state,\n}: {\n  state: FileSystemKernelState;\n}) {\n  const selectors = selectFileSystemKernel({ state });\n\n  return {\n    currentPath: state.path,\n    folderErrors: selectFolderErrors(state),\n    index: selectors.index,\n    loadingFolders: selectLoadingFolders(state),\n    search: state.query.search,\n    selectedPath: state.selectionPath,\n  };\n}\n\nexport function selectFolderErrors(state: FileSystemKernelState) {\n  const errors = new Map<string, string>();\n\n  for (const [path, folder] of state.folders) {\n    if (folder.status === \"failed\") errors.set(path, folder.error);\n  }\n\n  return errors;\n}\n\nexport function selectLoadingFolders(state: FileSystemKernelState) {\n  const folders = new Set<string>();\n\n  for (const [path, folder] of state.folders) {\n    if (folder.status === \"loading\") folders.add(path);\n  }\n\n  return folders;\n}\n\nexport function selectFileEntry(\n  state: FileSystemKernelState,\n  path: string,\n): FileSystemFileEntry | null {\n  const entryPath = normalizeFileSystemEntryPath(path);\n  const entry = entryPath ? state.tree.entriesByPath.get(entryPath) : null;\n\n  return entry?.kind === \"file\" ? entry : null;\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-kernel-selectors.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-selection-source-task.ts",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport type { ViewerSource } from \"@/lib/viewer-source\";\n\nimport { createFileSystemAsyncTaskRuntime } from \"./file-system-async-task\";\nimport type { FileSystemFileEntry } from \"./file-system-types\";\nimport { useKeyedMountEffect } from \"@/hooks/use-keyed-mount-effect\";\nimport { joinEffectKey } from \"@/lib/effect-key\";\n\nexport type FileSystemSourceResolver = (\n  file: FileSystemFileEntry,\n  signal: AbortSignal,\n) => Promise<ViewerSource | null>;\n\nexport type FileSystemSelectionSourceState =\n  | { source: ViewerSource | null; status: \"idle\" }\n  | { source: null; status: \"loading\" }\n  | { source: ViewerSource; status: \"ready\" }\n  | { source: null; status: \"unavailable\" }\n  | { error: string; source: null; status: \"error\" };\n\nexport type FileSystemSelectionSourceTask = FileSystemSelectionSourceState & {\n  retry: () => void;\n};\n\ntype FileSystemSelectionSourceTaskInput = {\n  file: FileSystemFileEntry;\n  retryKey: number;\n};\n\nexport function useFileSystemSelectionSourceTask(\n  file: FileSystemFileEntry | null,\n  resolveFileSource?: FileSystemSourceResolver,\n): FileSystemSelectionSourceTask {\n  const [retryKey, setRetryKey] = React.useState(0);\n  const [state, setState] = React.useState<FileSystemSelectionSourceState>({\n    source: null,\n    status: \"idle\",\n  });\n  const nextTaskNumberRef = React.useRef(0);\n  const taskRuntimeRef = React.useRef(\n    createFileSystemAsyncTaskRuntime<\n      FileSystemSelectionSourceTaskInput,\n      ViewerSource | null\n    >({\n      createTaskId: () => `preview-source:${++nextTaskNumberRef.current}`,\n      keyForInput: (input) =>\n        [\n          \"preview-source\",\n          input.file.path,\n          input.file.key,\n          input.retryKey,\n        ].join(\"\\0\"),\n    }),\n  );\n  const retry = React.useCallback(() => setRetryKey((key) => key + 1), []);\n\n  useKeyedMountEffect(\n    joinEffectKey([file, resolveFileSource, retryKey]),\n    () => {\n      if (!file) {\n        setState({ source: null, status: \"idle\" });\n        return;\n      }\n      if (file.source) {\n        setState({ source: file.source, status: \"ready\" });\n        return;\n      }\n      if (!resolveFileSource) {\n        setState({ source: null, status: \"unavailable\" });\n        return;\n      }\n\n      const taskRuntime = taskRuntimeRef.current;\n      const { promise, task } = taskRuntime.start({ file, retryKey });\n\n      setState({ source: null, status: \"loading\" });\n      void resolveFileSource(file, task.abortController.signal)\n        .then((source) => taskRuntime.succeed(task, source))\n        .catch((error) => taskRuntime.fail(task, error));\n\n      void promise\n        .then((source) => {\n          if (task.abortController.signal.aborted) return;\n          setState(\n            source\n              ? { source, status: \"ready\" }\n              : { source: null, status: \"unavailable\" },\n          );\n        })\n        .catch((error) => {\n          if (task.abortController.signal.aborted) return;\n\n          setState({\n            error: selectionSourceErrorMessage(error),\n            source: null,\n            status: \"error\",\n          });\n        });\n\n      return () =>\n        taskRuntime.abort(task.key, \"preview source task superseded\");\n    },\n  );\n\n  return { ...state, retry };\n}\n\nfunction selectionSourceErrorMessage(error: unknown) {\n  return error instanceof Error && error.message\n    ? error.message\n    : \"Couldn't load this file.\";\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-selection-source-task.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-open-source-task.ts",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { useMountEffect } from \"@/hooks/use-mount-effect\";\nimport type { ViewerSource } from \"@/lib/viewer-source\";\n\nimport { createFileSystemAsyncTaskRuntime } from \"./file-system-async-task\";\nimport type { FileSystemSourceController } from \"./file-system-source-controller\";\nimport type { FileSystemFileEntry, FileSystemProps } from \"./file-system-types\";\n\nexport type FileSystemOpenSourceState =\n  | { status: \"idle\" }\n  | { file: FileSystemFileEntry; status: \"resolving\" }\n  | { file: FileSystemFileEntry; source: ViewerSource; status: \"open\" }\n  | { file: FileSystemFileEntry; status: \"unavailable\" }\n  | { error: string; file: FileSystemFileEntry; status: \"failed\" };\n\nexport type FileSystemOpenSourceTask = {\n  close: () => void;\n  open: (file: FileSystemFileEntry) => void;\n  state: FileSystemOpenSourceState;\n};\n\ntype FileSystemOpenSourceTaskInput = {\n  file: FileSystemFileEntry;\n};\n\nexport function useFileSystemOpenSourceTask({\n  onFileOpen,\n  resolveFileSource,\n}: {\n  onFileOpen?: FileSystemProps[\"onFileOpen\"];\n  resolveFileSource: FileSystemSourceController[\"resolveFileSource\"];\n}): FileSystemOpenSourceTask {\n  const [state, setState] = React.useState<FileSystemOpenSourceState>({\n    status: \"idle\",\n  });\n  const nextTaskNumberRef = React.useRef(0);\n  const taskRuntimeRef = React.useRef(\n    createFileSystemAsyncTaskRuntime<\n      FileSystemOpenSourceTaskInput,\n      ViewerSource | null\n    >({\n      createTaskId: () => `open-source:${++nextTaskNumberRef.current}`,\n      keyForInput: () => \"open-source\",\n    }),\n  );\n\n  const close = React.useCallback(() => {\n    taskRuntimeRef.current.abortAll(\"open source task closed\");\n    setState({ status: \"idle\" });\n  }, []);\n\n  const open = React.useCallback(\n    (file: FileSystemFileEntry) => {\n      const taskRuntime = taskRuntimeRef.current;\n\n      taskRuntime.abortAll(\"open source task superseded\");\n      const { promise, task } = taskRuntime.start({ file });\n      setState({ file, status: \"resolving\" });\n\n      void resolveFileSource(file, task.abortController.signal)\n        .then((source) => taskRuntime.succeed(task, source))\n        .catch((error) => taskRuntime.fail(task, error));\n\n      void promise\n        .then((source) => {\n          if (task.abortController.signal.aborted) return;\n\n          onFileOpen?.(file, source);\n          if (!source) {\n            setState({ file, status: \"unavailable\" });\n            return;\n          }\n\n          setState({ file, source, status: \"open\" });\n        })\n        .catch((error: unknown) => {\n          if (task.abortController.signal.aborted) return;\n\n          onFileOpen?.(file, null);\n          setState({\n            error: openSourceErrorMessage(error),\n            file,\n            status: \"failed\",\n          });\n        });\n    },\n    [onFileOpen, resolveFileSource],\n  );\n\n  useMountEffect(() => close);\n\n  return React.useMemo(() => ({ close, open, state }), [close, open, state]);\n}\n\nfunction openSourceErrorMessage(error: unknown) {\n  return error instanceof Error && error.message\n    ? error.message\n    : \"Unable to open file.\";\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-open-source-task.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-open-preview-state.ts",
      "content": "\"use client\";\n\nexport {\n  useFileSystemOpenSourceTask as useFileSystemOpenPreviewController,\n  type FileSystemOpenSourceState as FileSystemOpenPreviewState,\n  type FileSystemOpenSourceTask as FileSystemOpenPreviewController,\n} from \"./file-system-open-source-task\";\n",
      "type": "registry:ui",
      "target": "@ui/file-system-open-preview-state.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-open-preview-dialog.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { AlertCircle, ExternalLink, FileQuestion } from \"lucide-react\";\n\nimport type { ViewerSource } from \"@/lib/viewer-source\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Dialog,\n  DialogContent,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ui/dialog\";\nimport { FileViewerPreview } from \"@/components/ui/file-viewer\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\nimport { Spinner } from \"@/components/ui/spinner\";\n\nimport { useFileSystem } from \"./file-system-provider\";\nimport type { FileSystemOpenPreviewState } from \"./file-system-open-preview-state\";\n\nexport function useFileSystemOpenPreview() {\n  return useFileSystem().openPreview;\n}\n\nexport function FileSystemOpenPreview() {\n  const { close, state } = useFileSystemOpenPreview();\n  const file = state.status === \"idle\" ? null : state.file;\n  const source = state.status === \"open\" ? state.source : null;\n\n  return (\n    <Dialog\n      open={state.status !== \"idle\"}\n      onOpenChange={(open) => {\n        if (!open) close();\n      }}\n    >\n      {file ? (\n        <DialogContent className=\"h-[88vh] max-w-[min(96vw,1280px)] overflow-hidden p-0\">\n          <DialogHeader className=\"shrink-0 border-b px-4 py-3\">\n            <div className=\"flex min-w-0 items-center gap-3 pr-8\">\n              <DialogTitle className=\"truncate text-base\">\n                {file.name}\n              </DialogTitle>\n              {source?.kind === \"url\" ? (\n                <Button asChild size=\"xs\" variant=\"outline\">\n                  <a href={source.url} target=\"_blank\" rel=\"noreferrer\">\n                    <ExternalLink className=\"size-3.5\" aria-hidden />\n                    Open\n                  </a>\n                </Button>\n              ) : null}\n            </div>\n          </DialogHeader>\n          <div className=\"min-h-0 flex-1\">\n            <FileSystemOpenPreviewContent state={state} />\n          </div>\n        </DialogContent>\n      ) : null}\n    </Dialog>\n  );\n}\n\nfunction FileSystemOpenPreviewContent({\n  state,\n}: {\n  state: FileSystemOpenPreviewState;\n}) {\n  if (state.status === \"resolving\") {\n    return (\n      <FileSystemOpenPreviewMessage>\n        <Spinner className=\"size-4\" />\n        Opening preview\n      </FileSystemOpenPreviewMessage>\n    );\n  }\n\n  if (state.status === \"unavailable\") {\n    return (\n      <FileSystemOpenPreviewMessage>\n        <FileQuestion className=\"size-5\" aria-hidden />\n        Preview unavailable\n      </FileSystemOpenPreviewMessage>\n    );\n  }\n\n  if (state.status === \"failed\") {\n    return (\n      <FileSystemOpenPreviewMessage>\n        <AlertCircle className=\"size-5\" aria-hidden />\n        {state.error}\n      </FileSystemOpenPreviewMessage>\n    );\n  }\n\n  if (state.status !== \"open\") {\n    return null;\n  }\n\n  return (\n    <ScrollArea>\n      <div className=\"h-[calc(88vh-4rem)] min-h-0\">\n        <FileSystemOpenPreviewViewer source={state.source} />\n      </div>\n    </ScrollArea>\n  );\n}\n\nfunction FileSystemOpenPreviewMessage({\n  children,\n}: {\n  children: React.ReactNode;\n}) {\n  return (\n    <div className=\"text-muted-foreground flex size-full items-center justify-center gap-2 text-sm\">\n      {children}\n    </div>\n  );\n}\n\nfunction FileSystemOpenPreviewViewer({ source }: { source: ViewerSource }) {\n  return <FileViewerPreview source={source} className=\"size-full min-h-0\" />;\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-open-preview-dialog.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/viewer.tsx",
      "content": "\"use client\";\n\nexport { ViewerBody } from \"./viewer-body\";\nexport type { ViewerSidebarTriggerProps } from \"./viewer-chrome\";\nexport {\n  ViewerFrame,\n  ViewerHeader,\n  ViewerSidebarTrigger,\n} from \"./viewer-chrome\";\nexport {\n  ViewerRoot,\n  useOptionalViewerSidebar,\n  useViewerSidebar,\n} from \"./viewer-root\";\nexport { ViewerSidebar } from \"./viewer-sidebar\";\nexport { ViewerSurface, ViewerViewport } from \"./viewer-surface\";\nexport type {\n  ViewerBodyProps,\n  ViewerDataAttributes,\n  ViewerFrameProps,\n  ViewerHeaderProps,\n  ViewerRootProps,\n  ViewerSidebarCollapsible,\n  ViewerSidebarStateValue,\n  ViewerSidebarMode,\n  ViewerSidebarProps,\n  ViewerSidebarRequestedMode,\n  ViewerSidebarSide,\n  ViewerSidebarSlotNames,\n  ViewerSidebarState,\n  ViewerStateAttributeNamespace,\n  ViewerStateAttributeSlot,\n  ViewerStateAttributeValues,\n  ViewerSurfaceProps,\n  ViewerViewportProps,\n} from \"./viewer-types\";\n",
      "type": "registry:ui",
      "target": "@ui/viewer.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-types.ts",
      "content": "import type * as React from \"react\";\n\nimport type { ViewerSource } from \"@/lib/viewer-source\";\n\nexport type FileSystemView = \"list\" | \"grid\" | \"columns\";\n\nexport type FileSystemFolderItem = {\n  kind: \"folder\";\n  path: string;\n  name?: string;\n  parentPath?: string;\n  hasChildren?: boolean;\n  createdAt?: string;\n  updatedAt?: string;\n  metadata?: Record<string, string>;\n};\n\nexport type FileSystemFileItem = {\n  kind: \"file\";\n  path: string;\n  key?: string;\n  name?: string;\n  parentPath?: string;\n  mimeType?: string;\n  size?: number;\n  createdAt?: string;\n  updatedAt?: string;\n  etag?: string;\n  source?: ViewerSource;\n  previewSource?: ViewerSource;\n  previewImageUrl?: string | null;\n  metadata?: Record<string, string>;\n};\n\nexport type FileSystemItem = FileSystemFolderItem | FileSystemFileItem;\n\nexport type FileSystemLoadChildrenArgs = {\n  path: string;\n  cursor: string | null;\n  signal: AbortSignal;\n};\n\nexport type FileSystemLoadChildrenResult = {\n  items: FileSystemItem[];\n  nextCursor?: string | null;\n};\n\nexport type FileSystemResolveSourceArgs = {\n  file: FileSystemFileItem;\n  signal: AbortSignal;\n};\n\nexport type FileSystemSortKey = \"name\" | \"kind\" | \"size\" | \"updatedAt\";\n\nexport type FileSystemSortState = {\n  direction: \"asc\" | \"desc\";\n  key: FileSystemSortKey;\n};\n\nexport type FileSystemQueryState = {\n  search: string;\n  sort: FileSystemSortState;\n};\n\nexport type FileSystemProps = {\n  items: FileSystemItem[];\n  title?: string;\n  className?: string;\n  defaultPath?: string;\n  path?: string;\n  onPathChange?: (path: string) => void;\n  defaultView?: FileSystemView;\n  view?: FileSystemView;\n  onViewChange?: (view: FileSystemView) => void;\n  defaultQuery?: Partial<FileSystemQueryState>;\n  query?: FileSystemQueryState;\n  onQueryChange?: (query: FileSystemQueryState) => void;\n  selectedPath?: string | null;\n  defaultSelectedPath?: string | null;\n  onSelectionChange?: (item: FileSystemItem | null) => void;\n  loadChildren?: (\n    args: FileSystemLoadChildrenArgs,\n  ) => Promise<FileSystemLoadChildrenResult>;\n  resolveSource?: (\n    args: FileSystemResolveSourceArgs,\n  ) => Promise<ViewerSource | null>;\n  onFileOpen?: (file: FileSystemFileItem, source: ViewerSource | null) => void;\n  renderFileActions?: (file: FileSystemFileItem) => React.ReactNode;\n  renderMetadata?: (item: FileSystemItem) => React.ReactNode;\n};\n\nexport type FileSystemFolderEntry = FileSystemFolderItem & {\n  name: string;\n  parentPath: string;\n};\n\nexport type FileSystemFileEntry = FileSystemFileItem & {\n  key: string;\n  name: string;\n  parentPath: string;\n};\n\nexport type FileSystemEntry = FileSystemFolderEntry | FileSystemFileEntry;\n\nexport type FileSystemIndex = {\n  children: Map<string, FileSystemEntry[]>;\n  files: Map<string, FileSystemFileEntry>;\n  folders: Map<string, FileSystemFolderEntry>;\n};\n",
      "type": "registry:ui",
      "target": "@ui/file-system-types.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-index.ts",
      "content": "import type {\n  FileSystemEntry,\n  FileSystemFileEntry,\n  FileSystemFolderEntry,\n  FileSystemIndex,\n  FileSystemItem,\n} from \"./file-system-types\";\n\nexport function normalizeFolderPath(path: string | undefined | null): string {\n  if (!path || path === \"/\") return \"\";\n  const trimmed = path.replace(/^\\/+/, \"\");\n  return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\n}\n\nexport function normalizeFilePath(path: string): string {\n  return path.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n}\n\nexport function pathName(path: string): string {\n  const trimmed = path.endsWith(\"/\") ? path.slice(0, -1) : path;\n  const separatorIndex = trimmed.lastIndexOf(\"/\");\n  return separatorIndex === -1 ? trimmed : trimmed.slice(separatorIndex + 1);\n}\n\nexport function pathParent(path: string): string {\n  const trimmed = path.endsWith(\"/\") ? path.slice(0, -1) : path;\n  const separatorIndex = trimmed.lastIndexOf(\"/\");\n  return separatorIndex === -1 ? \"\" : `${trimmed.slice(0, separatorIndex)}/`;\n}\n\nexport function buildFileSystemIndex(items: readonly FileSystemItem[]) {\n  const folders = new Map<string, FileSystemFolderEntry>();\n  const files = new Map<string, FileSystemFileEntry>();\n\n  const ensureFolderChain = (folderPath: string) => {\n    let path = normalizeFolderPath(folderPath);\n\n    while (path && !folders.has(path)) {\n      folders.set(path, {\n        kind: \"folder\",\n        name: pathName(path),\n        parentPath: pathParent(path),\n        path,\n      });\n      path = pathParent(path);\n    }\n  };\n\n  for (const item of items) {\n    if (item.kind === \"folder\") {\n      const path = normalizeFolderPath(item.path);\n      if (!path) continue;\n\n      folders.set(path, {\n        ...item,\n        name: item.name ?? pathName(path),\n        parentPath: normalizeFolderPath(item.parentPath ?? pathParent(path)),\n        path,\n      });\n      ensureFolderChain(pathParent(path));\n      continue;\n    }\n\n    const path = normalizeFilePath(item.path);\n    if (!path) continue;\n\n    files.set(path, {\n      ...item,\n      key: item.key ?? path,\n      name: item.name ?? pathName(path),\n      parentPath: normalizeFolderPath(item.parentPath ?? pathParent(path)),\n      path,\n    });\n    ensureFolderChain(pathParent(path));\n  }\n\n  const children = new Map<string, FileSystemEntry[]>();\n  const pushChild = (entry: FileSystemEntry) => {\n    const siblings = children.get(entry.parentPath);\n\n    if (siblings) {\n      siblings.push(entry);\n    } else {\n      children.set(entry.parentPath, [entry]);\n    }\n  };\n\n  for (const folder of folders.values()) pushChild(folder);\n  for (const file of files.values()) pushChild(file);\n  for (const siblings of children.values()) siblings.sort(compareEntryNames);\n\n  deriveFolderModifiedDates({ children, files, folders });\n\n  return { children, files, folders } satisfies FileSystemIndex;\n}\n\nexport function compareEntryNames(\n  left: Pick<FileSystemEntry, \"kind\" | \"name\">,\n  right: Pick<FileSystemEntry, \"kind\" | \"name\">,\n) {\n  if (left.kind !== right.kind) return left.kind === \"folder\" ? -1 : 1;\n  return left.name.localeCompare(right.name, undefined, {\n    numeric: true,\n    sensitivity: \"base\",\n  });\n}\n\nexport function folderHasChildren(\n  index: FileSystemIndex,\n  folder: FileSystemFolderEntry,\n) {\n  return (\n    folder.hasChildren === true ||\n    (index.children.get(folder.path)?.length ?? 0) > 0\n  );\n}\n\nfunction deriveFolderModifiedDates(index: FileSystemIndex) {\n  const foldersDeepestFirst = [...index.folders.values()].sort(\n    (left, right) => right.path.length - left.path.length,\n  );\n\n  for (const folder of foldersDeepestFirst) {\n    if (folder.updatedAt) continue;\n\n    let newestTime = Number.NEGATIVE_INFINITY;\n    let newestValue: string | undefined;\n\n    for (const child of index.children.get(folder.path) ?? []) {\n      const value = child.updatedAt ?? child.createdAt;\n      const time = value ? Date.parse(value) : Number.NaN;\n\n      if (!Number.isNaN(time) && time > newestTime) {\n        newestTime = time;\n        newestValue = value;\n      }\n    }\n\n    if (newestValue) folder.updatedAt = newestValue;\n  }\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-index.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-query.ts",
      "content": "import { detectCategory } from \"@/lib/viewer-source\";\n\nimport { compareEntryNames } from \"./file-system-index\";\nimport type {\n  FileSystemEntry,\n  FileSystemFileEntry,\n  FileSystemIndex,\n  FileSystemQueryState,\n  FileSystemSortState,\n} from \"./file-system-types\";\n\nexport const DEFAULT_FILE_SYSTEM_SORT: FileSystemSortState = {\n  direction: \"asc\",\n  key: \"name\",\n};\n\nexport const DEFAULT_FILE_SYSTEM_QUERY: FileSystemQueryState = {\n  search: \"\",\n  sort: DEFAULT_FILE_SYSTEM_SORT,\n};\n\nexport function createFileSystemQueryState(\n  query: Partial<FileSystemQueryState> | undefined,\n): FileSystemQueryState {\n  return {\n    search: query?.search ?? \"\",\n    sort: {\n      direction: query?.sort?.direction ?? DEFAULT_FILE_SYSTEM_SORT.direction,\n      key: query?.sort?.key ?? DEFAULT_FILE_SYSTEM_SORT.key,\n    },\n  };\n}\n\nexport function normalizeFileSystemSearch(value: string): string {\n  return value.trim().toLowerCase();\n}\n\nexport function getFileSystemCategory(file: FileSystemFileEntry) {\n  return detectCategory(file.name, file.mimeType);\n}\n\nexport function getFileSystemCategoryLabel(category: string) {\n  switch (category) {\n    case \"csv\":\n      return \"CSV\";\n    case \"docx\":\n      return \"Word\";\n    case \"html\":\n      return \"HTML\";\n    case \"image\":\n      return \"Image\";\n    case \"markdown\":\n      return \"Markdown\";\n    case \"pdf\":\n      return \"PDF\";\n    case \"pptx\":\n      return \"PowerPoint\";\n    case \"text\":\n      return \"Text\";\n    case \"xlsx\":\n      return \"Excel\";\n    default:\n      return \"Unsupported\";\n  }\n}\n\nexport function fileMatchesQuery(\n  file: FileSystemFileEntry,\n  query: FileSystemQueryState,\n) {\n  const search = normalizeFileSystemSearch(query.search);\n  if (\n    search &&\n    !file.path.toLowerCase().includes(search) &&\n    !file.name.toLowerCase().includes(search)\n  ) {\n    return false;\n  }\n\n  return true;\n}\n\nexport function deriveVisibleIndex(\n  index: FileSystemIndex,\n  currentPath: string,\n  query: FileSystemQueryState,\n): FileSystemIndex {\n  const search = normalizeFileSystemSearch(query.search);\n\n  if (!search) return sortFileSystemIndex(index, query.sort);\n\n  const visiblePaths = new Set<string>();\n  const markVisible = (path: string) => {\n    let nextPath = path;\n\n    while (\n      nextPath &&\n      nextPath !== currentPath &&\n      !visiblePaths.has(nextPath)\n    ) {\n      visiblePaths.add(nextPath);\n      const trimmed = nextPath.endsWith(\"/\") ? nextPath.slice(0, -1) : nextPath;\n      const separatorIndex = trimmed.lastIndexOf(\"/\");\n\n      nextPath =\n        separatorIndex === -1 ? \"\" : `${trimmed.slice(0, separatorIndex)}/`;\n    }\n  };\n\n  for (const [path, file] of index.files) {\n    if (currentPath && !path.startsWith(currentPath)) continue;\n    if (!fileMatchesQuery(file, query)) continue;\n    visiblePaths.add(path);\n    markVisible(file.parentPath);\n  }\n\n  for (const [path, folder] of index.folders) {\n    if (currentPath && !path.startsWith(currentPath)) continue;\n    if (\n      !path.toLowerCase().includes(search) &&\n      !folder.name.toLowerCase().includes(search)\n    ) {\n      continue;\n    }\n    visiblePaths.add(path);\n    markVisible(folder.parentPath);\n  }\n\n  const children = new Map<string, FileSystemEntry[]>();\n\n  for (const [parentPath, entries] of index.children) {\n    const visibleEntries = entries.filter((entry) =>\n      visiblePaths.has(entry.path),\n    );\n    if (visibleEntries.length) children.set(parentPath, visibleEntries);\n  }\n\n  return sortFileSystemIndex({ ...index, children }, query.sort);\n}\n\nexport function sortFileSystemIndex(\n  index: FileSystemIndex,\n  sort: FileSystemSortState,\n) {\n  if (\n    sort.key === DEFAULT_FILE_SYSTEM_SORT.key &&\n    sort.direction === DEFAULT_FILE_SYSTEM_SORT.direction\n  ) {\n    return index;\n  }\n\n  const children = new Map<string, FileSystemEntry[]>();\n\n  for (const [parentPath, entries] of index.children) {\n    children.set(\n      parentPath,\n      [...entries].sort((left, right) => compareEntries(left, right, sort)),\n    );\n  }\n\n  return { ...index, children } satisfies FileSystemIndex;\n}\n\nexport function compareEntries(\n  left: FileSystemEntry,\n  right: FileSystemEntry,\n  sort: FileSystemSortState,\n) {\n  if (left.kind !== right.kind) return left.kind === \"folder\" ? -1 : 1;\n\n  let result = 0;\n\n  switch (sort.key) {\n    case \"kind\":\n      result = entryKindLabel(left).localeCompare(entryKindLabel(right));\n      break;\n    case \"size\":\n      result = (entrySize(left) ?? -1) - (entrySize(right) ?? -1);\n      break;\n    case \"updatedAt\":\n      result = entryTime(left) - entryTime(right);\n      break;\n    case \"name\":\n      result = compareEntryNames(left, right);\n      break;\n  }\n\n  if (result === 0) result = compareEntryNames(left, right);\n  return sort.direction === \"asc\" ? result : -result;\n}\n\nexport function entryKindLabel(entry: FileSystemEntry) {\n  return entry.kind === \"folder\"\n    ? \"Folder\"\n    : getFileSystemCategoryLabel(getFileSystemCategory(entry));\n}\n\nfunction entrySize(entry: FileSystemEntry) {\n  return entry.kind === \"file\" ? entry.size : undefined;\n}\n\nfunction entryTime(entry: FileSystemEntry) {\n  const time = Date.parse(entry.updatedAt ?? entry.createdAt ?? \"\");\n  return Number.isNaN(time) ? Number.NEGATIVE_INFINITY : time;\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-query.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-source-controller.ts",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport type { ViewerSource } from \"@/lib/viewer-source\";\n\nimport type { FileSystemFileEntry, FileSystemProps } from \"./file-system-types\";\n\nexport type FileSystemSourceController = {\n  resolveFileSource: (\n    file: FileSystemFileEntry,\n    signal: AbortSignal,\n  ) => Promise<ViewerSource | null>;\n};\n\nexport function useFileSystemSourceController({\n  items,\n  resolveSource,\n}: Pick<\n  FileSystemProps,\n  \"items\" | \"resolveSource\"\n>): FileSystemSourceController {\n  const sourceCache = React.useRef(new Map<string, ViewerSource | null>());\n  const pendingSourceCache = React.useRef(\n    new Map<string, Promise<ViewerSource | null>>(),\n  );\n  const sourceCacheItemsRef = React.useRef(items);\n\n  if (sourceCacheItemsRef.current !== items) {\n    sourceCache.current.clear();\n    pendingSourceCache.current.clear();\n    sourceCacheItemsRef.current = items;\n  }\n\n  const resolveFileSource = React.useCallback(\n    async (file: FileSystemFileEntry, signal: AbortSignal) => {\n      if (file.source) return file.source;\n\n      const cacheKey = sourceCacheKey(file);\n\n      if (sourceCache.current.has(cacheKey)) {\n        return sourceCache.current.get(cacheKey) ?? null;\n      }\n      const pendingSource = pendingSourceCache.current.get(cacheKey);\n      if (pendingSource) return pendingSource;\n      if (!resolveSource) return null;\n\n      const sourcePromise = resolveSource({ file, signal }).then(\n        (source) => {\n          pendingSourceCache.current.delete(cacheKey);\n          if (!signal.aborted) sourceCache.current.set(cacheKey, source);\n          return source;\n        },\n        (error: unknown) => {\n          pendingSourceCache.current.delete(cacheKey);\n          throw error;\n        },\n      );\n\n      pendingSourceCache.current.set(cacheKey, sourcePromise);\n      signal.addEventListener(\n        \"abort\",\n        () => {\n          pendingSourceCache.current.delete(cacheKey);\n        },\n        { once: true },\n      );\n      return sourcePromise;\n    },\n    [resolveSource],\n  );\n\n  return { resolveFileSource };\n}\n\nfunction sourceCacheKey(file: FileSystemFileEntry) {\n  return [file.path, file.key, file.etag ?? \"\", file.updatedAt ?? \"\"].join(\n    \"\\0\",\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-source-controller.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-controls.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport {\n  ArrowLeft,\n  ArrowRight,\n  Columns3,\n  Grid3X3,\n  List,\n  Search,\n} from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n  Breadcrumb,\n  BreadcrumbItem,\n  BreadcrumbList,\n  BreadcrumbPage,\n  BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Tabs, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\n\nimport type {\n  FileSystemBrowserState,\n  FileSystemHeaderState,\n} from \"./file-system-browser-state\";\nimport { normalizeFileSystemSearch } from \"./file-system-query\";\nimport type { FileSystemSortKey, FileSystemView } from \"./file-system-types\";\nimport { ViewerSidebarTrigger } from \"./viewer\";\n\nconst VIEW_OPTIONS: Array<{\n  icon: React.ComponentType<{ className?: string }>;\n  label: string;\n  value: FileSystemView;\n}> = [\n  { icon: List, label: \"List\", value: \"list\" },\n  { icon: Grid3X3, label: \"Grid\", value: \"grid\" },\n  { icon: Columns3, label: \"Columns\", value: \"columns\" },\n];\n\nconst SORT_OPTIONS: Array<{\n  label: string;\n  value: FileSystemSortKey;\n}> = [\n  { label: \"Name\", value: \"name\" },\n  { label: \"Type\", value: \"kind\" },\n  { label: \"Size\", value: \"size\" },\n  { label: \"Modified\", value: \"updatedAt\" },\n];\n\nexport function FileSystemToolbar({\n  canGoBack,\n  canGoForward,\n  currentPath,\n  goBack,\n  goForward,\n  query,\n  setSearch,\n  setView,\n  title,\n  view,\n}: {\n  canGoBack: FileSystemHeaderState[\"canGoBack\"];\n  canGoForward: FileSystemHeaderState[\"canGoForward\"];\n  currentPath: FileSystemHeaderState[\"currentPath\"];\n  goBack: FileSystemHeaderState[\"goBack\"];\n  goForward: FileSystemHeaderState[\"goForward\"];\n  query: FileSystemHeaderState[\"query\"];\n  setSearch: FileSystemHeaderState[\"setSearch\"];\n  setView: FileSystemHeaderState[\"setView\"];\n  title: FileSystemHeaderState[\"title\"];\n  view: FileSystemHeaderState[\"view\"];\n}) {\n  const currentPathSegments = React.useMemo(\n    () => getFileSystemBreadcrumbSegments(currentPath, title),\n    [currentPath, title],\n  );\n\n  return (\n    <div className=\"bg-muted/35 flex h-12 shrink-0 items-center gap-2 border-b px-2\">\n      <div className=\"flex min-w-0 flex-1 items-center gap-1\">\n        <ViewerSidebarTrigger />\n        <Button\n          aria-label=\"Back\"\n          disabled={!canGoBack}\n          onClick={goBack}\n          size=\"iconSm\"\n          variant=\"ghost\"\n        >\n          <ArrowLeft className=\"size-4\" aria-hidden />\n        </Button>\n        <Button\n          aria-label=\"Forward\"\n          disabled={!canGoForward}\n          onClick={goForward}\n          size=\"iconSm\"\n          variant=\"ghost\"\n        >\n          <ArrowRight className=\"size-4\" aria-hidden />\n        </Button>\n        <Breadcrumb className=\"min-w-0 px-1\">\n          <BreadcrumbList className=\"min-w-0 flex-nowrap gap-1 overflow-hidden text-sm sm:gap-1.5\">\n            {currentPathSegments.map((segment, index) => {\n              const isLast = index === currentPathSegments.length - 1;\n\n              return (\n                <React.Fragment key={`${segment}-${index}`}>\n                  <BreadcrumbItem\n                    className={cn(\"min-w-0\", !isLast && \"shrink-0\")}\n                  >\n                    {isLast ? (\n                      <BreadcrumbPage className=\"truncate\">\n                        {segment}\n                      </BreadcrumbPage>\n                    ) : (\n                      <span className=\"text-muted-foreground\">{segment}</span>\n                    )}\n                  </BreadcrumbItem>\n                  {!isLast ? <BreadcrumbSeparator /> : null}\n                </React.Fragment>\n              );\n            })}\n          </BreadcrumbList>\n        </Breadcrumb>\n      </div>\n      <FileSystemViewTabs view={view} setView={setView} />\n      <div className=\"relative w-52 min-w-0 max-sm:w-36\">\n        <Search\n          className=\"text-muted-foreground pointer-events-none absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\"\n          aria-hidden\n        />\n        <Input\n          aria-label=\"Search files\"\n          className=\"[&_input]:pl-7\"\n          nativeInput\n          onChange={(event) => setSearch(event.target.value)}\n          placeholder=\"Search\"\n          size=\"sm\"\n          type=\"search\"\n          value={query.search}\n        />\n      </div>\n    </div>\n  );\n}\n\nfunction getFileSystemBreadcrumbSegments(currentPath: string, title: string) {\n  const segments = currentPath.split(\"/\").filter(Boolean);\n\n  return segments.length > 0 ? segments : [title];\n}\n\nfunction FileSystemViewTabs({\n  setView,\n  view,\n}: {\n  setView: FileSystemHeaderState[\"setView\"];\n  view: FileSystemHeaderState[\"view\"];\n}) {\n  return (\n    <Tabs\n      value={view}\n      onValueChange={(nextView) => setView(nextView as FileSystemView)}\n      className=\"hidden md:block\"\n      data-slot=\"file-system-view-tabs\"\n    >\n      <TabsList className=\"bg-muted/80 text-muted-foreground relative z-0 grid h-8 grid-cols-3 items-center gap-0.5 rounded-md p-0.5\">\n        {VIEW_OPTIONS.map((option) => (\n          <TabsTrigger\n            key={option.value}\n            value={option.value}\n            aria-label={`${option.label} view`}\n            title={`${option.label} view`}\n            className=\"hover:text-foreground focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:ring-border/40 flex size-7 cursor-pointer items-center justify-center rounded-sm transition-colors outline-none focus-visible:ring-2 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[state=active]:shadow-xs data-[state=active]:ring-1 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0\"\n          >\n            <option.icon aria-hidden />\n          </TabsTrigger>\n        ))}\n      </TabsList>\n    </Tabs>\n  );\n}\n\nexport function FileSystemCommandBar({\n  controller,\n}: {\n  controller: FileSystemHeaderState;\n}) {\n  return (\n    <div className=\"flex shrink-0 items-center gap-1 overflow-x-auto border-b px-2 py-1.5\">\n      <FileSystemSortControls controller={controller} />\n    </div>\n  );\n}\n\nexport function FileSystemSortControls({\n  controller,\n}: {\n  controller: FileSystemHeaderState;\n}) {\n  return (\n    <>\n      {SORT_OPTIONS.map((option) => {\n        const isActive = controller.query.sort.key === option.value;\n\n        return (\n          <button\n            key={option.value}\n            type=\"button\"\n            aria-label={option.label}\n            onClick={() => controller.setSortKey(option.value)}\n            className={cn(\n              \"hover:bg-accent focus-visible:ring-ring flex h-6 shrink-0 items-center gap-1 rounded-sm border px-2 text-xs outline-none focus-visible:ring-2\",\n              isActive\n                ? \"border-primary bg-primary text-primary-foreground\"\n                : \"border-input bg-background text-muted-foreground\",\n            )}\n          >\n            <span>{option.label}</span>\n            {isActive ? (\n              <span aria-hidden>\n                {controller.query.sort.direction === \"asc\" ? \"↑\" : \"↓\"}\n              </span>\n            ) : null}\n          </button>\n        );\n      })}\n    </>\n  );\n}\n\nexport function FileSystemStatusBar({\n  browser,\n}: {\n  browser: FileSystemBrowserState;\n}) {\n  const itemCount = browser.entries.length;\n  const isSearching =\n    normalizeFileSystemSearch(browser.query.search).length > 0;\n  const selectedEntry = browser.selectedEntry;\n\n  return (\n    <div\n      aria-live=\"polite\"\n      className=\"bg-muted/35 text-muted-foreground flex h-8 shrink-0 items-center justify-between gap-3 border-t px-3 text-xs\"\n    >\n      <span>\n        {itemCount}{\" \"}\n        {isSearching\n          ? itemCount === 1\n            ? \"result\"\n            : \"results\"\n          : itemCount === 1\n            ? \"item\"\n            : \"items\"}\n      </span>\n      {selectedEntry ? (\n        <span className=\"min-w-0 truncate\">{selectedEntry.name} selected</span>\n      ) : null}\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-controls.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-navigation.ts",
      "content": "import type * as React from \"react\";\n\nexport type FileSystemNavigationEntry = {\n  name: string;\n  path: string;\n};\n\nexport function fileSystemEntryAtOffset<\n  Entry extends FileSystemNavigationEntry,\n>(entries: readonly Entry[], selectedPath: string | null, offset: number) {\n  const currentIndex = entries.findIndex(\n    (entry) => entry.path === selectedPath,\n  );\n  const nextIndex = Math.min(\n    entries.length - 1,\n    Math.max(0, currentIndex === -1 ? 0 : currentIndex + offset),\n  );\n\n  return entries[nextIndex] ?? null;\n}\n\nexport function fileSystemBoundaryEntry<\n  Entry extends FileSystemNavigationEntry,\n>(entries: readonly Entry[], boundary: \"first\" | \"last\") {\n  return boundary === \"first\"\n    ? (entries[0] ?? null)\n    : (entries[entries.length - 1] ?? null);\n}\n\nexport function fileSystemTypeAheadMatch<\n  Entry extends FileSystemNavigationEntry,\n>(\n  event: React.KeyboardEvent,\n  entries: readonly Entry[],\n  selectedPath: string | null,\n) {\n  if (\n    event.key.length !== 1 ||\n    event.altKey ||\n    event.ctrlKey ||\n    event.metaKey ||\n    !/^[\\p{L}\\p{N}]$/u.test(event.key)\n  ) {\n    return null;\n  }\n\n  const search = event.key.toLowerCase();\n  const startIndex = Math.max(\n    0,\n    entries.findIndex((entry) => entry.path === selectedPath) + 1,\n  );\n\n  for (let step = 0; step < entries.length; step += 1) {\n    const entry = entries[(startIndex + step) % entries.length];\n\n    if (entry.name.toLowerCase().startsWith(search)) {\n      event.preventDefault();\n      return entry;\n    }\n  }\n\n  return null;\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-navigation.ts"
    },
    {
      "path": "registry/new-york-v4/ui/use-file-system-roving-focus.ts",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport {\n  fileSystemBoundaryEntry,\n  fileSystemEntryAtOffset,\n  fileSystemTypeAheadMatch,\n  type FileSystemNavigationEntry,\n} from \"./file-system-navigation\";\n\nexport function useFileSystemRovingFocus<\n  Entry extends FileSystemNavigationEntry,\n>({\n  entries,\n  getScrollIndex,\n  onSelect,\n  scrollToIndex,\n  selectedPath,\n}: {\n  entries: readonly Entry[];\n  selectedPath: string | null;\n  onSelect: (entry: Entry) => void;\n  getScrollIndex?: (entry: Entry) => number;\n  scrollToIndex?: (index: number) => void;\n}) {\n  const entryElements = React.useRef(new Map<string, HTMLElement>());\n\n  const registerEntryRef = React.useCallback(\n    (path: string, element: HTMLElement | null) => {\n      if (element) {\n        entryElements.current.set(path, element);\n      } else {\n        entryElements.current.delete(path);\n      }\n    },\n    [],\n  );\n\n  const focusEntry = React.useCallback(\n    (entry: Entry) => {\n      const index = getScrollIndex?.(entry);\n\n      if (index !== undefined) scrollToIndex?.(index);\n\n      requestAnimationFrame(() => {\n        entryElements.current.get(entry.path)?.focus();\n      });\n    },\n    [getScrollIndex, scrollToIndex],\n  );\n\n  const selectEntry = React.useCallback(\n    (entry: Entry | null) => {\n      if (!entry) return;\n      onSelect(entry);\n      focusEntry(entry);\n    },\n    [focusEntry, onSelect],\n  );\n\n  const selectByOffset = React.useCallback(\n    (offset: number) => {\n      selectEntry(fileSystemEntryAtOffset(entries, selectedPath, offset));\n    },\n    [entries, selectEntry, selectedPath],\n  );\n\n  const selectBoundary = React.useCallback(\n    (boundary: \"first\" | \"last\") => {\n      selectEntry(fileSystemBoundaryEntry(entries, boundary));\n    },\n    [entries, selectEntry],\n  );\n\n  const selectTypeAhead = React.useCallback(\n    (event: React.KeyboardEvent, path: string | null = selectedPath) => {\n      selectEntry(fileSystemTypeAheadMatch(event, entries, path));\n    },\n    [entries, selectEntry, selectedPath],\n  );\n\n  return {\n    focusEntry,\n    registerEntryRef,\n    selectBoundary,\n    selectByOffset,\n    selectEntry,\n    selectTypeAhead,\n  };\n}\n",
      "type": "registry:ui",
      "target": "@ui/use-file-system-roving-focus.ts"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-thumbnail.tsx",
      "content": "\"use client\";\n\nimport { FileThumbnail } from \"@/components/ui/file-thumbnail\";\n\nimport {\n  useFileSystemSelectionSourceTask,\n  type FileSystemSourceResolver,\n} from \"./file-system-selection-source-task\";\nimport type { FileSystemFileEntry } from \"./file-system-types\";\n\nexport function FileSystemThumbnail({\n  file,\n  className,\n  presentation,\n  resolveFileSource,\n}: {\n  file: FileSystemFileEntry;\n  className?: string;\n  presentation?: \"document\" | \"decorative\";\n  resolveFileSource?: FileSystemSourceResolver;\n}) {\n  const sourceState = useFileSystemSelectionSourceTask(\n    file.previewImageUrl ? null : file,\n    resolveFileSource,\n  );\n  const source = file.previewSource ?? file.source ?? sourceState.source;\n\n  if (file.previewImageUrl) {\n    return (\n      <FileThumbnail\n        file={{ name: file.name, type: file.mimeType ?? \"\" }}\n        presentation={presentation}\n        previewAspectRatio={1}\n        previewImageUrl={file.previewImageUrl}\n        className={className}\n      />\n    );\n  }\n\n  if (source) {\n    return (\n      <FileThumbnail\n        source={source}\n        presentation={presentation}\n        previewAspectRatio={1}\n        className={className}\n      />\n    );\n  }\n\n  return (\n    <FileThumbnail\n      file={{ name: file.name, type: file.mimeType ?? \"\" }}\n      presentation={presentation}\n      previewAspectRatio={1}\n      className={className}\n      state={sourceState.status === \"loading\" ? \"loading\" : undefined}\n    />\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-thumbnail.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-list-view.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport {\n  createFileTreeIconResolver,\n  getBuiltInSpriteSheet,\n} from \"@pierre/trees\";\nimport { AlertCircle, ChevronDown, ChevronRight, Folder } from \"lucide-react\";\nimport { useKeyedMountEffect } from \"@/hooks/use-keyed-mount-effect\";\nimport { useMountEffect } from \"@/hooks/use-mount-effect\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\n\nimport type { FileSystemBrowserController } from \"./file-system-browser-controller\";\nimport { entryKindLabel } from \"./file-system-query\";\nimport { FileSystemThumbnail } from \"./file-system-thumbnail\";\nimport type { FileSystemEntry, FileSystemFileEntry } from \"./file-system-types\";\nimport {\n  formatFileSystemDate,\n  formatFileSystemSize,\n} from \"./file-system-utils\";\nimport { useFixedRowVirtualization } from \"./fixed-grid-virtualization\";\n\ntype FileSystemListRow =\n  | {\n      depth: number;\n      entry: FileSystemEntry;\n      id: string;\n      isExpanded: boolean;\n      kind: \"entry\";\n    }\n  | {\n      depth: number;\n      folder: FileSystemEntry;\n      id: string;\n      kind: \"loading\";\n    }\n  | {\n      depth: number;\n      error: string;\n      folder: FileSystemEntry;\n      id: string;\n      kind: \"error\";\n    };\n\nconst LIST_ROW_HEIGHT = 34;\nconst LIST_COLUMNS =\n  \"grid-cols-[minmax(13rem,1fr)_minmax(7rem,9rem)_minmax(5rem,7rem)_minmax(8rem,11rem)]\";\nconst PIERRE_ICON_SPRITE_ROOT_ID = \"file-system-pierre-icon-sprite-root\";\nconst PIERRE_FILE_ICON_RESOLVER = createFileTreeIconResolver({\n  colored: false,\n  set: \"complete\",\n});\n\nexport function FileSystemListView({\n  controller,\n}: {\n  controller: FileSystemBrowserController;\n}) {\n  const { browser, fileActions } = controller;\n  const [expandedPaths, setExpandedPaths] = React.useState<ReadonlySet<string>>(\n    () => new Set(),\n  );\n  const [focusedPath, setFocusedPath] = React.useState<string | null>(\n    browser.selectedPath,\n  );\n  const parentRef = React.useRef<HTMLDivElement | null>(null);\n  // Track the scroll element in state (not just the ref) so virtualization\n  // re-measures when the tree remounts, e.g. after navigating through a\n  // transient empty/loading state. A plain ref mutation never re-renders, so\n  // a ref-only wiring leaves the row window stuck at zero rendered rows.\n  const [parentElement, setParentElement] =\n    React.useState<HTMLDivElement | null>(null);\n  const setParentRef = React.useCallback((node: HTMLDivElement | null) => {\n    parentRef.current = node;\n    setParentElement((current) => (current === node ? current : node));\n  }, []);\n  const rows = React.useMemo(\n    () =>\n      createFileSystemListRows({\n        currentPath: browser.currentPath,\n        expandedPaths,\n        folderErrors: browser.folderErrors,\n        index: browser.index,\n        isSearching: browser.query.search.trim().length > 0,\n        loadingFolders: browser.loadingFolders,\n      }),\n    [\n      browser.currentPath,\n      browser.folderErrors,\n      browser.index,\n      browser.loadingFolders,\n      browser.query.search,\n      expandedPaths,\n    ],\n  );\n  const { virtualRows, totalRowSize } = useFixedRowVirtualization({\n    rowCount: rows.length,\n    rowSize: LIST_ROW_HEIGHT,\n    rowOverscan: 12,\n    initialViewportHeight: 560,\n    scrollRef: parentRef,\n    scrollElement: parentElement,\n  });\n  const entryRows = React.useMemo(\n    () =>\n      rows.filter(\n        (row): row is Extract<FileSystemListRow, { kind: \"entry\" }> =>\n          row.kind === \"entry\",\n      ),\n    [rows],\n  );\n  const focusedIndex = entryRows.findIndex(\n    (row) => row.entry.path === (focusedPath ?? browser.selectedPath),\n  );\n\n  useKeyedMountEffect(`selected:${browser.selectedPath ?? \"null\"}`, () => {\n    setFocusedPath(browser.selectedPath);\n  });\n\n  const toggleFolder = React.useCallback(\n    (entry: FileSystemEntry, options?: { retry?: boolean }) => {\n      if (entry.kind !== \"folder\") return;\n\n      if (expandedPaths.has(entry.path) && !options?.retry) {\n        setExpandedPaths((current) => {\n          const next = new Set(current);\n          next.delete(entry.path);\n          return next;\n        });\n        return;\n      }\n\n      setExpandedPaths((current) => new Set(current).add(entry.path));\n      void browser.ensureChildren(entry.path, options).catch(() => {});\n    },\n    [browser, expandedPaths],\n  );\n  const selectEntry = React.useCallback(\n    (entry: FileSystemEntry) => {\n      setFocusedPath(entry.path);\n      browser.selectEntry(entry);\n    },\n    [browser],\n  );\n  const openEntry = React.useCallback(\n    (entry: FileSystemEntry) => {\n      selectEntry(entry);\n\n      if (entry.kind === \"folder\") {\n        browser.navigateTo(entry.path);\n        return;\n      }\n\n      fileActions.openPreview(entry);\n    },\n    [browser, fileActions, selectEntry],\n  );\n  const focusEntryAt = React.useCallback(\n    (index: number) => {\n      const row = entryRows[Math.max(0, Math.min(index, entryRows.length - 1))];\n      if (!row) return;\n\n      selectEntry(row.entry);\n    },\n    [entryRows, selectEntry],\n  );\n  const handleKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\n      if (!entryRows.length) return;\n\n      const currentIndex = focusedIndex >= 0 ? focusedIndex : 0;\n      const current = entryRows[currentIndex]?.entry;\n\n      if (event.key === \"ArrowDown\") {\n        focusEntryAt(currentIndex + 1);\n        event.preventDefault();\n        return;\n      }\n      if (event.key === \"ArrowUp\") {\n        focusEntryAt(currentIndex - 1);\n        event.preventDefault();\n        return;\n      }\n      if (event.key === \"Enter\" && current) {\n        openEntry(current);\n        event.preventDefault();\n        return;\n      }\n      if (event.key === \"ArrowRight\" && current?.kind === \"folder\") {\n        if (!expandedPaths.has(current.path)) {\n          toggleFolder(current);\n        } else {\n          browser.navigateTo(current.path);\n        }\n        event.preventDefault();\n        return;\n      }\n      if (event.key === \"ArrowLeft\" && current?.kind === \"folder\") {\n        if (expandedPaths.has(current.path)) {\n          toggleFolder(current);\n          event.preventDefault();\n        }\n      }\n    },\n    [\n      browser,\n      entryRows,\n      expandedPaths,\n      focusEntryAt,\n      focusedIndex,\n      openEntry,\n      toggleFolder,\n    ],\n  );\n\n  if (!browser.entries.length) {\n    return <FileSystemEmptyRows label=\"This folder is empty\" />;\n  }\n\n  return (\n    <div\n      className=\"bg-background flex size-full min-h-0 flex-col\"\n      data-slot=\"file-system-list-view\"\n    >\n      <PierreFileIconSprite />\n      <div\n        className={cn(\n          \"bg-muted/35 text-muted-foreground grid h-9 shrink-0 items-center border-b px-3 text-xs font-medium\",\n          LIST_COLUMNS,\n        )}\n      >\n        <div>Name</div>\n        <div>Type</div>\n        <div className=\"text-right\">Size</div>\n        <div>Modified</div>\n      </div>\n      <div\n        ref={setParentRef}\n        role=\"tree\"\n        aria-label=\"Files\"\n        tabIndex={0}\n        onKeyDown={handleKeyDown}\n        className=\"min-h-0 flex-1 overflow-auto outline-none\"\n      >\n        <div\n          className=\"relative min-w-[42rem]\"\n          style={{ height: totalRowSize }}\n        >\n          {virtualRows.map((virtualRow) => {\n            const row = rows[virtualRow.index];\n            if (!row) return null;\n\n            return (\n              <div\n                key={row.id}\n                className=\"absolute inset-x-0 top-0\"\n                style={{\n                  height: virtualRow.size,\n                  transform: `translateY(${virtualRow.start}px)`,\n                }}\n              >\n                {row.kind === \"entry\" ? (\n                  <FileSystemListEntryRow\n                    depth={row.depth}\n                    entry={row.entry}\n                    hasError={browser.folderErrors.has(row.entry.path)}\n                    isExpanded={row.isExpanded}\n                    isFocused={row.entry.path === focusedPath}\n                    isSelected={row.entry.path === browser.selectedPath}\n                    onOpen={openEntry}\n                    onSelect={selectEntry}\n                    onToggle={toggleFolder}\n                  />\n                ) : row.kind === \"loading\" ? (\n                  <FileSystemListMessageRow depth={row.depth} label=\"Loading\" />\n                ) : (\n                  <FileSystemListErrorRow\n                    depth={row.depth}\n                    error={row.error}\n                    folder={row.folder}\n                    onRetry={toggleFolder}\n                  />\n                )}\n              </div>\n            );\n          })}\n        </div>\n      </div>\n    </div>\n  );\n}\n\nfunction FileSystemListEntryRow({\n  depth,\n  entry,\n  hasError,\n  isExpanded,\n  isFocused,\n  isSelected,\n  onOpen,\n  onSelect,\n  onToggle,\n}: {\n  depth: number;\n  entry: FileSystemEntry;\n  hasError: boolean;\n  isExpanded: boolean;\n  isFocused: boolean;\n  isSelected: boolean;\n  onOpen: (entry: FileSystemEntry) => void;\n  onSelect: (entry: FileSystemEntry) => void;\n  onToggle: (entry: FileSystemEntry, options?: { retry?: boolean }) => void;\n}) {\n  return (\n    <div\n      role=\"treeitem\"\n      aria-expanded={entry.kind === \"folder\" ? isExpanded : undefined}\n      aria-label={entry.name}\n      aria-level={depth + 1}\n      aria-selected={isSelected}\n      data-path={entry.path}\n      onClick={() => {\n        onSelect(entry);\n        if (entry.kind !== \"folder\") return;\n        if (hasError) {\n          onToggle(entry, { retry: true });\n          return;\n        }\n        if (!isExpanded) onToggle(entry);\n      }}\n      onDoubleClick={() => onOpen(entry)}\n      className={cn(\n        \"grid h-8 cursor-default items-center gap-3 px-3 text-sm outline-none\",\n        LIST_COLUMNS,\n        isSelected\n          ? \"bg-primary text-primary-foreground\"\n          : isFocused\n            ? \"bg-accent\"\n            : \"hover:bg-accent/50\",\n      )}\n    >\n      <div\n        className=\"flex min-w-0 items-center gap-1.5\"\n        style={{ paddingLeft: `${depth * 1.125}rem` }}\n      >\n        {entry.kind === \"folder\" ? (\n          <button\n            type=\"button\"\n            aria-label={\n              isExpanded ? `Collapse ${entry.name}` : `Expand ${entry.name}`\n            }\n            onClick={(event) => {\n              event.stopPropagation();\n              onToggle(entry);\n            }}\n            className=\"hover:bg-background/70 focus-visible:ring-ring flex size-5 shrink-0 items-center justify-center rounded-sm focus-visible:ring-2\"\n          >\n            {isExpanded ? (\n              <ChevronDown className=\"size-3.5\" aria-hidden />\n            ) : (\n              <ChevronRight className=\"size-3.5\" aria-hidden />\n            )}\n          </button>\n        ) : (\n          <span className=\"size-5 shrink-0\" />\n        )}\n        {entry.kind === \"folder\" ? (\n          <Folder\n            className=\"text-muted-foreground size-4 shrink-0\"\n            aria-hidden\n          />\n        ) : shouldUseFileSystemListThumbnail(entry) ? (\n          <FileSystemThumbnail\n            file={entry}\n            presentation=\"decorative\"\n            className=\"size-5 shrink-0 rounded-[3px]\"\n          />\n        ) : (\n          <PierreFileIcon file={entry} className=\"size-4 shrink-0\" />\n        )}\n        <span className=\"min-w-0 truncate\">{entry.name}</span>\n      </div>\n      <div className=\"text-muted-foreground truncate\">\n        {entryKindLabel(entry)}\n      </div>\n      <div className=\"text-muted-foreground truncate text-right\">\n        {entry.kind === \"file\" ? formatFileSystemSize(entry.size) : \"\"}\n      </div>\n      <div className=\"text-muted-foreground truncate\">\n        {formatFileSystemDate(entry.updatedAt ?? entry.createdAt)}\n      </div>\n    </div>\n  );\n}\n\nfunction PierreFileIconSprite() {\n  useMountEffect(() => {\n    if (document.getElementById(PIERRE_ICON_SPRITE_ROOT_ID)) return;\n\n    const root = document.createElement(\"div\");\n    root.id = PIERRE_ICON_SPRITE_ROOT_ID;\n    root.hidden = true;\n    root.innerHTML = getBuiltInSpriteSheet(\"complete\");\n    document.body.appendChild(root);\n  });\n\n  return null;\n}\n\nfunction PierreFileIcon({\n  className,\n  file,\n}: {\n  className?: string;\n  file: FileSystemFileEntry;\n}) {\n  const icon = PIERRE_FILE_ICON_RESOLVER.resolveIcon(\n    \"file-tree-icon-file\",\n    file.name,\n  );\n  const width = icon.width ?? 16;\n  const height = icon.height ?? 16;\n\n  return (\n    <svg\n      aria-hidden\n      className={cn(\"text-muted-foreground\", className)}\n      data-icon-name={icon.remappedFrom ?? icon.name}\n      data-icon-token={icon.token}\n      fill=\"currentColor\"\n      height={height}\n      viewBox={icon.viewBox ?? `0 0 ${width} ${height}`}\n      width={width}\n    >\n      <use href={`#${icon.name.replace(/^#/, \"\")}`} />\n    </svg>\n  );\n}\n\nfunction shouldUseFileSystemListThumbnail(file: FileSystemFileEntry) {\n  if (file.previewImageUrl || file.previewSource) return true;\n\n  const mimeType = file.mimeType ?? file.source?.mimeType ?? \"\";\n  if (mimeType === \"application/pdf\" || mimeType.startsWith(\"image/\")) {\n    return true;\n  }\n\n  return /\\.(avif|bmp|gif|jpe?g|pdf|png|svg|tiff?|webp)$/i.test(file.name);\n}\n\nfunction FileSystemListMessageRow({\n  depth,\n  label,\n}: {\n  depth: number;\n  label: string;\n}) {\n  return (\n    <div\n      className={cn(\n        \"text-muted-foreground grid h-8 items-center gap-3 px-3 text-sm\",\n        LIST_COLUMNS,\n      )}\n    >\n      <div style={{ paddingLeft: `${(depth + 1) * 1.125}rem` }}>{label}</div>\n      <div />\n      <div />\n      <div />\n    </div>\n  );\n}\n\nfunction FileSystemListErrorRow({\n  depth,\n  error,\n  folder,\n  onRetry,\n}: {\n  depth: number;\n  error: string;\n  folder: FileSystemEntry;\n  onRetry: (entry: FileSystemEntry, options?: { retry?: boolean }) => void;\n}) {\n  return (\n    <div\n      className={cn(\n        \"text-destructive grid h-8 items-center gap-3 px-3 text-sm\",\n        LIST_COLUMNS,\n      )}\n    >\n      <div\n        className=\"flex min-w-0 items-center gap-2\"\n        style={{ paddingLeft: `${(depth + 1) * 1.125}rem` }}\n      >\n        <AlertCircle className=\"size-3.5 shrink-0\" aria-hidden />\n        <span className=\"truncate\">{error}</span>\n        <Button\n          type=\"button\"\n          size=\"sm\"\n          variant=\"ghost\"\n          className=\"h-6 px-2\"\n          onClick={() => onRetry(folder, { retry: true })}\n        >\n          Retry\n        </Button>\n      </div>\n      <div />\n      <div />\n      <div />\n    </div>\n  );\n}\n\nfunction createFileSystemListRows({\n  currentPath,\n  expandedPaths,\n  folderErrors,\n  index,\n  isSearching,\n  loadingFolders,\n}: {\n  currentPath: string;\n  expandedPaths: ReadonlySet<string>;\n  folderErrors: ReadonlyMap<string, string>;\n  index: { children: Map<string, FileSystemEntry[]> };\n  isSearching: boolean;\n  loadingFolders: ReadonlySet<string>;\n}): FileSystemListRow[] {\n  const rows: FileSystemListRow[] = [];\n  const appendChildren = (path: string, depth: number) => {\n    const children = index.children.get(path) ?? [];\n\n    for (const entry of children) {\n      const hasVisibleFolderState =\n        entry.kind === \"folder\" &&\n        (loadingFolders.has(entry.path) || folderErrors.has(entry.path));\n      const isExpanded =\n        entry.kind === \"folder\" &&\n        (isSearching || expandedPaths.has(entry.path) || hasVisibleFolderState);\n\n      rows.push({\n        depth,\n        entry,\n        id: `entry:${entry.path}`,\n        isExpanded,\n        kind: \"entry\",\n      });\n\n      if (entry.kind !== \"folder\" || !isExpanded) continue;\n\n      if (loadingFolders.has(entry.path)) {\n        rows.push({\n          depth,\n          folder: entry,\n          id: `loading:${entry.path}`,\n          kind: \"loading\",\n        });\n      }\n\n      const error = folderErrors.get(entry.path);\n      if (error) {\n        rows.push({\n          depth,\n          error,\n          folder: entry,\n          id: `error:${entry.path}`,\n          kind: \"error\",\n        });\n      }\n\n      appendChildren(entry.path, depth + 1);\n    }\n  };\n\n  appendChildren(currentPath, 0);\n  return rows;\n}\n\nexport function FileSystemEmptyRows({ label }: { label: string }) {\n  return (\n    <div className=\"text-muted-foreground flex size-full items-center justify-center text-sm\">\n      {label}\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-list-view.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-grid-view.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Folder } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\n\nimport type { FileSystemBrowserController } from \"./file-system-browser-controller\";\nimport { FileSystemThumbnail } from \"./file-system-thumbnail\";\nimport type { FileSystemEntry } from \"./file-system-types\";\nimport { useFileSystemRovingFocus } from \"./use-file-system-roving-focus\";\nimport { useKeyedLayoutEffect } from \"@/hooks/use-keyed-layout-effect\";\nimport { useFixedRowVirtualization } from \"./fixed-grid-virtualization\";\n\nconst TILE_MIN_WIDTH = 124;\nconst TILE_HEIGHT = 132;\nconst GRID_PADDING = 12;\n\nexport function FileSystemGridView({\n  controller,\n}: {\n  controller: FileSystemBrowserController;\n}) {\n  const viewportRef = React.useRef<HTMLDivElement | null>(null);\n  const [columnCount, setColumnCount] = React.useState(1);\n  const { browser, fileActions } = controller;\n  const entries = browser.entries;\n\n  useKeyedLayoutEffect(\"mount\", () => {\n    const viewport = viewportRef.current;\n    if (!viewport || typeof ResizeObserver === \"undefined\") return;\n\n    const update = () => {\n      const available = Math.max(1, viewport.clientWidth - GRID_PADDING * 2);\n      setColumnCount(Math.max(1, Math.floor(available / TILE_MIN_WIDTH)));\n    };\n    const observer = new ResizeObserver(update);\n\n    update();\n    observer.observe(viewport);\n    return () => observer.disconnect();\n  });\n\n  const rowCount = Math.ceil(entries.length / columnCount);\n  const { scrollToRow, totalRowSize, virtualRows } = useFixedRowVirtualization({\n    rowCount,\n    rowSize: TILE_HEIGHT,\n    rowOverscan: 5,\n    initialViewportHeight: 560,\n    scrollRef: viewportRef,\n  });\n  const rovingFocus = useFileSystemRovingFocus({\n    entries,\n    getScrollIndex: (entry) => {\n      const index = entries.findIndex(\n        (candidate) => candidate.path === entry.path,\n      );\n\n      return index === -1 ? -1 : Math.floor(index / columnCount);\n    },\n    onSelect: browser.selectEntry,\n    scrollToIndex: (index) => {\n      if (index !== -1) {\n        scrollToRow({ rowIndex: index, align: \"center\", behavior: \"auto\" });\n      }\n    },\n    selectedPath: browser.selectedPath,\n  });\n  const openEntry = React.useCallback(\n    (entry: FileSystemEntry) => {\n      if (entry.kind === \"folder\") {\n        browser.navigateTo(entry.path);\n      } else {\n        fileActions.openPreview(entry);\n      }\n    },\n    [browser.navigateTo, fileActions],\n  );\n  const handleKeyDown = (event: React.KeyboardEvent) => {\n    if (event.key === \"ArrowRight\" || event.key === \"ArrowLeft\") {\n      rovingFocus.selectByOffset(event.key === \"ArrowRight\" ? 1 : -1);\n      event.preventDefault();\n      return;\n    }\n    if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n      rovingFocus.selectByOffset(\n        event.key === \"ArrowDown\" ? columnCount : -columnCount,\n      );\n      event.preventDefault();\n      return;\n    }\n    if (event.key === \"Home\" || event.key === \"End\") {\n      rovingFocus.selectBoundary(event.key === \"Home\" ? \"first\" : \"last\");\n      event.preventDefault();\n      return;\n    }\n    if (event.key === \"Enter\" && browser.selectedEntry) {\n      openEntry(browser.selectedEntry);\n      event.preventDefault();\n      return;\n    }\n\n    rovingFocus.selectTypeAhead(event);\n  };\n\n  if (!entries.length) {\n    return (\n      <div className=\"text-muted-foreground flex size-full items-center justify-center text-sm\">\n        This folder is empty\n      </div>\n    );\n  }\n\n  return (\n    <ScrollArea\n      orientation=\"vertical\"\n      viewportRef={viewportRef}\n      viewportClassName=\"p-3\"\n      viewportProps={{\n        onKeyDown: handleKeyDown,\n        role: \"listbox\",\n        tabIndex: 0,\n        \"aria-label\": \"Files\",\n      }}\n    >\n      <div className=\"relative\" style={{ height: totalRowSize }}>\n        {virtualRows.map((row) => {\n          const rowEntries = entries.slice(\n            row.index * columnCount,\n            row.index * columnCount + columnCount,\n          );\n\n          return (\n            <div\n              key={row.index}\n              className=\"absolute inset-x-0 grid gap-2\"\n              style={{\n                gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`,\n                transform: `translateY(${row.start}px)`,\n              }}\n            >\n              {rowEntries.map((entry) => (\n                <FileSystemGridTile\n                  key={entry.path}\n                  controller={controller}\n                  entry={entry}\n                  ref={(element) => {\n                    rovingFocus.registerEntryRef(entry.path, element);\n                  }}\n                />\n              ))}\n            </div>\n          );\n        })}\n      </div>\n    </ScrollArea>\n  );\n}\n\nconst FileSystemGridTile = React.forwardRef<\n  HTMLButtonElement,\n  {\n    controller: FileSystemBrowserController;\n    entry: FileSystemEntry;\n  }\n>(function FileSystemGridTile({ controller, entry }, ref) {\n  const { browser, fileActions } = controller;\n  const selectedPath = browser.selectedPath;\n  const isSelected = entry.path === selectedPath;\n\n  return (\n    <button\n      ref={ref}\n      type=\"button\"\n      role=\"option\"\n      aria-selected={isSelected}\n      tabIndex={isSelected || !selectedPath ? 0 : -1}\n      onClick={() => browser.selectEntry(entry)}\n      onDoubleClick={() => {\n        if (entry.kind === \"folder\") {\n          browser.navigateTo(entry.path);\n        } else {\n          fileActions.openPreview(entry);\n        }\n      }}\n      className=\"group hover:bg-accent/50 focus-visible:ring-ring flex h-[124px] min-w-0 flex-col items-center gap-2 rounded-sm p-2 text-center outline-none focus-visible:ring-2\"\n    >\n      <span\n        className={cn(\n          \"flex size-16 shrink-0 items-center justify-center rounded-sm\",\n          isSelected && \"bg-accent\",\n        )}\n      >\n        {entry.kind === \"folder\" ? (\n          <Folder className=\"text-muted-foreground size-11\" aria-hidden />\n        ) : (\n          <FileSystemThumbnail\n            file={entry}\n            resolveFileSource={fileActions.resolveFileSource}\n            className=\"size-16\"\n          />\n        )}\n      </span>\n      <span\n        className={cn(\n          \"line-clamp-2 max-w-full rounded px-1 text-xs leading-tight break-words\",\n          isSelected && \"bg-primary text-primary-foreground\",\n        )}\n      >\n        {entry.name}\n      </span>\n    </button>\n  );\n});\n",
      "type": "registry:ui",
      "target": "@ui/file-system-grid-view.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-columns-view.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { ChevronRight, Folder } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\n\nimport type { FileSystemBrowserController } from \"./file-system-browser-controller\";\nimport { folderHasChildren, pathParent } from \"./file-system-index\";\nimport { FileSystemThumbnail } from \"./file-system-thumbnail\";\nimport type { FileSystemEntry } from \"./file-system-types\";\nimport { useFixedRowVirtualization } from \"./fixed-grid-virtualization\";\nimport { useFileSystemRovingFocus } from \"./use-file-system-roving-focus\";\n\nconst COLUMN_ROW_HEIGHT = 32;\n\n// The columns view stacks multiple `w-64` (16rem) columns side by side, so it\n// needs a substantially wider sidebar than the single-pane list/tree views.\nexport const FILE_SYSTEM_SIDEBAR_WIDTH = \"min(22rem, 85vw)\";\nexport const FILE_SYSTEM_COLUMNS_SIDEBAR_WIDTH =\n  \"min(clamp(32rem, 40vw, 40rem), 85vw)\";\n\nexport function FileSystemColumnsView({\n  controller,\n}: {\n  controller: FileSystemBrowserController;\n}) {\n  const { browser } = controller;\n  const columnPaths = React.useMemo(() => {\n    const paths = [browser.currentPath];\n    const selectedPath = browser.selectedPath;\n\n    if (!selectedPath?.startsWith(browser.currentPath)) return paths;\n\n    const selectedEntry = browser.selectedEntry;\n    const targetPath =\n      selectedEntry?.kind === \"folder\"\n        ? selectedEntry.path\n        : (selectedEntry?.parentPath ?? browser.currentPath);\n    const relativePath = targetPath.slice(browser.currentPath.length);\n    let walkedPath = browser.currentPath;\n\n    for (const segment of relativePath.split(\"/\")) {\n      if (!segment) continue;\n      walkedPath = `${walkedPath}${segment}/`;\n      paths.push(walkedPath);\n    }\n\n    return paths;\n  }, [browser.currentPath, browser.selectedEntry, browser.selectedPath]);\n\n  return (\n    <ScrollArea\n      orientation=\"horizontal\"\n      viewportClassName=\"overscroll-x-contain\"\n    >\n      <div className=\"flex h-full min-w-full\">\n        {columnPaths.map((path, index) => (\n          <FileSystemColumn\n            key={path || \"(root)\"}\n            controller={controller}\n            isLast={index === columnPaths.length - 1}\n            path={path}\n          />\n        ))}\n      </div>\n    </ScrollArea>\n  );\n}\n\nfunction FileSystemColumn({\n  controller,\n  isLast,\n  path,\n}: {\n  controller: FileSystemBrowserController;\n  isLast: boolean;\n  path: string;\n}) {\n  const { browser, fileActions } = controller;\n  const viewportRef = React.useRef<HTMLDivElement | null>(null);\n  const entries = React.useMemo(\n    () => browser.index.children.get(path) ?? [],\n    [browser.index.children, path],\n  );\n  const { scrollToRow, totalRowSize, virtualRows } = useFixedRowVirtualization({\n    rowCount: entries.length,\n    rowSize: COLUMN_ROW_HEIGHT,\n    rowOverscan: 10,\n    initialViewportHeight: 560,\n    scrollRef: viewportRef,\n  });\n  const rovingFocus = useFileSystemRovingFocus({\n    entries,\n    getScrollIndex: (entry) =>\n      entries.findIndex((candidate) => candidate.path === entry.path),\n    onSelect: (entry) => {\n      browser.selectEntry(entry);\n      if (entry.kind === \"folder\") {\n        void browser.ensureChildren(entry.path).catch(() => {});\n      }\n    },\n    scrollToIndex: (index) => {\n      if (index !== -1) {\n        scrollToRow({ rowIndex: index, align: \"center\", behavior: \"auto\" });\n      }\n    },\n    selectedPath: browser.selectedPath,\n  });\n  const openEntry = React.useCallback(\n    (entry: FileSystemEntry) => {\n      if (entry.kind === \"folder\") {\n        browser.navigateTo(entry.path);\n      } else {\n        fileActions.openPreview(entry);\n      }\n    },\n    [browser.navigateTo, fileActions],\n  );\n  const selectParent = React.useCallback(() => {\n    const selectedEntry = browser.selectedEntry;\n    if (!selectedEntry) return;\n\n    const parentPath =\n      selectedEntry.kind === \"folder\"\n        ? pathParent(selectedEntry.path)\n        : selectedEntry.parentPath;\n    const parent = parentPath\n      ? (browser.rawIndex.folders.get(parentPath) ?? null)\n      : null;\n\n    if (parent) browser.selectEntry(parent);\n  }, [browser.rawIndex.folders, browser.selectEntry, browser.selectedEntry]);\n  const selectChild = React.useCallback(() => {\n    const selectedEntry = browser.selectedEntry;\n    if (selectedEntry?.kind !== \"folder\") return;\n\n    void browser.selectFirstChildAfterEnsure(selectedEntry.path);\n  }, [browser.selectFirstChildAfterEnsure, browser.selectedEntry]);\n  const handleKeyDown = (event: React.KeyboardEvent) => {\n    if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n      rovingFocus.selectByOffset(event.key === \"ArrowDown\" ? 1 : -1);\n      event.preventDefault();\n      return;\n    }\n    if (event.key === \"Home\" || event.key === \"End\") {\n      rovingFocus.selectBoundary(event.key === \"Home\" ? \"first\" : \"last\");\n      event.preventDefault();\n      return;\n    }\n    if (event.key === \"ArrowRight\") {\n      selectChild();\n      event.preventDefault();\n      return;\n    }\n    if (event.key === \"ArrowLeft\") {\n      selectParent();\n      event.preventDefault();\n      return;\n    }\n    if (event.key === \"Enter\" && browser.selectedEntry) {\n      openEntry(browser.selectedEntry);\n      event.preventDefault();\n      return;\n    }\n\n    rovingFocus.selectTypeAhead(event);\n  };\n\n  return (\n    <div\n      className={cn(\"w-64 shrink-0 border-r\", isLast && \"flex-1\")}\n      role=\"listbox\"\n      aria-label={path || \"Files\"}\n      tabIndex={0}\n      onKeyDown={handleKeyDown}\n    >\n      <div ref={viewportRef} className=\"h-full overflow-auto p-1.5\">\n        {entries.length ? (\n          <div className=\"relative\" style={{ height: totalRowSize }}>\n            {virtualRows.map((virtualRow) => {\n              const entry = entries[virtualRow.index];\n              if (!entry) return null;\n\n              return (\n                <FileSystemColumnRow\n                  key={entry.path}\n                  controller={controller}\n                  entry={entry}\n                  ref={(element) => {\n                    rovingFocus.registerEntryRef(entry.path, element);\n                  }}\n                  style={{ transform: `translateY(${virtualRow.start}px)` }}\n                />\n              );\n            })}\n          </div>\n        ) : (\n          <div className=\"text-muted-foreground px-2 py-1.5 text-xs\">\n            This folder is empty\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n\nconst FileSystemColumnRow = React.forwardRef<\n  HTMLButtonElement,\n  {\n    controller: FileSystemBrowserController;\n    entry: FileSystemEntry;\n    style: React.CSSProperties;\n  }\n>(function FileSystemColumnRow({ controller, entry, style }, ref) {\n  const { browser, fileActions } = controller;\n  const selectedPath = browser.selectedPath;\n  const isSelected = entry.path === selectedPath;\n  const isOnTrail =\n    entry.kind === \"folder\" &&\n    selectedPath?.startsWith(entry.path) &&\n    pathParent(selectedPath) !== entry.parentPath;\n\n  return (\n    <button\n      ref={ref}\n      type=\"button\"\n      role=\"option\"\n      aria-selected={isSelected}\n      tabIndex={isSelected || !selectedPath ? 0 : -1}\n      onClick={() => {\n        browser.selectEntry(entry);\n        if (entry.kind === \"folder\") {\n          void browser.ensureChildren(entry.path).catch(() => {});\n        }\n      }}\n      onDoubleClick={() => {\n        if (entry.kind === \"folder\") {\n          browser.navigateTo(entry.path);\n        } else {\n          fileActions.openPreview(entry);\n        }\n      }}\n      className={cn(\n        \"focus-visible:ring-ring absolute inset-x-0 flex h-8 shrink-0 items-center gap-2 rounded-sm px-2 text-left text-sm outline-none focus-visible:ring-2\",\n        isSelected\n          ? \"bg-primary text-primary-foreground\"\n          : isOnTrail\n            ? \"bg-accent\"\n            : \"hover:bg-accent/50\",\n      )}\n      style={style}\n    >\n      {entry.kind === \"folder\" ? (\n        <Folder className=\"text-muted-foreground size-4 shrink-0\" aria-hidden />\n      ) : (\n        <FileSystemThumbnail\n          file={entry}\n          resolveFileSource={fileActions.resolveFileSource}\n          className=\"w-4 shrink-0\"\n        />\n      )}\n      <span className=\"min-w-0 flex-1 truncate\">{entry.name}</span>\n      {entry.kind === \"folder\" && folderHasChildren(browser.rawIndex, entry) ? (\n        <ChevronRight className=\"text-muted-foreground size-3.5 shrink-0\" />\n      ) : null}\n    </button>\n  );\n});\n",
      "type": "registry:ui",
      "target": "@ui/file-system-columns-view.tsx"
    },
    {
      "path": "registry/new-york-v4/ui/file-system-utils.ts",
      "content": "import { formatFileSize } from \"@/components/ui/file-size-format\";\n\nexport function formatFileSystemSize(size: number | undefined) {\n  return typeof size === \"number\" ? formatFileSize(size) : \"\";\n}\n\nexport function formatFileSystemDate(value: string | undefined) {\n  if (!value) return \"\";\n\n  const date = new Date(value);\n  if (Number.isNaN(date.getTime())) return \"\";\n\n  return new Intl.DateTimeFormat(undefined, {\n    dateStyle: \"medium\",\n    timeStyle: \"short\",\n  }).format(date);\n}\n",
      "type": "registry:ui",
      "target": "@ui/file-system-utils.ts"
    }
  ],
  "type": "registry:ui"
}