File tree and basic file management

The sidebar and central Files page use the official @pierre/trees: default 30px row height, density 1, selection/focus states, keyboard navigation and virtual scrolling. Directory arrows are replaced with the existing Lucide open/closed folders; the framework supplies all other tree rendering.

Current status: official component integrated and default App updated; 394 Web tests, complete builds and independent review passed.

File columns

The shared sidebar and central Files tree has a fixed header with Name, Size, Date Modified and Kind columns, in that order. Below 720 pixels, Name and Size fill the initial viewport; horizontal scrolling reveals the remaining columns. Wider views fit all four columns. Name takes the remaining width and retains middle truncation. Size reserves 100 pixels, Date Modified 200 pixels and Kind 140 pixels. Header and rows share column boundaries and horizontal scroll position; the header stays visible during vertical scrolling.

The installed Pierre Trees 1.0.0-beta.6 public renderRowDecoration API supports text parts but has no native sortable columns. Retain its virtual rows, hierarchy, sticky ancestors and keyboard interactions. Render three fixed decoration parts through that API, style them with unsafeCSS, and synchronize the native horizontal scroll element with an external header. A ResizeObserver measures the native viewport, including the scrollbar gutter. Disconnect observers and listeners on unmount. Do not replace the tree with a table framework or introduce per-file metadata requests.

Existing directory and search responses provide mtime in epoch seconds. Pass that metadata into the shared tree; format dates in the current language and local timezone. Kind uses Folder, an uppercase extension plus file, or File when there is no extension. Missing timestamps and synthetic search ancestors leave the date blank. Directory headers toggle the existing per-project server sort preference, preserving folders-first, hidden and ignored filters. Search retains relevance ordering and displays non-interactive headers. Metadata and size-cache permissions, cancellation and refresh behavior remain owned by the existing controllers.

Acceptance uses the real public FileTree and PierreFileTree in Chromium: default Name/Size visibility, synchronized horizontal scroll and column geometry, wide view, nested and sticky rows, date/kind values, sorting requests and preference preservation, search relevance and vertical viewport restoration. Column reordering, manual resizing, extra metadata fields and filesystem watchers are outside this change.

Implementation status

The shared column implementation passes independent specification and quality reviews. Real Chromium verifies default Name/Size visibility, four-column alignment, horizontal synchronization, keyboard-revealed columns, sticky ancestors and ten-level indentation at narrow widths. Metadata display, sort requests, preference preservation, search relevance and viewport restoration pass the public-component checks.

Filename truncation

The metadata columns keep their specified widths. Filename content takes the remaining Name column width and retains Pierre middle truncation. Deep hierarchy indentation is capped inside Name, leaving space for the icon and filename while preserving column alignment. Unknown folder sizes remain blank; inline rename keeps the framework’s existing decoration suppression.

Persistent folder size samples

Opening Files reuses terminal size samples across view remounts and worker restarts. At most 256 samples are kept in the default profile state and displayed without recursive I/O. Explicit Refresh and Recalculate request new scans. Successful Files mutations remove affected ancestor and subtree samples from memory and disk and cancel affected active scans, including overlapping project roots. Incomplete scans retain skipped-entry provenance; active scan tokens are never persisted.

ChoiceBoundary
Existing atomic JSON writerAdopted for a bounded snapshot owned by one worker. Uses private temporary files and atomic replacement. A corrupt or unavailable cache falls back to scanning.
Python sqlite3Supports durable transactions and concurrent connections. Rejected for this bounded, single-worker sample cache; no database schema or new dependency is needed.
Pierre tree / React shared queueRetained for virtualization and two concurrent visible-folder jobs. Neither supplies durable server-side filesystem samples.

Keys use the validated absolute directory path. Device and inode identity must still match before serving a sample, so project rebinding or directory replacement cannot reuse another directory’s bytes. A cached sample can be outdated after nested edits; timestamps and completeness remain visible in details. Size sorting retains the existing recent-complete-sample rule. No filesystem watcher, recursive freshness check, content reads or new profile is added.

Acceptance through project_folder_size: a finished sample survives a fresh cache load without a recursive walk; corrupt cache storage leaves metadata queries usable; incomplete samples remain incomplete; replacement directories do not reuse old samples. Acceptance through Files: reopening both views and opening details issue no new scan for a cached sample; Refresh and Recalculate still update bytes using the shared queue.

Implementation status

