# 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, you’ll usually run:
- backend on `localhost:8080`
- frontend on `localhost:5173`
