2026-02-08 15:17:12 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"log"
|
|
|
|
|
|
|
|
|
|
"github.com/host-uk/core/pkg/mcp/ide"
|
|
|
|
|
"github.com/host-uk/core/pkg/ws"
|
|
|
|
|
"github.com/wailsapp/wails/v3/pkg/application"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// IDEService provides core IDE bindings for the frontend.
|
|
|
|
|
type IDEService struct {
|
|
|
|
|
app *application.App
|
|
|
|
|
ideSub *ide.Subsystem
|
|
|
|
|
hub *ws.Hub
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewIDEService creates a new IDEService.
|
|
|
|
|
func NewIDEService(ideSub *ide.Subsystem, hub *ws.Hub) *IDEService {
|
|
|
|
|
return &IDEService{ideSub: ideSub, hub: hub}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ServiceName returns the service name for Wails.
|
|
|
|
|
func (s *IDEService) ServiceName() string { return "IDEService" }
|
|
|
|
|
|
|
|
|
|
// ServiceStartup is called when the Wails application starts.
|
feat(core-ide): add MCP bridge (SERVER) and Claude bridge (CLIENT)
SERVER bridge (mcp_bridge.go):
- HTTP server on :9877 exposing 24 MCP tools
- Window management: list, get, position, size, bounds, maximize,
minimize, restore, focus, visibility, title, fullscreen, create, close
- Webview: eval JS, navigate, list
- System: clipboard read/write, tray control
- Endpoints: /mcp, /mcp/tools, /mcp/call, /health, /ws, /claude
CLIENT bridge (claude_bridge.go):
- WebSocket relay between GUI clients and MCP core on :9876
- Auto-reconnect with backoff
- Bidirectional message forwarding (claude_message type)
Moved HTTP server from IDEService to MCPBridge for unified endpoint.
Co-Authored-By: Virgil <virgil@lethean.io>
2026-02-08 23:12:51 +00:00
|
|
|
func (s *IDEService) ServiceStartup(_ context.Context, _ application.ServiceOptions) error {
|
2026-02-08 15:17:12 +00:00
|
|
|
log.Println("IDEService started")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ServiceShutdown is called when the Wails application shuts down.
|
|
|
|
|
func (s *IDEService) ServiceShutdown() error {
|
|
|
|
|
log.Println("IDEService shutdown")
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ConnectionStatus represents the IDE bridge connection state.
|
|
|
|
|
type ConnectionStatus struct {
|
|
|
|
|
BridgeConnected bool `json:"bridgeConnected"`
|
|
|
|
|
LaravelURL string `json:"laravelUrl"`
|
|
|
|
|
WSClients int `json:"wsClients"`
|
|
|
|
|
WSChannels int `json:"wsChannels"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetConnectionStatus returns the current bridge and WebSocket status.
|
|
|
|
|
func (s *IDEService) GetConnectionStatus() ConnectionStatus {
|
|
|
|
|
connected := false
|
|
|
|
|
if s.ideSub.Bridge() != nil {
|
|
|
|
|
connected = s.ideSub.Bridge().Connected()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stats := s.hub.Stats()
|
|
|
|
|
return ConnectionStatus{
|
|
|
|
|
BridgeConnected: connected,
|
|
|
|
|
WSClients: stats.Clients,
|
|
|
|
|
WSChannels: stats.Channels,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DashboardData aggregates data for the dashboard view.
|
|
|
|
|
type DashboardData struct {
|
|
|
|
|
Connection ConnectionStatus `json:"connection"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// GetDashboard returns aggregated dashboard data.
|
|
|
|
|
func (s *IDEService) GetDashboard() DashboardData {
|
|
|
|
|
return DashboardData{
|
|
|
|
|
Connection: s.GetConnectionStatus(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ShowWindow shows a named window.
|
|
|
|
|
func (s *IDEService) ShowWindow(name string) {
|
|
|
|
|
if s.app == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if w, ok := s.app.Window.Get(name); ok {
|
|
|
|
|
w.Show()
|
|
|
|
|
w.Focus()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|