Server persistence and Files reuse have passed public-entry regressions and independent specification and quality reviews. Fresh-worker reads preserve complete and skipped-entry samples. Files mutations invalidate durable ancestor samples and root-directory scans; remounts reuse terminal samples, while Refresh and Recalculate still scan.

Live component preview

This framework interaction preview uses the actual Pierre component and product folder configuration. It demonstrates hierarchy and selection; the column layout is verified separately through the shared product component. Data and sizes are examples; it does not read or modify real files. Expand folders, select entries, navigate with the keyboard, filter and switch themes. The create icon only demonstrates the product button appearance.

OpenProgram

Boundaries and feature integration

CapabilityCurrent design
Display and interactionPierre handles row layout, hierarchy, selection, focus, virtual scrolling and keyboard navigation. Directories use icons.remap with a custom sprite; expanded state selects open/closed paths. Folder rotation is prohibited.
Paths and toolbarThe tree, navigation and toolbar share 8px horizontal outer margins. The first row has responsive 14px breadcrumbs. Clicking a path first locates it among loaded entries and expands ancestors without rereading the list or recalculating sizes; query only if the target is missing. Path buttons are at least 32px high with 8px horizontal padding. Arrows have no side gaps and shift 4px toward adjacent buttons without changing button padding or width. Do not show duplicate-name tooltips. The right end copies the complete absolute path and shows a checkmark for 1.5 seconds on success. Path context menus copy the relative path, absolute path or name of the clicked location. The second row provides search, new file, new folder, refresh, sort and info; the third row expands search on demand. Keep existing buttons and rounded menus.
Queries and sortingproject_file_tree retains per-directory lazy loading, pagination and sorting. Framework comparators preserve backend order, supporting name, type, modification time, size and folders-first; never silently revert to alphabetical sorting.
File and folder sizesOrdinary files display byte counts. Visible directories reuse bounded background statistics; search-excluded directories such as .cache and node_modules still support metadata and size calculation. Preserve cached, scanning, complete, partial, canceled and error states. Lists display numeric sizes without ≈ or ≥. While calculation is active and a value exists, only that value slowly varies in gray brightness while continuing to update. Restore normal appearance when calculation stops, with no new text or icons. Leave missing values blank instead of showing a dash. Estimates, lower bounds and completion state remain in Details, which can continue calculation.
Search and locationSearch retains backend permission scope and pagination. Results use Pierre hierarchy, retaining directories in highlight mode. The backend still determines fuzzy matches, indicated by match markers and native current-item selection. Literal queries use framework text highlighting. Controllers expand and scroll to locations instead of relying on old handwritten row DOM.
Creation, renaming and context menusExisting creation and rename forms validate before submission. Framework-internal moves must not replace server operations. Context menus retain details, system reveal, creation, path copying, cut, copy, paste, rename and delete confirmation.
Refresh and errorsPreserve the selected path, expanded directories and loaded pages; retain old rows while refresh is pending. Collapsed parents stay closed even if descendants were previously expanded; reopening restores descendant state. Automatically load the next page near the end of loaded directory entries without a fixed pagination button. On failure, stop automatic retries and provide explicit Retry. Blue selected rows have no border; keyboard focus remains indicated on unselected rows. No divider separates the management toolbar and list. Remove extra vertical tree padding and reduce horizontal margins to 4px. Directory/pagination failures show the path and a retry entry, not fictitious file entries.
State and permissionsWorkspace scope, cancellation, stale-response isolation, draft protection and server-side idempotent mutations keep their existing contracts. The framework does not access real file contents or determine permissions.

References and choices

Adopt the Pierre Trees official React API pinned to 1.0.0-beta.6. The local Codex file-tree implementation and same-origin SVG were checked. Retain Lucide folder and product navigation icons; discontinue handwritten recursive rows, fixed 27px indentation and custom horizontal connectors. Do not enable client-side drag-and-drop moves that bypass server validation.

For shared file-type icons see icon design; for file contents, drafts and recovery contracts see file operations design. Apache 2.0 and icon MIT licenses ship with the product.

Implementation status

The official component is integrated. Passed 394 Web tests, 511 contract tests, Web checks, type checking, production build and independent review. In the default App dark theme, verified folder expansion/collapse, virtual scrolling, file sizes, file tabs, native context menus, sort menus and path preservation after refresh. Nested-parent collapse, tighter spacing and automatic pagination without buttons were verified in the App. Refresh after parent collapse preserves expanded descendants and ancestor caches; actual-component regression tests cover this sequence. Local browser URL policy prevented visual acceptance of the standalone HTML preview. Light mode has not received separate manual acceptance.