# dsh-dir-tree [็ฎ€ไฝ“ไธญๆ–‡](README.md) | **English** > A DeepSeek Harness (DSH) floating **workspace directory-tree** plugin: drag-and-drop file/folder paths into the chat box, lazy loading, search, file-type icons, and auto-follow when switching workspace/session. > ๐Ÿ“š **Full three-form showcase repo (install & internals comparison of dynamic / persistent / standard bundle)**: [dsh-plugin-dir-tree](https://github.com/bentong-chain/dsh-plugin-dir-tree) ## Features - ๐Ÿ“ Floating directory tree of the current session's workspace, minimizable at the bottom-right corner - ๐ŸŒฒ Lazy loading: click `โ–ถ` to expand subdirectories; large directories stay responsive - ๐Ÿ–ฑ๏ธ Drag files/folders into the chat box; the full path is filled in automatically - ๐Ÿ“‹ Double-click to copy a path; single-click to select - ๐Ÿ” Search filter for file names - ๐ŸŽจ File-type icons + directory ๐Ÿ“/๐Ÿ“‚ blue highlight + indented tree lines - ๐Ÿ”„ Switches workspace/session and the tree follows automatically - ๐ŸชŸ Draggable floating window position ## Screenshots ### Main UI (floating window + directory tree) ![Main UI](docs/screenshot-main.png) The floating window "๐Ÿ“ Current Workspace" sits in the bottom-right corner: the full path on top, the tree below โ€” directories in blue with a `๐Ÿ“` icon and a `โ–ถ` expand arrow, files with type icons. ### Drag a path into the chat box (animation) ![Drag demo](docs/drag-drop.gif) Drag any file/folder node into the chat input box; the full path is filled in automatically. ### Lazy-load expansion (animation) ![Lazy load](docs/lazy-load.gif) Click the `โ–ถ` of a folder to expand its children; only the current level is loaded, so large directories stay responsive. ### Minimize / Restore ![Minimize](docs/minimize.gif) Click `โˆ’` or `ร—` to collapse the window; a blue "๐Ÿ“ Directory Tree" button appears in the bottom-right corner. Click it to restore. ## Installation This is a **standard bundle** for DSH โ€” install with `dsh plugin add`, with no source checkout, no editing of built-in packages, and no Creator mode. ### 0. Install/run DSH (pick one) **Option A: Global install (recommended for daily use)** ```bash npm install -g @deepseek-ai/dsh ``` **Option B: Run temporarily with npx (no install, occasional trials)** ```bash npx @deepseek-ai/dsh web ``` | | Option A: Global install | Option B: npx temporary run | |---|---|---| | Installed to the system? | Yes, permanently | No, downloads and runs on demand | | Command form | `dsh ...` (available directly) | `npx @deepseek-ai/dsh ...` | | First start | Fast | Slower (downloads the package first) | | Version | Pinned to the globally installed version (manual updates) | Usually the latest on npm | | Use case | Daily use | Occasional trials, keep the environment clean | > Both share the same `$DSH_HOME` (default `~/.dsh`) and profile directory โ€” plugins/sessions/config are fully interchangeable, so this doesn't affect the plugin install below. ### 1. Install the plugin **Option 1: Install from npm (recommended โ€” no authorization needed)** The plugin is published on npm, one command: ```bash dsh plugin --profile web add dsh-dir-tree ``` **Option 2: Install from git (no npm publish involved)** ```bash dsh plugin --profile web add github:bentong-chain/dsh-dir-tree ``` On first install you'll be prompted to add a build authorization to `pnpm-workspace.yaml` in your profile: ```yaml allowBuilds: dsh-dir-tree: true ``` Copy it and re-run `dsh plugin --profile web add github:bentong-chain/dsh-dir-tree`. ### 2. Start DSH (web UI) `dsh web` is a **hard-coded alias** of `dsh --profile web` โ€” fully equivalent; all three spellings start the same `web` profile (`~/.dsh/profiles/web`): ```bash # Option A: after global install (recommended) dsh --profile web # or the equivalent alias: dsh web # Option B: temporary npx run (equivalent to above) npx @deepseek-ai/dsh web ``` > No matter how you start it, the plugin loads normally โ€” startup method doesn't matter. ## Usage 1. After starting DSH (`dsh --profile web` / `dsh web` / `npx @deepseek-ai/dsh web`), the "๐Ÿ“ Current Workspace" floating window appears in the bottom-right corner 2. Click a folder's `โ–ถ` to expand its subdirectories 3. Drag files/folders into the chat input box to fill in the full path 4. Double-click to copy a path; use the search box to filter; click `โˆ’`/`ร—` to minimize; restore via the bottom-right button ## Structure ``` dsh-dir-tree/ โ”œโ”€โ”€ package.json # dsh.bundle + dsh.client + prepare build script โ”œโ”€โ”€ cordis.patch.yml # inserts the plugin row โ”œโ”€โ”€ index.js # Host half (connection.rpc.handle + node:fs directory listing) โ”œโ”€โ”€ client.js # Client half source (floating UI + connection.rpc.call) โ”œโ”€โ”€ client.bundle.js # build output (generated by prepare, not committed) โ”œโ”€โ”€ build.mjs # prepare script: esbuild bundling of client.js โ””โ”€โ”€ docs/ # README screenshots (main UI/drag/lazy-load/minimize) ``` ## Technical Notes - **RPC**: uses `ctx.connection.rpc` (a Clientโ†’Host channel available to third parties); no api-remotes, no Typert code generation. - **Workspace tracking**: the Client half reads the current session's `cwd` from `ctx.sessions` and passes it to the Host; it refreshes reactively when the workspace/session switches. - **Directory detection**: the Host uses `node:fs`'s `readdir({ withFileTypes: true })` to get `Dirent.isDirectory()` directly โ€” no per-entry `stat`, so large directories stay responsive. - **โš ๏ธ `exports` must include `./package.json`**: client-modules locates packages with `require.resolve('/package.json')`; if an `exports` field is defined, any subpath not listed fails to resolve and the client half is **silently skipped** (no error, never reaches `window.__DSH_BOOT__`). Always include `"./package.json": "./package.json"`. - **โš ๏ธ The Client half must `import React from 'react'`**: in a persistent client bundle, React is not a global โ€” it must be fetched from the browser module table via `require('react')` (`react` is one of the platform modules); referencing a global `React` throws `ReferenceError` at apply time. ## License MIT