Skip to main content
Glama
brummer_data_provider_impl.go4.85 kB
package tui import ( "sync/atomic" "github.com/standardbeagle/brummer/internal/aicoder" "github.com/standardbeagle/brummer/internal/logs" "github.com/standardbeagle/brummer/internal/proxy" ) // TUIDataProvider implements aicoder.BrummerDataProvider interface // It provides thread-safe access to TUI model data for PTY sessions type TUIDataProvider struct { model atomic.Value // stores *Model } // NewTUIDataProvider creates a new TUI data provider func NewTUIDataProvider(model *Model) aicoder.BrummerDataProvider { p := &TUIDataProvider{} p.model.Store(model) return p } // SetModel sets the model reference for the data provider func (p *TUIDataProvider) SetModel(model *Model) { p.model.Store(model) } // GetLastError returns the most recent error context func (p *TUIDataProvider) GetLastError() *logs.ErrorContext { model, ok := p.model.Load().(*Model) if !ok || model == nil || model.logStore == nil { return nil } contexts := model.logStore.GetErrorContexts() if len(contexts) > 0 { return &contexts[0] } return nil } // GetRecentLogs returns recent log entries func (p *TUIDataProvider) GetRecentLogs(count int) []logs.LogEntry { model, ok := p.model.Load().(*Model) if !ok || model == nil || model.logStore == nil { return []logs.LogEntry{} } allLogs := model.logStore.GetAll() if len(allLogs) <= count { return allLogs } // Return the most recent logs return allLogs[len(allLogs)-count:] } // GetTestFailures returns test failure information func (p *TUIDataProvider) GetTestFailures() interface{} { model, ok := p.model.Load().(*Model) if !ok || model == nil || model.logStore == nil { return nil } // Get test-related errors var testFailures []logs.ErrorContext contexts := model.logStore.GetErrorContexts() // Get last 10 test-related errors count := 0 for i := len(contexts) - 1; i >= 0 && count < 10; i-- { ctx := contexts[i] if ctx.Type == "test_failure" || ctx.Type == "test_error" { testFailures = append(testFailures, ctx) count++ } } return testFailures } // GetBuildOutput returns recent build output func (p *TUIDataProvider) GetBuildOutput() string { model, ok := p.model.Load().(*Model) if !ok || model == nil || model.logStore == nil { return "" } // Get logs from build-related processes var buildOutput string logs := model.logStore.GetAll() // Look for build-related logs in the last 50 entries start := len(logs) - 50 if start < 0 { start = 0 } for i := start; i < len(logs); i++ { log := logs[i] // Check if this is a build-related log if log.ProcessName == "build" || log.ProcessName == "compile" || log.ProcessName == "webpack" || log.ProcessName == "vite" || log.ProcessName == "go build" || log.ProcessName == "make" { buildOutput += log.Content + "\n" } } return buildOutput } // GetProcessInfo returns information about running processes func (p *TUIDataProvider) GetProcessInfo() interface{} { model, ok := p.model.Load().(*Model) if !ok || model == nil || model.processMgr == nil { return nil } processes := model.processMgr.GetAllProcesses() // Create a simplified process info structure type ProcessInfo struct { ID string Name string Status string PID int Started string Duration string } var processInfos []ProcessInfo for _, proc := range processes { // Use ProcessState for atomic access to multiple fields state := proc.GetStateAtomic() info := ProcessInfo{ ID: state.ID, Name: state.Name, Status: string(state.Status), PID: 0, // Process PID is not exposed Started: state.StartTime.Format("15:04:05"), } if state.EndTime != nil { info.Duration = state.EndTime.Sub(state.StartTime).String() } else { info.Duration = "Running" } processInfos = append(processInfos, info) } return processInfos } // GetDetectedURLs returns URLs detected in process logs func (p *TUIDataProvider) GetDetectedURLs() []logs.URLEntry { model, ok := p.model.Load().(*Model) if !ok || model == nil || model.logStore == nil { return []logs.URLEntry{} } return model.logStore.GetURLs() } // GetRecentProxyRequests returns recent proxy requests func (p *TUIDataProvider) GetRecentProxyRequests(count int) []*proxy.Request { model, ok := p.model.Load().(*Model) if !ok || model == nil || model.proxyServer == nil { return []*proxy.Request{} } allRequests := model.proxyServer.GetRequests() if len(allRequests) <= count { // Convert to pointer slice result := make([]*proxy.Request, len(allRequests)) for i := range allRequests { result[i] = &allRequests[i] } return result } // Return the most recent requests as pointers start := len(allRequests) - count result := make([]*proxy.Request, count) for i := 0; i < count; i++ { result[i] = &allRequests[start+i] } return result }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/standardbeagle/brummer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server