ui-workspace's two trigger surfaces each declare a single-kind directory-flow hole (conversation.hero.workspace.directoryFlow / sidebar.workspaces.directoryFlow, same owner contract) and keep only the trigger and the adoption: the Open-local- folder entry renders while the surface's hole is occupied, and the occupant reports one picked path per open through the hole's owner conversation (open/busy/onPicked/onCancel/onError). directory-picker-native becomes dual-face: its browser half fills both holes with a renderless occupant driving host.pickDirectory, so the cordis.yml row that mounts the backend also composes the client interaction — a mismatch is impossible and a second flow package fails at client load. With composition wiring both sides, the host.describe.directoryPicker advertisement and the client's kind branching lose their last consumer: the field, WorkspacesService.directoryPickerKind(), the DirectoryPickerKind wire type, and the picker's per-open describe read are deleted. The connection fixture now serves a deterministic pickDirectory path so the keyless snapshot drives the full pick-then-adopt flow. ui-workspace's hand-rolled declaration deferral is replaced by the deferRegistration helper it duplicated.
2.5 KiB
@deepseek-ai/dsh-host-directory-picker
English | 中文
The workspace-directory picking seam for the web-GUI host: an abstract DirectoryPicker service (ctx.directoryPicker) whose single contract method capability() returns a discriminated capability describing how an operator selects a directory. Backends differ in interaction shape, not just mechanism, so the seam models the shapes explicitly instead of one method set: { kind: 'native', pick(signal) } opens one native OS chooser on the host display (-native); { kind: 'browse', list(path?), createDirectory(path, name) } serves listing/creation primitives an in-app browser drives, which works for remote clients no OS chooser can reach (-browse). Consumers switch on capability().kind; the union derives from the merge-extensible DirectoryPickerCapabilities map (a new backend declaration-merges its shape there), and the documented default for an unknown kind is to hide the picking affordance rather than fail. The capability object must be stable for the service lifetime. The client side mirrors the seam without a wire advertisement: each backend package is dual-face, its browser half registering the matching picking interaction into ui-workspace's directory-flow slots — so one composition row swaps both the host capability and the client flow together.
Browse primitives fail with the typed DirectoryPickerError (directory-unreadable / directory-exists / directory-create-failed, each carrying the subject path), which the consuming gateway maps 1:1 onto wire error codes. DirectoryEntry rows carry a host-owned hidden flag (POSIX dot convention) so display policy stays client-side; DirectoryListing.crumbs is the ancestor chain from the filesystem root, every crumb a jump target. Design rationale, the ctx.fs separation, and the policy decisions live in the directory-picker capability seam Agent Note.
Model Experience
None, as the seam 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
- No multi-root vocabulary — the browse contract exposes one ancestry chain per listing; per-deployment root scoping (and Windows drive-root enumeration above a drive) waits for a consumer that needs it, per the seam Agent Note.