Skip to content
dsh.fish
Bundle

dsh-oh-my-terminal

DSH Web GUI 底部终端面板插件——node-pty 驱动的多标签交互式终端(Windows ConPTY / POSIX openpty)

Source
btsd321
stars
1 stars
License
Apache-2.0
Updated
Updated 2 hours ago

Readme

# dsh-oh-my-terminal

[![version](https://img.shields.io/badge/version-0.2.7-blue)](package.json)
[![license](https://img.shields.io/badge/license-Apache--2.0-green)](LICENSE)
[![node](https://img.shields.io/badge/node-%5E20.19.0%20%7C%7C%20%3E%3D22.0.0-brightgreen)](package.json)

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.

[中文文档](README.zh.md)

## 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

## Installation

This package is not yet published to npm. Install directly from GitHub:

```bash
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 `type` in `$PATH`
- **origin**: `auto` (startup-detected) or `user` (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

```bash
# 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`, not `npm`. 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)
│   ├── 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

[Apache-2.0](LICENSE)

Install

dsh plugin --profile web add github:btsd321/dsh-oh-my-terminal#d9b47ce20256b47ef096a1ea3d935a2d61e7ac60

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
Source