Bottom terminal panel for the DSH Web GUI, providing multi-tab interactive terminals powered by node-pty (Windows ConPTY / POSIX openpty) with split panes, a side terminal list, and a dropdown new/split menu.
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:btsd321/dsh-oh-my-terminal
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
A bottom terminal panel plugin for DSH Web GUI. Powered by @lydell/node-pty, it provides multi-session interactive terminals over WebSocket using xterm.js in the browser. Supports Windows ConPTY and POSIX openpty with no local compilation required.
Features
- Multiple terminal sessions: manage several sessions simultaneously; a side list replaces the traditional horizontal tab bar, with right-click rename support
- Split terminals: horizontal splits within the same group; a VSCode-style dropdown next to the
+button (new / split / new by kind) - Session persistence: sessions survive panel close/reopen and are automatically restored on startup
- Configurable shortcut: toggle the panel with a keyboard shortcut; integrates with the host shortcut system and the panel label updates to reflect the current binding
- Resizable panel: drag the top edge of the panel to adjust its height
- Cross-platform: Windows ConPTY and POSIX openpty are selected automatically by
@lydell/node-pty; pre-compiled binaries ship with the package, nothing to compile - Profile-driven terminals: a configurable terminal profile table (type / name / path) drives new-terminal creation; profiles are auto-detected at startup and can be added, renamed, and edited in the settings UI
- Configurable fonts: font family, size, and line height are adjustable and hot-reload on open terminals
- DSH-better-sidebar compatibility: auto-detects DSH-better-sidebar at runtime and switches to compat mode — registers a "Terminal" tab in its bottom workbench instead of the standalone dock; PTY sessions are not bound to the DSH session write handle, eliminating conflicts with DSH-better-sidebar's own terminal. When the host supports
TabDescriptor.rightActions(v0.25.0+), the terminal's action buttons (new / split / restart) are injected into the tab strip's right end, VSCode-style; otherwise it falls back to a header row inside the tab content area
Installation
This package is not yet published to npm. Install directly from GitHub:
dsh plugin --profile web add github:btsd321/dsh-oh-my-terminal
Configuration
| Option | Description | Default |
|---|---|---|
toggleShortcut |
Shortcut to toggle the terminal panel (legacy host only; see below) | Ctrl+Shift+` |
fontFamily |
Terminal font family (CSS font-family string); empty = built-in default stack with CJK fallback |
'' |
fontSize |
Terminal font size in pixels | 12.5 |
lineHeight |
Terminal line height multiplier | 1.25 |
terminalProfiles |
Terminal profile table (JSON array); empty = use auto-detected $PATH terminals | '' |
Terminal profiles
The terminal profile table is a JSON array of { id, type, name, path, origin } entries:
- type: determines spawn semantics —
pwsh/powershell/cmd/bash/zsh/fish/gitbash/nushell/custom - name: display name shown in the dropdown menu (user-editable)
- path: executable path; empty = resolve by
typein$PATH - origin:
auto(startup-detected) oruser(manually added)
Auto-detected profiles (origin: auto) cannot be deleted and their path is read-only, but the name is always editable. The profile table is editable in the settings UI with inline editing, add-row, and delete support.
Development
# Install dependencies (@lydell/node-pty ships pre-compiled binaries — ready to use immediately)
pnpm install
# Type check
pnpm run typecheck
# Build (esbuild, two entry points, output to lib/)
pnpm run build
# Unit tests
pnpm exec tsx --test tests/unit/*.test.ts
Use
pnpm, notnpm. Peer dependencies pin exact versions; npm's incremental resolution on an existing tree will produce ERESOLVE errors.
About the build output
lib/ is committed to version control. The DSH loader imports plugins as plain ESM; it does not run tsx. This repo also declares no lifecycle scripts (prepare, postinstall, etc.) because pnpm 11 rejects git-hosted packages that declare install-time scripts with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED. Run pnpm run build manually and commit the output alongside source.
Native dependency notes
Terminal capability comes from @lydell/node-pty (a pre-compiled distribution of microsoft/node-pty with the same API), pinned exactly to 1.1.0. The ^ range is intentionally omitted: the package's dist-tags.latest points at the 1.2.0-beta series.
It is an N-API package. Binaries are split into six platform sub-packages and shipped inside the tarball; no download or compilation happens at install time. A single binary supports both Node 22 and Node 24. Its package.json has no scripts field at all, so pnpm 10, 11, and 12 never enter the build-authorization path, giving consistent behavior across versions.
The host side lazy-loads the package (await import() on first session creation). If the native binding fails to load, the error is contained to session creation; the plugin module itself remains importable and all other routes stay available.
Architecture overview
src/
├── index.ts # Host entry (Cordis plugin + settings + session lifecycle)
├── routes.ts # HTTP route handlers
├── ws-handler.ts # WebSocket handler (pty data forwarding)
├── client.tsx # Browser entry (React components + plugin registration)
├── client/
│ ├── types.ts # Shared types
│ ├── hooks.ts # useReducer state management + custom hooks
│ ├── term-pane.tsx # xterm.js terminal pane component
│ ├── dropdown.tsx # Dropdown menu next to the + button
│ ├── side-list.tsx # Right-side terminal list panel
│ ├── styles.ts # CSS constants + Campbell dark theme
│ ├── icons.tsx # SVG icon components
│ ├── clipboard.ts # Clipboard utility functions
│ ├── shortcut-bridge.ts # Shortcuts service integration (command registration + toggle bridge)
│ ├── compat.ts # DSH-better-sidebar compat mode detection (soft-probe ctx.betterSidebar + service interface)
│ ├── sidebar-tab.tsx # Sidebar terminal tab (compat mode: embed in DSH-better-sidebar bottom workbench, no DSH session binding)
│ ├── settings/ # Settings UI (types / store / card / profile-table / api / styles)
│ └── terminal/ # Terminal tab state (use-tabs / reducer / use-terminal-state / geometry)
├── persistence.ts # Session persistence (log storage, metadata, startup restore)
├── platform.ts # Platform adapter (POSIX / Windows + shell detection)
├── terminal/ # Terminal kinds, detection, resolution, profile store
├── settings/ # Settings bridge (namespace, bridge routes, patch ops)
├── constants.ts # Protocol, size, shortcut, and env var constants
├── server-command.ts # Command-line parsing utilities
├── shortcut.ts # Shortcut parsing utilities
└── logger.ts # Structured logger
The host side and browser side communicate over WebSocket at /api/dsh-oh-my-terminal and do not import each other directly.
License
Links
More in this category
zhu1090093659/dsh-web#packages/dsh-task-board★ 8567
Task board for the dsh web GUI: a sidebar multi-column kanban whose cards run in real DSH agent sessions and can also be scheduled with cron expressions, executed host-side even with the browser closed.
zhu1090093659/dsh-web#packages/dsh-web-all★ 8567
Plugin and skin collection for the DSH Web UI: task board, Git graph, right-side panel, remote mobile UI, pet, live token stats, and a skin center.
MeteorNOX/DeepSeek-Balance-Whale-Widget★ 4363
A fixed-corner whale widget for the DSH web GUI — balance, today's usage and per-turn cost with peak/off-peak pricing, editable balance-alert and daily-budget bubbles, a module-based custom bubble queue with A/B weighted choices and random lines or images, 30+ vendor templates (OpenAI, OpenRouter, Kimi, SiliconFlow, Ark, Zhipu, MiniMax and more) with per-model balance and subscription quota, plus task-end sound, imported audio, custom roles and a resource manager. Local-only, no telemetry.
ccch1mneyyy/dsh-TUI★ 4235
Claude Code-style full-screen terminal UI: pixel-whale header, live status line, and streaming thought expansion.
omdsh-dev/DSH-better-sidebar★ 4081
Full sidebar workbench with file rendering and editing, terminal, Git, and subagents; third-party plugins can register new tabs.
Devin-AXIS/deepseek-design#deepseek-idesign★ 1441
Visual design studio for websites, app prototypes, posters, cards, reports, and magazines, with templates, direct element editing, selection-aware AI draft handoff, and export.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.