@haowjy/remote-workspace
v0.1.4
Published
Mobile-friendly web workspace for SSH + tmux workflows.
Readme
Remote Workspace
Mobile-friendly read/upload web workspace for this repository.
Features
- Browse repository folders/files
- Upload images into
.clipboard/at repo root (single image per upload) - Delete images from
.clipboard/from the UI - Open any folder in the Files tab to view all images in that folder as a grid
- Preview text files and images
- Render Markdown with Mermaid diagrams
- Hide and block access to configured path segments (always hides
.git) - Allow specific gitignored/hidden image folders (for example
.playwright-mcp) via config - Dedicated collapsible
.clipboardpanel for upload + quick image viewing
This app is intentionally no text editing to keep remote access simple and lower risk. Image operations are limited to upload/delete with strict filename validation.
Start
From repo root:
pnpm devBy default it serves on 127.0.0.1:18080.
The Node launcher configures Tailscale Serve (tailnet-only) by default before starting.
Disable Serve mode (local-only):
pnpm dev -- no-serveEnable Funnel mode (public internet):
pnpm dev -- password your-password --funnelEnable Basic Auth:
pnpm dev -- password your-password
# or
REMOTE_WS_PASSWORD=your-password pnpm dev -- passwordWhen a password is set and serve mode is not explicitly chosen, the launcher defaults to local-only (--no-serve). Add --serve if you want password-protected remote access through Tailscale.
--funnel requires password auth and exposes the workspace publicly.
When this auto-switch happens, the launcher prints a warning with the exact --serve override.
Copy/paste startup command:
cd /path/to/your/repo && pnpm devOptions
pnpm dev -- config /path/to/config
pnpm dev -- port 18111
pnpm dev -- always-hidden .git,.env,.secrets
pnpm dev -- image-dirs .clipboard,.playwright-mcp
pnpm dev -- install
pnpm dev -- no-serve
pnpm dev -- password your-password
pnpm dev -- password your-password --serve
pnpm dev -- password your-password --funnelEnvironment
REMOTE_WS_PORT(default18080)REMOTE_WS_MAX_PREVIEW_BYTES(default1048576)REMOTE_WS_MAX_UPLOAD_BYTES(default26214400)REMOTE_WS_PASSWORD(optional, enables HTTP Basic Auth when set)REMOTE_WS_CONFIG_FILE(optional config file path override)REMOTE_WS_ALWAYS_HIDDEN(optional comma-separated extra hidden path segments)REMOTE_WS_IMAGE_DIRS(optional comma-separated repo-relative folders to expose for image browsing; default.clipboard)REPO_ROOT(injected by launcher script)
Password config file format (default: repo root .remote-workspace.conf):
REMOTE_WS_PASSWORD=your-passwordPassword/config precedence:
- CLI inline password (
--password <pwd>) - Env password (
REMOTE_WS_PASSWORD) - Selected config file value (
REMOTE_WS_PASSWORD=...)
Config file selection precedence:
- CLI config path (
--config <path>) - Env config path (
REMOTE_WS_CONFIG_FILE) - Project config (
<repo-root>/.remote-workspace.conf) - User config (
$XDG_CONFIG_HOME/remote-workspace/config, then$APPDATA/remote-workspace/config, then~/.config/remote-workspace/config)
Upload Clipboard
POST /api/clipboard/uploadalways writes toREPO_ROOT/.clipboardDELETE /api/clipboard/file?name=<filename>deletes one image inREPO_ROOT/.clipboard.clipboardpanel uses dedicated clipboard endpoints (/api/clipboard/upload,/api/clipboard/list,/api/clipboard/file)- Main repository browser blocks always-hidden path segments (
.git+ optional configured segments) - Gitignored paths are hidden/blocked (for example
node_modules/, build artifacts, local secrets) REMOTE_WS_IMAGE_DIRS/--image-dirslets you allow specific hidden/gitignored folders in Files view (for example.playwright-mcp)- Accepted upload types are images only (
png,jpg,jpeg,gif,webp,svg,bmp,heic,heif,avif) - Clipboard panel supports both file picker and
Paste From Clipboardbutton (when browser clipboard image API is available) - Upload requires
namequery parameter (filename is user-controlled) - Filename rules: no spaces, no leading dot,
[A-Za-z0-9._-]only, and must use an allowed image extension - Multipart field names accepted:
file(current UI) andfiles(legacy cached UI compatibility) - Legacy alias:
/api/uploadis still accepted for older cached clients
Folder Image Gallery
- Selecting a directory in Files renders a gallery of image files directly inside that folder.
- Gallery images stream through
GET /api/file?path=<repo-relative-path>. - This works for normal folders and for configured
REMOTE_WS_IMAGE_DIRSfolders.
Caching
- The browser now caches image bytes (
/api/clipboard/file, image responses from/api/file) with short-lived cache headers and validators. - The client keeps a small local metadata cache (tree + clipboard lists) and hydrates immediately on reload, then refreshes in the background.
- Refresh buttons bypass local metadata cache and force a new server fetch.
Tailscale
Tailscale Serve is enabled by default and stays private to your tailnet.
Use --no-serve if you want local-only mode.
Use --funnel to publish via Tailscale Funnel (password required).
If Tailscale is missing or disconnected while serve mode is enabled, the launcher exits with guidance to either switch to local-only mode or run tailscale up and retry --serve.
# Tailnet-only URL
pnpm devManual commands (equivalent):
tailscale serve --bg --https=443 127.0.0.1:18080Auth
When REMOTE_WS_PASSWORD is set (or --password is passed to the launcher), the app requires HTTP Basic Auth for all routes (UI + API).
When auth is enabled, mutating routes (POST/DELETE) also require same-origin Origin/Referer headers.
