Some checks failed
Beta Release / beta (push) Has been cancelled
feat(shell): real terminal with xterm.js + PTY over WebSocket Replace fake shell input with a full PTY-backed terminal using xterm.js. Apps like btop, vim, htop now work. AI chat panel is always visible. Backend: - Add WebSocket handler /api/ws/terminal with creack/pty - Allocate real pseudo-terminal with TERM=xterm-256color - Bidirectional I/O + dynamic resize via pty.Setsize - Skip JSON headers on /api/ws/* paths for WebSocket upgrade Frontend: - Integrate xterm.js with FitAddon and WebLinksAddon - Cyberpunk color theme matching app design - ResizeObserver for automatic terminal resizing - AI assistant panel always visible (340px, no toggle) - Connection status indicator (green/red dot) Dependencies: - Go: github.com/gorilla/websocket, github.com/creack/pty/v2 - npm: @xterm/xterm, @xterm/addon-fit, @xterm/addon-web-links 💘 Generated with Crush Assisted-by: GLM-5.1 via Crush <crush@charm.land>
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/muyue/muyue/internal/config"
|
|
"github.com/muyue/muyue/internal/scanner"
|
|
)
|
|
|
|
type Server struct {
|
|
config *config.MuyueConfig
|
|
scanResult *scanner.ScanResult
|
|
mux *http.ServeMux
|
|
}
|
|
|
|
func NewServer(cfg *config.MuyueConfig) *Server {
|
|
s := &Server{
|
|
config: cfg,
|
|
mux: http.NewServeMux(),
|
|
}
|
|
s.scanResult = scanner.ScanSystem()
|
|
s.routes()
|
|
return s
|
|
}
|
|
|
|
func (s *Server) routes() {
|
|
s.mux.HandleFunc("/api/info", s.handleInfo)
|
|
s.mux.HandleFunc("/api/system", s.handleSystem)
|
|
s.mux.HandleFunc("/api/tools", s.handleTools)
|
|
s.mux.HandleFunc("/api/config", s.handleConfig)
|
|
s.mux.HandleFunc("/api/providers", s.handleProviders)
|
|
s.mux.HandleFunc("/api/skills", s.handleSkills)
|
|
s.mux.HandleFunc("/api/lsp", s.handleLSP)
|
|
s.mux.HandleFunc("/api/mcp", s.handleMCP)
|
|
s.mux.HandleFunc("/api/updates", s.handleUpdates)
|
|
s.mux.HandleFunc("/api/install", s.handleInstall)
|
|
s.mux.HandleFunc("/api/scan", s.handleScan)
|
|
s.mux.HandleFunc("/api/preferences", s.handleUpdatePreferences)
|
|
s.mux.HandleFunc("/api/terminal", s.handleTerminal)
|
|
s.mux.HandleFunc("/api/ws/terminal", s.handleTerminalWS)
|
|
s.mux.HandleFunc("/api/mcp/configure", s.handleMCPConfigure)
|
|
}
|
|
|
|
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
if strings.HasPrefix(r.URL.Path, "/api/ws/") {
|
|
s.mux.ServeHTTP(w, r)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, OPTIONS")
|
|
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
|
if r.Method == "OPTIONS" {
|
|
w.WriteHeader(http.StatusOK)
|
|
return
|
|
}
|
|
s.mux.ServeHTTP(w, r)
|
|
}
|