A file browser tab plugin for CloudCLI that lets you browse directories, preview text files, and download files — all without leaving the web UI.
- Directory browsing — Navigate the filesystem with breadcrumb trail and Up button
- File preview — Click any text file to view contents in a modal overlay (up to 256 KB)
- File download — Download any file directly to your local machine via the browser
- Search — Fuzzy filename search with debounced input across the current directory tree
- Smart filtering — Heavy directories (
node_modules,.git, etc.) are listed but not traversed - File type icons — Emoji icons for 30+ file types (JS, TS, Python, Rust, Docker, etc.)
- Dark/light theme — Automatically follows CloudCLI's theme setting
- Path security — Configurable allowed root directories; path traversal protection built in
| Dark Mode | Light Mode |
|---|---|
![]() |
![]() |
- Open CloudCLI web UI
- Go to Settings > Plugins
- Paste the repository URL:
https://github.com/strykereye2/cloudcli-plugin-file-manager - Click Install
- Restart CloudCLI (or refresh the page)
# Clone into your plugins directory
cd ~/.claude-code-ui/plugins
git clone https://github.com/strykereye2/cloudcli-plugin-file-manager file-manager
# Register in plugins.json
node -e "
const fs = require('fs');
const p = process.env.HOME + '/.claude-code-ui/plugins.json';
let cfg = {};
try { cfg = JSON.parse(fs.readFileSync(p, 'utf8')); } catch {}
cfg['file-manager'] = { name: 'file-manager', source: 'local', enabled: true };
fs.writeFileSync(p, JSON.stringify(cfg, null, 2));
console.log('Registered file-manager plugin');
"If you're baking this into a Docker image, copy the plugin files at build time and register at runtime:
# Dockerfile
COPY plugins/file-manager /home/user/.claude-code-ui/plugins/file-manager# Runtime registration (e.g., in an entrypoint script)
node -e "
const fs = require('fs');
const p = '/home/user/.claude-code-ui/plugins.json';
let cfg = {};
try { cfg = JSON.parse(fs.readFileSync(p, 'utf8')); } catch {}
if (!cfg['file-manager']) {
cfg['file-manager'] = { name: 'file-manager', source: 'local', enabled: true };
fs.writeFileSync(p, JSON.stringify(cfg, null, 2));
}
"| Variable | Description | Default |
|---|---|---|
FILE_MANAGER_ROOTS |
Comma-separated list of allowed root directories | $HOME,/tmp |
FILE_MANAGER_DEFAULT_PATH |
Starting directory when the plugin opens | First entry in FILE_MANAGER_ROOTS |
Example:
export FILE_MANAGER_ROOTS="/workspace,/home/myuser,/tmp,/data"
export FILE_MANAGER_DEFAULT_PATH="/workspace"The plugin enforces a strict path allowlist:
- Allowed roots — Only directories under
FILE_MANAGER_ROOTSare accessible - Path traversal protection — All paths are resolved to absolute before checking against the allowlist
- No symlink escape —
lstatis used for directory listings; symlinks are flagged but not followed outside roots - Hidden directory filtering —
.git/objects,.git/pack, andnode_modules/.cacheare automatically excluded - Skip heavy directories —
node_modules,.git,__pycache__,.venv,coverage,.turboare listed but not traversed during search
The plugin server exposes these endpoints (accessed via CloudCLI's plugin RPC proxy):
| Method | Endpoint | Description |
|---|---|---|
GET |
/list?path=<dir> |
List directory contents |
GET |
/info?path=<file> |
Get file metadata + text preview |
GET |
/download?path=<file> |
Download file with correct MIME type |
GET |
/search?root=<dir>&q=<query> |
Search filenames (max 100 results, 6 levels deep) |
cloudcli-plugin-file-manager/
├── manifest.json # Plugin metadata (name, slot, entry points)
├── icon.svg # Tab icon (folder with download arrow)
├── src/
│ ├── server.js # Node.js HTTP backend (list, info, download, search)
│ └── index.js # Frontend UI (mount/unmount exports)
├── dist/
│ ├── server.js # Production copy of server
│ └── index.js # Production copy of frontend
├── package.json
├── LICENSE # MIT
└── README.md
manifest.json— Declares the plugin name, type (module), slot (tab), and entry pointsserverentry — CloudCLI spawns this as a child process; it prints{"ready": true, "port": N}to stdoutentry— Frontend module that exportsmount(container, api)andunmount(container)api.rpc(method, path, body)— Proxied to the server process via CloudCLI's plugin RPCapi.context— Provides theme, project path, session infoapi.onContextChange(cb)— Subscribe to theme/project changes
# Clone the repo
git clone https://github.com/strykereye2/cloudcli-plugin-file-manager
cd cloudcli-plugin-file-manager
# Build (copies src → dist)
npm run build
# Test the server standalone
node dist/server.js
# Outputs: {"ready":true,"port":XXXXX}
# Then test endpoints:
curl http://127.0.0.1:XXXXX/list?path=/tmp
curl http://127.0.0.1:XXXXX/search?root=/tmp&q=test- CloudCLI v0.3.0+ (plugin system support)
- Node.js v18+ (uses ES modules,
node:imports)
MIT — see LICENSE.

