Files
deepseek-harness/packages/host/directory-picker-browse

@deepseek-ai/dsh-host-directory-picker-browse

English | 中文

The in-app browsing backend of the directory-picker seam: BrowseDirectoryPicker registers ctx.directoryPicker with the browse capability — one-level directory listing and child-directory creation over Node's stdlib, which already carries the per-OS adaptation. Nothing renders on the host display, so this backend serves remote clients the native backend cannot.

Behavior facts: listings return directories only, name-sorted, with symlinks-to-directories followed (broken/cyclic links skipped — the probe stat failing means "not enterable") and a host-owned hidden flag (POSIX dot convention) left for the client to act on; crumbs is the root-to-target ancestor chain, the root crumb labeled by its full path (/, C:\); an absent list path means the host account's home directory. createDirectory is non-recursive (a missing parent is a real failure, not a level to invent) and validates the name as a single non-blank segment even when called directly, mirroring the wire schema's fence. Both primitives reject an explicit path that is not fully qualified — relative forms, and on Windows the rooted drive-less forms (\foo, /foo) and incomplete UNC prefixes (\\, \\server) that isAbsolute accepts — with directory-unreadable/directory-create-failed, instead of letting resolve rebase it under the host process cwd or current drive. One list call returns at most maxEntries rows (config, default 1000 — the bound GitHub's web UI applies to directory listings), and the level streams through a bounded window so memory stays O(maxEntries) no matter how many children the directory holds: a cut level keeps the name-sorted head, counts hidden rows against the bound, probes only windowed candidates, and reports truncated: true so the client can say the level is incomplete (a windowed broken symlink is not backfilled from beyond the window — the eviction already marks the level truncated); window insertion is binary with an O(1) full-window tail rejection, and list threads the caller's AbortSignal so a disconnect or timeout stops the scan instead of letting it outlive the caller. Failures throw the seam's typed DirectoryPickerError. Policy rationale: the directory-picker capability seam Agent Note.

Dual-face package: the browser half (./client) fills ui-workspace's two directory-flow holes with the in-app Select Workspace Directory dialog (figma Harness 813-23126 family — Miller two-column view whose navigations land selection-anchored and quiet: the previous view keeps rendering while a crumb jump or a submitted path is scanned (a "Loading…" pill floats over it only once the scan outlives a 300ms silence window, never shifting the columns), then target and parent legs land as one two-pane frame with the target re-selected as its actual parent-level entry — so stepping back never collapses and no intermediate frame flashes (a parent leg outliving its 200ms wait bound lands the target alone and upgrades in place; a failed or truncated parent leg keeps the single-pane landing; the display root keeps the single wide level); breadcrumb with a click-to-edit path zone whose editor seeds a trailing separator, prefix-filters the listed level from the draft's final segment while typing (case-insensitively, over the listed — possibly truncated — rows only; Enter still navigates by the exact text), and cancels on Escape or when focus leaves the dialog card (window/tab switches and in-card focus moves keep the draft); a fixed-label show-hidden footer toggle over the host's hidden flags, with a dot-led typed prefix revealing its matches and the current selection exempt from both filters; nested New-folder dialog), driving host.listDirectory/host.createDirectory and registering its own locale namespace (directory-browser, zh default / en). One cordis.yml row therefore composes both sides of the browse interaction; the client carries no capability-kind branching, and mounting a second flow package fails at load (the holes are single kind).

Model Experience

None, as the backend serves the GUI host's directory selection; nothing here reaches a model request.

KV Cache effect

None; this package neither assembles nor sends a provider request.

Known Limitations and Deferred Work

  • Windows hidden attribute is not read — Node dirents do not expose FILE_ATTRIBUTE_HIDDEN, so hidden means dot-prefixed on every platform until a native probe is worth its cost.
  • No drive-root enumeration — on Windows the ancestry stops at the drive root; crossing drives waits for the browser UI's path-entry affordance rather than an enumeration primitive here.
  • Whole-filesystem scope — no per-deployment browse-root restriction; workspace.create accepts arbitrary paths today, so a root here would be UX scoping, not a boundary — deferred until a deployment needs it.