4.4 KiB
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 bygolang.org/x/crypto/ssh - persists SSH profiles / quick commands / scripts to the local filesystem under
data/
- exposes a WebSocket SSH “bridge” (
mengyaconnect-frontend/— Vite + Vue 3 single-page UI usingxterm.jsto 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):
cd mengyaconnect-backend
go run .
Build a local binary:
cd mengyaconnect-backend
go build -o mengyaconnect-backend
Basic checks (no dedicated lint/test tooling is configured beyond standard Go tools):
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):
cd mengyaconnect-frontend
npm install
Run dev server (default http://localhost:5173):
cd mengyaconnect-frontend
npm run dev
Build + preview:
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/sshPOST /api/sshPUT /api/ssh/:nameDELETE /api/ssh/:name
- Quick command CRUD (stored as an array; updates by index):
GET /api/commandsPOST /api/commandsPUT /api/commands/:indexDELETE /api/commands/:index
- Script CRUD (stored as files):
GET /api/scriptsGET /api/scripts/:namePOST /api/scriptsPUT /api/scripts/:nameDELETE /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_DIRenv var, defaultdata/ - 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 }pingclose
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(default8080) orADDR(default:<PORT>)DATA_DIR(defaultdata)GIN_MODE(if set, passed togin.SetMode)ALLOWED_ORIGINS(comma-separated) is used by the WebSocket upgraderCheckOrigin.
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_URLis 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, you’ll usually run:
- backend on
localhost:8080 - frontend on
localhost:5173