This commit is contained in:
2026-03-12 15:01:48 +08:00
commit f27996dde0
20 changed files with 5450 additions and 0 deletions

154
CLAUDE.md Normal file
View File

@@ -0,0 +1,154 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository layout (high level)
- `mengyaconnect-backend/` — Go (Gin) HTTP + WebSocket server that:
- exposes a WebSocket SSH “bridge” (`/api/ws/ssh`) backed by `golang.org/x/crypto/ssh`
- persists SSH profiles / quick commands / scripts to the local filesystem under `data/`
- `mengyaconnect-frontend/` — Vite + Vue 3 single-page UI using `xterm.js` to render terminals and talk to the backend WebSocket.
There is no top-level build system; run commands inside each subproject directory.
## Common development commands
### Backend (Go)
Run the server (default `:8080`):
```sh
cd mengyaconnect-backend
go run .
```
Build a local binary:
```sh
cd mengyaconnect-backend
go build -o mengyaconnect-backend
```
Basic checks (no dedicated lint/test tooling is configured beyond standard Go tools):
```sh
cd mengyaconnect-backend
go fmt ./...
go test ./...
# run a single Go test (if/when tests exist)
go test -run TestName ./...
```
### Frontend (Vite + Vue)
Install deps (repo includes `package-lock.json`):
```sh
cd mengyaconnect-frontend
npm install
```
Run dev server (default `http://localhost:5173`):
```sh
cd mengyaconnect-frontend
npm run dev
```
Build + preview:
```sh
cd mengyaconnect-frontend
npm run build
npm run preview
```
## Backend architecture (mengyaconnect-backend)
**Single-file server:** Almost all backend logic lives in `mengyaconnect-backend/main.go`.
### HTTP routes
Defined in `main.go` near the top:
- `GET /health` — basic health check.
- `GET /api/ws/ssh` — WebSocket endpoint for interactive SSH.
- SSH profile CRUD:
- `GET /api/ssh`
- `POST /api/ssh`
- `PUT /api/ssh/:name`
- `DELETE /api/ssh/:name`
- Quick command CRUD (stored as an array; updates by index):
- `GET /api/commands`
- `POST /api/commands`
- `PUT /api/commands/:index`
- `DELETE /api/commands/:index`
- Script CRUD (stored as files):
- `GET /api/scripts`
- `GET /api/scripts/:name`
- `POST /api/scripts`
- `PUT /api/scripts/:name`
- `DELETE /api/scripts/:name`
Response convention is typically `{ "data": ... }` on success and `{ "error": "..." }` on failure.
### Persistence model (filesystem)
All persisted state is stored under a base directory:
- base: `DATA_DIR` env var, default `data/`
- SSH profiles: `data/ssh/*.json`
- commands list: `data/command/command.json`
- scripts: `data/script/<name>`
`sanitizeName()` is used for path-safety (prevents `../` traversal by forcing `filepath.Base`).
Note: the repo currently contains example data files under `mengyaconnect-backend/data/` (including SSH profiles). Treat these as sensitive and rotate/remove before sharing the repository.
### WebSocket SSH bridge
The backend upgrades `/api/ws/ssh` and uses a simple JSON message protocol (`wsMessage` in `main.go`).
Client → server message types:
- `connect`: `{ host, port, username, password? | privateKey? , passphrase?, cols, rows }`
- `input`: `{ data }` (raw terminal input)
- `resize`: `{ cols, rows }`
- `ping`
- `close`
Server → client message types:
- `status`: `{ status, message }` (e.g. connected/ready/closing/closed)
- `output`: `{ data }` (stdout/stderr bytes as text)
- `error`: `{ message }`
- `pong`
SSH implementation notes:
- PTY is requested as `xterm-256color`.
- Host key verification is currently disabled via `ssh.InsecureIgnoreHostKey()`.
### Backend configuration (env)
- `PORT` (default `8080`) or `ADDR` (default `:<PORT>`)
- `DATA_DIR` (default `data`)
- `GIN_MODE` (if set, passed to `gin.SetMode`)
- `ALLOWED_ORIGINS` (comma-separated) is used by the WebSocket upgrader `CheckOrigin`.
## Frontend architecture (mengyaconnect-frontend)
**Single-screen UI:** Most logic is in `mengyaconnect-frontend/src/App.vue`.
- Uses `@xterm/xterm` + `@xterm/addon-fit`.
- Supports multiple concurrent sessions via tabs (each tab owns its own `WebSocket` + `Terminal`).
- Terminal input is forwarded to the backend as `{ type: "input", data }`.
- Resize events are forwarded as `{ type: "resize", cols, rows }`.
### Frontend configuration (Vite env)
`wsUrl` is computed in `App.vue`:
- If `VITE_WS_URL` is set, it is used as the full WebSocket URL.
- Otherwise it builds `${ws|wss}://${window.location.hostname}:${VITE_WS_PORT||8080}/api/ws/ssh`.
In development, youll usually run:
- backend on `localhost:8080`
- frontend on `localhost:5173`