1package backend
2
3import (
4 "context"
5
6 tea "charm.land/bubbletea/v2"
7
8 mcptools "github.com/charmbracelet/crush/internal/agent/tools/mcp"
9 "github.com/charmbracelet/crush/internal/app"
10 "github.com/charmbracelet/crush/internal/config"
11 "github.com/charmbracelet/crush/internal/pubsub"
12)
13
14// SubscribeEvents returns a per-caller event channel for a workspace.
15// Each caller receives all events; multiple callers do not compete.
16func (b *Backend) SubscribeEvents(ctx context.Context, workspaceID string) (<-chan pubsub.Event[tea.Msg], error) {
17 ws, err := b.GetWorkspace(workspaceID)
18 if err != nil {
19 return nil, err
20 }
21
22 return ws.Events(ctx), nil
23}
24
25// GetLSPStates returns the state of all LSP clients.
26func (b *Backend) GetLSPStates(workspaceID string) (map[string]app.LSPClientInfo, error) {
27 _, err := b.GetWorkspace(workspaceID)
28 if err != nil {
29 return nil, err
30 }
31
32 return app.GetLSPStates(), nil
33}
34
35// GetLSPDiagnostics returns diagnostics for a specific LSP client in
36// the workspace.
37func (b *Backend) GetLSPDiagnostics(workspaceID, lspName string) (any, error) {
38 ws, err := b.GetWorkspace(workspaceID)
39 if err != nil {
40 return nil, err
41 }
42
43 for name, client := range ws.LSPManager.Clients().Seq2() {
44 if name == lspName {
45 return client.GetDiagnostics(), nil
46 }
47 }
48
49 return nil, ErrLSPClientNotFound
50}
51
52// GetWorkspaceConfig returns the workspace-level configuration.
53func (b *Backend) GetWorkspaceConfig(workspaceID string) (*config.Config, error) {
54 ws, err := b.GetWorkspace(workspaceID)
55 if err != nil {
56 return nil, err
57 }
58
59 return ws.Cfg.Config(), nil
60}
61
62// GetWorkspaceProviders returns the configured providers for a
63// workspace.
64func (b *Backend) GetWorkspaceProviders(workspaceID string) (any, error) {
65 ws, err := b.GetWorkspace(workspaceID)
66 if err != nil {
67 return nil, err
68 }
69
70 providers, _ := config.Providers(ws.Cfg.Config())
71 return providers, nil
72}
73
74// LSPStart starts an LSP server for the given path.
75func (b *Backend) LSPStart(ctx context.Context, workspaceID, path string) error {
76 ws, err := b.GetWorkspace(workspaceID)
77 if err != nil {
78 return err
79 }
80
81 ws.LSPManager.Start(ctx, path)
82 return nil
83}
84
85// LSPStopAll stops all LSP servers for a workspace.
86func (b *Backend) LSPStopAll(ctx context.Context, workspaceID string) error {
87 ws, err := b.GetWorkspace(workspaceID)
88 if err != nil {
89 return err
90 }
91
92 ws.LSPManager.StopAll(ctx)
93 return nil
94}
95
96// MCPGetStates returns the current state of all MCP clients.
97func (b *Backend) MCPGetStates(_ string) map[string]mcptools.ClientInfo {
98 return mcptools.GetStates()
99}
100
101// MCPRefreshPrompts refreshes prompts for a named MCP client.
102func (b *Backend) MCPRefreshPrompts(ctx context.Context, _ string, name string) {
103 mcptools.RefreshPrompts(ctx, name)
104}
105
106// MCPRefreshResources refreshes resources for a named MCP client.
107func (b *Backend) MCPRefreshResources(ctx context.Context, _ string, name string) {
108 mcptools.RefreshResources(ctx, name)
109}