From 8eb20fa690aac9be69e828063ab741d51c781cf6 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 11:09:49 -0400 Subject: [PATCH 01/25] fix(tui): adjust completions popup to fit within window width This commit modifies the completions popup to reposition itself if it exceeds the window width and moves it to the right edge of the window. --- internal/tui/components/completions/completions.go | 14 +++++++++++++- internal/tui/tui.go | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/internal/tui/components/completions/completions.go b/internal/tui/components/completions/completions.go index 5a6bcfe92e23f38c3f40c84770a0dcc9893e59d5..1b3a09bc6b1a5d49fb8b10a9e19261da50742892 100644 --- a/internal/tui/components/completions/completions.go +++ b/internal/tui/components/completions/completions.go @@ -40,6 +40,8 @@ type Completions interface { Query() string // Returns the current filter query KeyMap() KeyMap Position() (int, int) // Returns the X and Y position of the completions popup + Width() int + Height() int } type completionsCmp struct { @@ -54,6 +56,8 @@ type completionsCmp struct { query string // The current filter query } +const MaxCompletionsWidth = 80 // Maximum width for the completions popup + func New() Completions { completionsKeyMap := DefaultKeyMap() keyMap := list.DefaultKeyMap() @@ -92,7 +96,7 @@ func (c *completionsCmp) Init() tea.Cmd { func (c *completionsCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: - c.width = min(msg.Width-c.x, 80) + c.width = min(msg.Width-c.x, MaxCompletionsWidth) c.height = min(msg.Height-c.y, 15) return c, nil case tea.KeyPressMsg: @@ -201,3 +205,11 @@ func (c *completionsCmp) KeyMap() KeyMap { func (c *completionsCmp) Position() (int, int) { return c.x, c.y - c.height } + +func (c *completionsCmp) Width() int { + return c.width +} + +func (c *completionsCmp) Height() int { + return c.height +} diff --git a/internal/tui/tui.go b/internal/tui/tui.go index 0b10b74792c5cc6c91dc285d42a7d9a6736c2b90..811c18122687464d216e33f093aba60bbf5221c1 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -116,6 +116,16 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case completions.OpenCompletionsMsg, completions.FilterCompletionsMsg, completions.CloseCompletionsMsg: u, completionCmd := a.completions.Update(msg) a.completions = u.(completions.Completions) + switch msg := msg.(type) { + case completions.OpenCompletionsMsg: + x, _ := a.completions.Position() + if a.completions.Width()+x >= a.wWidth { + // Adjust X position to fit in the window. + msg.X = a.wWidth - a.completions.Width() - 1 + u, completionCmd = a.completions.Update(msg) + a.completions = u.(completions.Completions) + } + } return a, completionCmd // Dialog messages From 40d53fe4e3a0e0fc6ecdbba1b164bc5cb1f524cf Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 13:46:32 -0400 Subject: [PATCH 02/25] fix(tui): permissions: ensure content viewport has a minimum height --- internal/tui/components/dialogs/permissions/permissions.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/internal/tui/components/dialogs/permissions/permissions.go b/internal/tui/components/dialogs/permissions/permissions.go index 0bbaa034ed2357cc4643ad92c0a680bb01cf61ff..98311fc35d05875b98e2ec239a68ce3961efc57e 100644 --- a/internal/tui/components/dialogs/permissions/permissions.go +++ b/internal/tui/components/dialogs/permissions/permissions.go @@ -445,7 +445,11 @@ func (p *permissionDialogCmp) render() string { contentFinal := p.getOrGenerateContent() // Always set viewport content (the caching is handled in getOrGenerateContent) - contentHeight := min(p.height-9, lipgloss.Height(contentFinal)) + const minContentHeight = 9 + contentHeight := min( + max(minContentHeight, p.height-minContentHeight), + lipgloss.Height(contentFinal), + ) p.contentViewPort.SetHeight(contentHeight) p.contentViewPort.SetContent(contentFinal) From a29ec05c9a91d15ca40b64540da128cbc74bc28c Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 14:14:21 -0400 Subject: [PATCH 03/25] fix(tui): permissions: properly pad command block This change ensures the bash command block has 1 vertical padding and 2 horizontal paddings, improving the visual layout in the permissions dialog. --- .../tui/components/dialogs/permissions/permissions.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/tui/components/dialogs/permissions/permissions.go b/internal/tui/components/dialogs/permissions/permissions.go index 0bbaa034ed2357cc4643ad92c0a680bb01cf61ff..356c6ec8d5ad8a7ef8138251b0ab6887eb6583a1 100644 --- a/internal/tui/components/dialogs/permissions/permissions.go +++ b/internal/tui/components/dialogs/permissions/permissions.go @@ -16,7 +16,6 @@ import ( "github.com/charmbracelet/crush/internal/tui/styles" "github.com/charmbracelet/crush/internal/tui/util" "github.com/charmbracelet/lipgloss/v2" - "github.com/charmbracelet/x/ansi" ) type PermissionAction string @@ -317,18 +316,14 @@ func (p *permissionDialogCmp) generateBashContent() string { content := pr.Command t := styles.CurrentTheme() content = strings.TrimSpace(content) - content = "\n" + content + "\n" lines := strings.Split(content, "\n") width := p.width - 4 var out []string for _, ln := range lines { - ln = " " + ln // left padding - if len(ln) > width { - ln = ansi.Truncate(ln, width, "…") - } out = append(out, t.S().Muted. Width(width). + Padding(0, 2). Foreground(t.FgBase). Background(t.BgSubtle). Render(ln)) @@ -338,6 +333,7 @@ func (p *permissionDialogCmp) generateBashContent() string { renderedContent := strings.Join(out, "\n") finalContent := baseStyle. Width(p.contentViewPort.Width()). + Padding(1, 0). Render(renderedContent) return finalContent From 6dd3b09d897536734eee297d108c58b059b0fe08 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 15 Jul 2025 16:07:41 -0300 Subject: [PATCH 04/25] refactor: use sync primitives in GetMcpTools Signed-off-by: Carlos Alexandro Becker --- cmd/root.go | 17 ------ internal/llm/agent/agent.go | 2 +- internal/llm/agent/mcp-tools.go | 103 +++++++++++++++++++------------- 3 files changed, 63 insertions(+), 59 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index ad558173c6eb1dd1bf4fdda30524ca7b04793ff5..fe17181c110c68a032495ee806c91651daf3631e 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -92,9 +92,6 @@ to assist developers in writing, debugging, and understanding code directly from } defer app.Shutdown() - // Initialize MCP tools early for both modes - initMCPTools(ctx, app, cfg) - prompt, err = maybePrependStdin(prompt) if err != nil { slog.Error(fmt.Sprintf("Failed to read from stdin: %v", err)) @@ -126,20 +123,6 @@ to assist developers in writing, debugging, and understanding code directly from }, } -func initMCPTools(ctx context.Context, app *app.App, cfg *config.Config) { - go func() { - defer log.RecoverPanic("MCP-goroutine", nil) - - // Create a context with timeout for the initial MCP tools fetch - ctxWithTimeout, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() - - // Set this up once with proper error handling - agent.GetMcpTools(ctxWithTimeout, app.Permissions, cfg) - slog.Info("MCP message handling goroutine exiting") - }() -} - func Execute() { if err := fang.Execute( context.Background(), diff --git a/internal/llm/agent/agent.go b/internal/llm/agent/agent.go index 7cd01e91900a6b0a2720a092e6740ab7d989fb6d..0cc8b71029191a7e05fe1e77b437066d3cdd40c5 100644 --- a/internal/llm/agent/agent.go +++ b/internal/llm/agent/agent.go @@ -94,7 +94,7 @@ func NewAgent( ) (Service, error) { ctx := context.Background() cfg := config.Get() - otherTools := GetMcpTools(ctx, permissions, cfg) + otherTools := GetMCPTools(ctx, permissions, cfg) if len(lspClients) > 0 { otherTools = append(otherTools, tools.NewDiagnosticsTool(lspClients)) } diff --git a/internal/llm/agent/mcp-tools.go b/internal/llm/agent/mcp-tools.go index d8610b557896272d94c76c608b9bc00347655be4..4ed4c023719642724c8dd49cbe3293376e3f3c57 100644 --- a/internal/llm/agent/mcp-tools.go +++ b/internal/llm/agent/mcp-tools.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "log/slog" + "sync" "github.com/charmbracelet/crush/internal/config" "github.com/charmbracelet/crush/internal/llm/tools" @@ -154,8 +155,6 @@ func NewMcpTool(name string, tool mcp.Tool, permissions permission.Service, mcpC } } -var mcpTools []tools.BaseTool - func getTools(ctx context.Context, name string, m config.MCPConfig, permissions permission.Service, c MCPClient, workingDir string) []tools.BaseTool { var stdioTools []tools.BaseTool initRequest := mcp.InitializeRequest{} @@ -183,50 +182,72 @@ func getTools(ctx context.Context, name string, m config.MCPConfig, permissions return stdioTools } -func GetMcpTools(ctx context.Context, permissions permission.Service, cfg *config.Config) []tools.BaseTool { - if len(mcpTools) > 0 { - return mcpTools - } +var ( + mcpToolsOnce sync.Once + mcpTools []tools.BaseTool +) + +func GetMCPTools(ctx context.Context, permissions permission.Service, cfg *config.Config) []tools.BaseTool { + mcpToolsOnce.Do(func() { + mcpTools = doGetMCPTools(ctx, permissions, cfg) + }) + return mcpTools +} + +func doGetMCPTools(ctx context.Context, permissions permission.Service, cfg *config.Config) []tools.BaseTool { + var mu sync.Mutex + var wg sync.WaitGroup + var result []tools.BaseTool for name, m := range cfg.MCP { if m.Disabled { slog.Debug("skipping disabled mcp", "name", name) continue } - switch m.Type { - case config.MCPStdio: - c, err := client.NewStdioMCPClient( - m.Command, - m.Env, - m.Args..., - ) - if err != nil { - slog.Error("error creating mcp client", "error", err) - continue + wg.Add(1) + go func(name string, m config.MCPConfig) { + defer wg.Done() + switch m.Type { + case config.MCPStdio: + c, err := client.NewStdioMCPClient( + m.Command, + m.Env, + m.Args..., + ) + if err != nil { + slog.Error("error creating mcp client", "error", err) + return + } + + mu.Lock() + result = append(result, getTools(ctx, name, m, permissions, c, cfg.WorkingDir())...) + mu.Unlock() + case config.MCPHttp: + c, err := client.NewStreamableHttpClient( + m.URL, + transport.WithHTTPHeaders(m.Headers), + ) + if err != nil { + slog.Error("error creating mcp client", "error", err) + return + } + mu.Lock() + result = append(result, getTools(ctx, name, m, permissions, c, cfg.WorkingDir())...) + mu.Unlock() + case config.MCPSse: + c, err := client.NewSSEMCPClient( + m.URL, + client.WithHeaders(m.Headers), + ) + if err != nil { + slog.Error("error creating mcp client", "error", err) + return + } + mu.Lock() + result = append(result, getTools(ctx, name, m, permissions, c, cfg.WorkingDir())...) + mu.Unlock() } - - mcpTools = append(mcpTools, getTools(ctx, name, m, permissions, c, cfg.WorkingDir())...) - case config.MCPHttp: - c, err := client.NewStreamableHttpClient( - m.URL, - transport.WithHTTPHeaders(m.Headers), - ) - if err != nil { - slog.Error("error creating mcp client", "error", err) - continue - } - mcpTools = append(mcpTools, getTools(ctx, name, m, permissions, c, cfg.WorkingDir())...) - case config.MCPSse: - c, err := client.NewSSEMCPClient( - m.URL, - client.WithHeaders(m.Headers), - ) - if err != nil { - slog.Error("error creating mcp client", "error", err) - continue - } - mcpTools = append(mcpTools, getTools(ctx, name, m, permissions, c, cfg.WorkingDir())...) - } + }(name, m) } - - return mcpTools + wg.Wait() + return result } From 0427603a44382ad2ab8387e3c172697d3afe40e2 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 15 Jul 2025 16:41:36 -0300 Subject: [PATCH 05/25] fix: imports Signed-off-by: Carlos Alexandro Becker --- cmd/root.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index fe17181c110c68a032495ee806c91651daf3631e..b3ea36c8a976face0bb29c3d77e0d2c82dfb1399 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -6,14 +6,11 @@ import ( "io" "log/slog" "os" - "time" tea "github.com/charmbracelet/bubbletea/v2" "github.com/charmbracelet/crush/internal/app" "github.com/charmbracelet/crush/internal/config" "github.com/charmbracelet/crush/internal/db" - "github.com/charmbracelet/crush/internal/llm/agent" - "github.com/charmbracelet/crush/internal/log" "github.com/charmbracelet/crush/internal/tui" "github.com/charmbracelet/crush/internal/version" "github.com/charmbracelet/fang" From 483303de5b07c10ec53d87fa30254393a78037ca Mon Sep 17 00:00:00 2001 From: Christian Rocha Date: Tue, 15 Jul 2025 16:28:24 -0400 Subject: [PATCH 06/25] docs(readme): add MCP info --- README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/README.md b/README.md index f69a451eaba21f92da001f075ad630fa43ff3aba..7071ed94e9ec656ea06652c421e6f2441962bf58 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,22 @@ Crush can use LSPs for additional context to help inform its decisions, just lik } ``` +### MCPs + +Crush can also use MCPs for additional context. Add LSPs to the config like so: + +``` +{ + "mcp": { + "context7": { + "command": "", + "url": "https://mcp.context7.com/mcp", + "type": "http" + } + }, +} +``` + ### OpenAI-Compatible APIs Crush supports all OpenAI-compatible APIs. Here's an example configuration for Deepseek, which uses an OpenAI-compatible API. Don't forget to set `DEEPSEEK_API_KEY` in your environment. From 806d21ec7132d9e63cb7896c8cc63b2224b17677 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 16:31:40 -0400 Subject: [PATCH 07/25] fix(tui): chat: fix compact mode details toggle If the details are open, then the window gets wider, the sidebar state doesn't get reset. This commit fixes the issue by ensuring that the sidebar is reset when the compact mode is toggled off. --- internal/tui/page/chat/chat.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/internal/tui/page/chat/chat.go b/internal/tui/page/chat/chat.go index be7c0f2658202ea59e70778df1785b98310bc458..a76c3b2e9f0f81f862da221d4908d2e932380295 100644 --- a/internal/tui/page/chat/chat.go +++ b/internal/tui/page/chat/chat.go @@ -273,7 +273,7 @@ func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return p, p.cancel() } case key.Matches(msg, p.keyMap.Details): - p.showDetails() + p.toggleDetails() return p, nil } @@ -415,12 +415,9 @@ func (p *chatPage) setCompactMode(compact bool) { } p.compact = compact if compact { - p.compact = true p.sidebar.SetCompactMode(true) } else { - p.compact = false - p.showingDetails = false - p.sidebar.SetCompactMode(false) + p.setShowDetails(false) } } @@ -525,12 +522,19 @@ func (p *chatPage) cancel() tea.Cmd { return cancelTimerCmd() } -func (p *chatPage) showDetails() { +func (p *chatPage) setShowDetails(show bool) { + p.showingDetails = show + p.header.SetDetailsOpen(p.showingDetails) + if !p.compact { + p.sidebar.SetCompactMode(false) + } +} + +func (p *chatPage) toggleDetails() { if p.session.ID == "" || !p.compact { return } - p.showingDetails = !p.showingDetails - p.header.SetDetailsOpen(p.showingDetails) + p.setShowDetails(!p.showingDetails) } func (p *chatPage) sendMessage(text string, attachments []message.Attachment) tea.Cmd { From ccd83f755a3f7df02683844c9a5d49b69ae4396d Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 17:34:38 -0400 Subject: [PATCH 08/25] Update internal/tui/components/dialogs/permissions/permissions.go Co-authored-by: Christian Rocha --- internal/tui/components/dialogs/permissions/permissions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/tui/components/dialogs/permissions/permissions.go b/internal/tui/components/dialogs/permissions/permissions.go index 356c6ec8d5ad8a7ef8138251b0ab6887eb6583a1..6f346d9a339cb82d6cf0ffcef5703804af39ed81 100644 --- a/internal/tui/components/dialogs/permissions/permissions.go +++ b/internal/tui/components/dialogs/permissions/permissions.go @@ -323,7 +323,7 @@ func (p *permissionDialogCmp) generateBashContent() string { for _, ln := range lines { out = append(out, t.S().Muted. Width(width). - Padding(0, 2). + Padding(0, 3). Foreground(t.FgBase). Background(t.BgSubtle). Render(ln)) From a203cbe2a0b7d9659089259019970e257b3b8256 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 16:38:48 -0400 Subject: [PATCH 09/25] fix(tui): chat: properly align and pad the version text --- internal/tui/page/chat/chat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/tui/page/chat/chat.go b/internal/tui/page/chat/chat.go index bd54e489d3be17512a9a50369f0dbcc1df3f415a..cb6b87f740c38a0f860e633f9bcbbfee0e25e13a 100644 --- a/internal/tui/page/chat/chat.go +++ b/internal/tui/page/chat/chat.go @@ -382,7 +382,7 @@ func (p *chatPage) View() string { Width(p.detailsWidth). Border(lipgloss.RoundedBorder()). BorderForeground(t.BorderFocus) - version := t.S().Subtle.Width(p.detailsWidth - 2).AlignHorizontal(lipgloss.Right).Render(version.Version) + version := t.S().Subtle.Width(p.detailsWidth - 4).AlignHorizontal(lipgloss.Right).Render(version.Version) details := style.Render( lipgloss.JoinVertical( lipgloss.Left, From 46e31c57c3c66eae085ec5b5cd45d1953de98d83 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 16:41:46 -0400 Subject: [PATCH 10/25] fix(tui): chat: change version text color --- internal/tui/page/chat/chat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/tui/page/chat/chat.go b/internal/tui/page/chat/chat.go index cb6b87f740c38a0f860e633f9bcbbfee0e25e13a..2c7bf17fcb2c78e43e0d130696474379985ac99d 100644 --- a/internal/tui/page/chat/chat.go +++ b/internal/tui/page/chat/chat.go @@ -382,7 +382,7 @@ func (p *chatPage) View() string { Width(p.detailsWidth). Border(lipgloss.RoundedBorder()). BorderForeground(t.BorderFocus) - version := t.S().Subtle.Width(p.detailsWidth - 4).AlignHorizontal(lipgloss.Right).Render(version.Version) + version := t.S().Base.Foreground(t.Border).Width(p.detailsWidth - 4).AlignHorizontal(lipgloss.Right).Render(version.Version) details := style.Render( lipgloss.JoinVertical( lipgloss.Left, From 6805b3494b733479235c801c8b54ed2f6873ab93 Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Wed, 16 Jul 2025 13:55:20 +0200 Subject: [PATCH 11/25] chore: some mcp improvements --- internal/config/config.go | 45 ++++++++++++++++--- internal/llm/agent/mcp-tools.go | 20 +++++---- .../dialogs/permissions/permissions.go | 25 ++++++++--- 3 files changed, 69 insertions(+), 21 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 354005ac42f8fb1d179442353b819e871cc61259..d63a34f73d5210c2542be8a598ef38cb06339bd9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,8 +6,10 @@ import ( "slices" "strings" + "github.com/charmbracelet/crush/internal/env" "github.com/charmbracelet/crush/internal/fur/provider" "github.com/tidwall/sjson" + "golang.org/x/exp/slog" ) const ( @@ -90,12 +92,12 @@ const ( ) type MCPConfig struct { - Command string `json:"command,omitempty" ` - Env []string `json:"env,omitempty"` - Args []string `json:"args,omitempty"` - Type MCPType `json:"type"` - URL string `json:"url,omitempty"` - Disabled bool `json:"disabled,omitempty"` + Command string `json:"command,omitempty" ` + Env map[string]string `json:"env,omitempty"` + Args []string `json:"args,omitempty"` + Type MCPType `json:"type"` + URL string `json:"url,omitempty"` + Disabled bool `json:"disabled,omitempty"` // TODO: maybe make it possible to get the value from the env Headers map[string]string `json:"headers,omitempty"` @@ -165,6 +167,37 @@ func (l LSPs) Sorted() []LSP { return sorted } +func (m MCPConfig) ResolvedEnv() []string { + resolver := NewShellVariableResolver(env.New()) + for e, v := range m.Env { + var err error + m.Env[e], err = resolver.ResolveValue(v) + if err != nil { + slog.Error("error resolving environment variable", "error", err, "variable", e, "value", v) + continue + } + } + + env := make([]string, 0, len(m.Env)) + for k, v := range m.Env { + env = append(env, fmt.Sprintf("%s=%s", k, v)) + } + return env +} + +func (m MCPConfig) ResolvedHeaders() map[string]string { + resolver := NewShellVariableResolver(env.New()) + for e, v := range m.Headers { + var err error + m.Headers[e], err = resolver.ResolveValue(v) + if err != nil { + slog.Error("error resolving header variable", "error", err, "variable", e, "value", v) + continue + } + } + return m.Headers +} + type Agent struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` diff --git a/internal/llm/agent/mcp-tools.go b/internal/llm/agent/mcp-tools.go index d8610b557896272d94c76c608b9bc00347655be4..c655e01815c45959247ba0f02241232346dc166f 100644 --- a/internal/llm/agent/mcp-tools.go +++ b/internal/llm/agent/mcp-tools.go @@ -36,7 +36,7 @@ type MCPClient interface { } func (b *mcpTool) Name() string { - return fmt.Sprintf("%s_%s", b.mcpName, b.tool.Name) + return fmt.Sprintf("mcp_%s_%s", b.mcpName, b.tool.Name) } func (b *mcpTool) Info() tools.ToolInfo { @@ -45,7 +45,7 @@ func (b *mcpTool) Info() tools.ToolInfo { required = make([]string, 0) } return tools.ToolInfo{ - Name: fmt.Sprintf("%s_%s", b.mcpName, b.tool.Name), + Name: fmt.Sprintf("mcp_%s_%s", b.mcpName, b.tool.Name), Description: b.tool.Description, Parameters: b.tool.InputSchema.Properties, Required: required, @@ -107,14 +107,14 @@ func (b *mcpTool) Run(ctx context.Context, params tools.ToolCall) (tools.ToolRes }, ) if !p { - return tools.NewTextErrorResponse("permission denied"), nil + return tools.ToolResponse{}, permission.ErrorPermissionDenied } switch b.mcpConfig.Type { case config.MCPStdio: c, err := client.NewStdioMCPClient( b.mcpConfig.Command, - b.mcpConfig.Env, + b.mcpConfig.ResolvedEnv(), b.mcpConfig.Args..., ) if err != nil { @@ -124,7 +124,7 @@ func (b *mcpTool) Run(ctx context.Context, params tools.ToolCall) (tools.ToolRes case config.MCPHttp: c, err := client.NewStreamableHttpClient( b.mcpConfig.URL, - transport.WithHTTPHeaders(b.mcpConfig.Headers), + transport.WithHTTPHeaders(b.mcpConfig.ResolvedHeaders()), ) if err != nil { return tools.NewTextErrorResponse(err.Error()), nil @@ -133,7 +133,7 @@ func (b *mcpTool) Run(ctx context.Context, params tools.ToolCall) (tools.ToolRes case config.MCPSse: c, err := client.NewSSEMCPClient( b.mcpConfig.URL, - client.WithHeaders(b.mcpConfig.Headers), + client.WithHeaders(b.mcpConfig.ResolvedHeaders()), ) if err != nil { return tools.NewTextErrorResponse(err.Error()), nil @@ -192,11 +192,12 @@ func GetMcpTools(ctx context.Context, permissions permission.Service, cfg *confi slog.Debug("skipping disabled mcp", "name", name) continue } + switch m.Type { case config.MCPStdio: c, err := client.NewStdioMCPClient( m.Command, - m.Env, + m.ResolvedEnv(), m.Args..., ) if err != nil { @@ -206,9 +207,10 @@ func GetMcpTools(ctx context.Context, permissions permission.Service, cfg *confi mcpTools = append(mcpTools, getTools(ctx, name, m, permissions, c, cfg.WorkingDir())...) case config.MCPHttp: + slog.Info("creating mcp client", "name", name, "url", m.URL, "headers", m.ResolvedHeaders()) c, err := client.NewStreamableHttpClient( m.URL, - transport.WithHTTPHeaders(m.Headers), + transport.WithHTTPHeaders(m.ResolvedHeaders()), ) if err != nil { slog.Error("error creating mcp client", "error", err) @@ -218,7 +220,7 @@ func GetMcpTools(ctx context.Context, permissions permission.Service, cfg *confi case config.MCPSse: c, err := client.NewSSEMCPClient( m.URL, - client.WithHeaders(m.Headers), + client.WithHeaders(m.ResolvedHeaders()), ) if err != nil { slog.Error("error creating mcp client", "error", err) diff --git a/internal/tui/components/dialogs/permissions/permissions.go b/internal/tui/components/dialogs/permissions/permissions.go index 0bbaa034ed2357cc4643ad92c0a680bb01cf61ff..fa08885e7db516f11248430e74046e978dd00e88 100644 --- a/internal/tui/components/dialogs/permissions/permissions.go +++ b/internal/tui/components/dialogs/permissions/permissions.go @@ -407,13 +407,26 @@ func (p *permissionDialogCmp) generateDefaultContent() string { content := p.permission.Description - // Use the cache for markdown rendering - renderedContent := p.GetOrSetMarkdown(p.permission.ID, func() (string, error) { - r := styles.GetMarkdownRenderer(p.width - 4) - s, err := r.Render(content) - return s, err - }) + content = strings.TrimSpace(content) + content = "\n" + content + "\n" + lines := strings.Split(content, "\n") + + width := p.width - 4 + var out []string + for _, ln := range lines { + ln = " " + ln // left padding + if len(ln) > width { + ln = ansi.Truncate(ln, width, "…") + } + out = append(out, t.S().Muted. + Width(width). + Foreground(t.FgBase). + Background(t.BgSubtle). + Render(ln)) + } + // Use the cache for markdown rendering + renderedContent := strings.Join(out, "\n") finalContent := baseStyle. Width(p.contentViewPort.Width()). Render(renderedContent) From d66797d6da0f49eb36894fe9deeed3a79d75c670 Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Wed, 16 Jul 2025 13:56:27 +0200 Subject: [PATCH 12/25] chore: add github mcp --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7071ed94e9ec656ea06652c421e6f2441962bf58..91301808b695c7fd40724b04a764cd7e8c1f587f 100644 --- a/README.md +++ b/README.md @@ -82,15 +82,22 @@ Crush can use LSPs for additional context to help inform its decisions, just lik Crush can also use MCPs for additional context. Add LSPs to the config like so: -``` +```json { "mcp": { "context7": { "command": "", "url": "https://mcp.context7.com/mcp", "type": "http" + }, + "github": { + "type": "http", + "url": "https://api.githubcopilot.com/mcp/", + "headers": { + "Authorization": "$(echo Bearer $GH_MCP_TOKEN)" + } } - }, + } } ``` From 972ab6e32af27e4efa3b5951ef0fa9cd7365adc3 Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Wed, 16 Jul 2025 14:09:28 +0200 Subject: [PATCH 13/25] chore: remove unnecessary config --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 91301808b695c7fd40724b04a764cd7e8c1f587f..7f428d31ed38ba437d2df4edb6747452d9624e2b 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,6 @@ Crush can also use MCPs for additional context. Add LSPs to the config like so: { "mcp": { "context7": { - "command": "", "url": "https://mcp.context7.com/mcp", "type": "http" }, From 849572d4d0b50f8dee0d75ef5a3198d0b7119606 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 16 Jul 2025 09:40:37 -0400 Subject: [PATCH 14/25] fix(tui): completions: don't export variable --- internal/tui/components/completions/completions.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/tui/components/completions/completions.go b/internal/tui/components/completions/completions.go index 1b3a09bc6b1a5d49fb8b10a9e19261da50742892..22e725596daace22153e9d26994b3218d2434959 100644 --- a/internal/tui/components/completions/completions.go +++ b/internal/tui/components/completions/completions.go @@ -56,7 +56,7 @@ type completionsCmp struct { query string // The current filter query } -const MaxCompletionsWidth = 80 // Maximum width for the completions popup +const maxCompletionsWidth = 80 // Maximum width for the completions popup func New() Completions { completionsKeyMap := DefaultKeyMap() @@ -96,7 +96,7 @@ func (c *completionsCmp) Init() tea.Cmd { func (c *completionsCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: - c.width = min(msg.Width-c.x, MaxCompletionsWidth) + c.width = min(msg.Width-c.x, maxCompletionsWidth) c.height = min(msg.Height-c.y, 15) return c, nil case tea.KeyPressMsg: From 7b219b166b14f7171926f29fd6bbc8aa2aad32e2 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 14:20:44 -0400 Subject: [PATCH 15/25] fix(tui): permissions: set a maximum width for the dialog The dialog won't exceed 160 characters in width, ensuring it fits well within a wide terminal window. --- internal/tui/components/dialogs/permissions/permissions.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/tui/components/dialogs/permissions/permissions.go b/internal/tui/components/dialogs/permissions/permissions.go index 4370d99e3fbf5490beb67422c9f102195482948c..280279060ef570181dcf67f5ef875212e83ebe23 100644 --- a/internal/tui/components/dialogs/permissions/permissions.go +++ b/internal/tui/components/dialogs/permissions/permissions.go @@ -529,6 +529,9 @@ func (p *permissionDialogCmp) SetSize() tea.Cmd { // Default to diff split mode when dialog is wide enough. p.defaultDiffSplitMode = p.width >= 140 + // Set a maximum width for the dialog + p.width = min(p.width, 180) + // Mark content as dirty if size changed if oldWidth != p.width || oldHeight != p.height { p.contentDirty = true From 199cc96d72e93ae25d4a5369f47836c7d13f12a4 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 16 Jul 2025 10:15:02 -0400 Subject: [PATCH 16/25] chore: bump ultraviolet to latest main --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index d510a774a03c27ceca623400257228763cc2e9a1..3a3c61dc11d7f60e6af41b55a5b0a6be96523547 100644 --- a/go.mod +++ b/go.mod @@ -75,7 +75,7 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/charmbracelet/colorprofile v0.3.1 // indirect - github.com/charmbracelet/ultraviolet v0.0.0-20250708152637-0fe0235c8db9 // indirect + github.com/charmbracelet/ultraviolet v0.0.0-20250716141307-2fae2b322afb // indirect github.com/charmbracelet/x/cellbuf v0.0.14-0.20250516160309-24eee56f89fa // indirect github.com/charmbracelet/x/exp/slice v0.0.0-20250611152503-f53cdd7e01ef github.com/charmbracelet/x/term v0.2.1 @@ -133,8 +133,8 @@ require ( golang.org/x/crypto v0.37.0 // indirect golang.org/x/image v0.26.0 // indirect golang.org/x/net v0.39.0 // indirect - golang.org/x/sync v0.15.0 // indirect - golang.org/x/sys v0.33.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.34.0 // indirect golang.org/x/term v0.31.0 // indirect golang.org/x/text v0.24.0 // indirect google.golang.org/genai v1.3.0 diff --git a/go.sum b/go.sum index d7004401154b86ce0658162c06bfc610a0c77126..07fabb9e21563d1c5bcd9c875a395f3ebd392f56 100644 --- a/go.sum +++ b/go.sum @@ -82,8 +82,8 @@ github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb/go.mod h1:wEc/TRrTAIDJYjVCg3+y8WeKaN+F88gpYfGbUuP6W3A= github.com/charmbracelet/log/v2 v2.0.0-20250226163916-c379e29ff706 h1:WkwO6Ks3mSIGnGuSdKl9qDSyfbYK50z2wc2gGMggegE= github.com/charmbracelet/log/v2 v2.0.0-20250226163916-c379e29ff706/go.mod h1:mjJGp00cxcfvD5xdCa+bso251Jt4owrQvuimJtVmEmM= -github.com/charmbracelet/ultraviolet v0.0.0-20250708152637-0fe0235c8db9 h1:+LLFCLxtb/sHegwY3zYdFAbaOgI/I9pv/pxdUlI1Q9s= -github.com/charmbracelet/ultraviolet v0.0.0-20250708152637-0fe0235c8db9/go.mod h1:/O+B00+dYG6lqRAWIaNxSvywnDrIH6dmLYQAsH0LRTg= +github.com/charmbracelet/ultraviolet v0.0.0-20250716141307-2fae2b322afb h1:fMyaSpuEyPP+uuTu98Wx2S/7OY52uhjF+kYfM5w7x+s= +github.com/charmbracelet/ultraviolet v0.0.0-20250716141307-2fae2b322afb/go.mod h1:XrrgNFfXLrFAyd9DUmrqVc3yQFVv8Uk+okj4PsNNzpc= github.com/charmbracelet/x/ansi v0.9.3 h1:BXt5DHS/MKF+LjuK4huWrC6NCvHtexww7dMayh6GXd0= github.com/charmbracelet/x/ansi v0.9.3/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= github.com/charmbracelet/x/cellbuf v0.0.14-0.20250516160309-24eee56f89fa h1:lphz0Z3rsiOtMYiz8axkT24i9yFiueDhJbzyNUADmME= @@ -309,8 +309,8 @@ golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= -golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -325,8 +325,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= From f4ca3bd642ceec787c70b962aba948060646a8d1 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 16 Jul 2025 10:15:16 -0400 Subject: [PATCH 17/25] chore: go mod vendor --- .../aymanbagabas/go-udiff/myers/diff.go | 246 ------------------ .../charmbracelet/ultraviolet/README.md | 2 + .../charmbracelet/ultraviolet/input.go | 28 ++ .../charmbracelet/ultraviolet/terminal.go | 89 ++++--- .../ultraviolet/terminal_reader.go | 14 +- .../charmbracelet/ultraviolet/winch_unix.go | 27 +- vendor/golang.org/x/sync/errgroup/errgroup.go | 118 +++------ vendor/golang.org/x/sys/unix/zerrors_linux.go | 25 +- .../x/sys/unix/zerrors_linux_386.go | 1 + .../x/sys/unix/zerrors_linux_amd64.go | 1 + .../x/sys/unix/zerrors_linux_arm.go | 1 + .../x/sys/unix/zerrors_linux_arm64.go | 1 + .../x/sys/unix/zerrors_linux_loong64.go | 1 + .../x/sys/unix/zerrors_linux_mips.go | 1 + .../x/sys/unix/zerrors_linux_mips64.go | 1 + .../x/sys/unix/zerrors_linux_mips64le.go | 1 + .../x/sys/unix/zerrors_linux_mipsle.go | 1 + .../x/sys/unix/zerrors_linux_ppc.go | 1 + .../x/sys/unix/zerrors_linux_ppc64.go | 1 + .../x/sys/unix/zerrors_linux_ppc64le.go | 1 + .../x/sys/unix/zerrors_linux_riscv64.go | 1 + .../x/sys/unix/zerrors_linux_s390x.go | 1 + .../x/sys/unix/zerrors_linux_sparc64.go | 1 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 108 +++++++- .../golang.org/x/sys/unix/ztypes_linux_386.go | 16 ++ .../x/sys/unix/ztypes_linux_amd64.go | 16 ++ .../golang.org/x/sys/unix/ztypes_linux_arm.go | 16 ++ .../x/sys/unix/ztypes_linux_arm64.go | 16 ++ .../x/sys/unix/ztypes_linux_loong64.go | 16 ++ .../x/sys/unix/ztypes_linux_mips.go | 16 ++ .../x/sys/unix/ztypes_linux_mips64.go | 16 ++ .../x/sys/unix/ztypes_linux_mips64le.go | 16 ++ .../x/sys/unix/ztypes_linux_mipsle.go | 16 ++ .../golang.org/x/sys/unix/ztypes_linux_ppc.go | 16 ++ .../x/sys/unix/ztypes_linux_ppc64.go | 16 ++ .../x/sys/unix/ztypes_linux_ppc64le.go | 16 ++ .../x/sys/unix/ztypes_linux_riscv64.go | 16 ++ .../x/sys/unix/ztypes_linux_s390x.go | 16 ++ .../x/sys/unix/ztypes_linux_sparc64.go | 16 ++ vendor/modules.txt | 7 +- 40 files changed, 500 insertions(+), 419 deletions(-) delete mode 100644 vendor/github.com/aymanbagabas/go-udiff/myers/diff.go diff --git a/vendor/github.com/aymanbagabas/go-udiff/myers/diff.go b/vendor/github.com/aymanbagabas/go-udiff/myers/diff.go deleted file mode 100644 index cc274d03d0cd2b4b142efb98d4a577a526f1afec..0000000000000000000000000000000000000000 --- a/vendor/github.com/aymanbagabas/go-udiff/myers/diff.go +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package myers implements the Myers diff algorithm. -package myers - -import ( - "strings" - - diff "github.com/aymanbagabas/go-udiff" -) - -// Sources: -// https://blog.jcoglan.com/2017/02/17/the-myers-diff-algorithm-part-3/ -// https://www.codeproject.com/Articles/42279/%2FArticles%2F42279%2FInvestigating-Myers-diff-algorithm-Part-1-of-2 - -// ComputeEdits returns the diffs of two strings using a simple -// line-based implementation, like [diff.Strings]. -// -// Deprecated: this implementation is moribund. However, when diffs -// appear in marker test expectations, they are the particular diffs -// produced by this implementation. The marker test framework -// asserts diff(orig, got)==wantDiff, but ideally it would compute -// got==apply(orig, wantDiff) so that the notation of the diff -// is immaterial. -func ComputeEdits(before, after string) []diff.Edit { - beforeLines := splitLines(before) - ops := operations(beforeLines, splitLines(after)) - - // Build a table mapping line number to offset. - lineOffsets := make([]int, 0, len(beforeLines)+1) - total := 0 - for i := range beforeLines { - lineOffsets = append(lineOffsets, total) - total += len(beforeLines[i]) - } - lineOffsets = append(lineOffsets, total) // EOF - - edits := make([]diff.Edit, 0, len(ops)) - for _, op := range ops { - start, end := lineOffsets[op.I1], lineOffsets[op.I2] - switch op.Kind { - case opDelete: - // Delete: before[I1:I2] is deleted. - edits = append(edits, diff.Edit{Start: start, End: end}) - case opInsert: - // Insert: after[J1:J2] is inserted at before[I1:I1]. - if content := strings.Join(op.Content, ""); content != "" { - edits = append(edits, diff.Edit{Start: start, End: end, New: content}) - } - } - } - return edits -} - -// opKind is used to denote the type of operation a line represents. -type opKind int - -const ( - opDelete opKind = iota // line deleted from input (-) - opInsert // line inserted into output (+) - opEqual // line present in input and output -) - -func (kind opKind) String() string { - switch kind { - case opDelete: - return "delete" - case opInsert: - return "insert" - case opEqual: - return "equal" - default: - panic("unknown opKind") - } -} - -type operation struct { - Kind opKind - Content []string // content from b - I1, I2 int // indices of the line in a - J1 int // indices of the line in b, J2 implied by len(Content) -} - -// operations returns the list of operations to convert a into b, consolidating -// operations for multiple lines and not including equal lines. -func operations(a, b []string) []*operation { - if len(a) == 0 && len(b) == 0 { - return nil - } - - trace, offset := shortestEditSequence(a, b) - snakes := backtrack(trace, len(a), len(b), offset) - - M, N := len(a), len(b) - - var i int - solution := make([]*operation, len(a)+len(b)) - - add := func(op *operation, i2, j2 int) { - if op == nil { - return - } - op.I2 = i2 - if op.Kind == opInsert { - op.Content = b[op.J1:j2] - } - solution[i] = op - i++ - } - x, y := 0, 0 - for _, snake := range snakes { - if len(snake) < 2 { - continue - } - var op *operation - // delete (horizontal) - for snake[0]-snake[1] > x-y { - if op == nil { - op = &operation{ - Kind: opDelete, - I1: x, - J1: y, - } - } - x++ - if x == M { - break - } - } - add(op, x, y) - op = nil - // insert (vertical) - for snake[0]-snake[1] < x-y { - if op == nil { - op = &operation{ - Kind: opInsert, - I1: x, - J1: y, - } - } - y++ - } - add(op, x, y) - op = nil - // equal (diagonal) - for x < snake[0] { - x++ - y++ - } - if x >= M && y >= N { - break - } - } - return solution[:i] -} - -// backtrack uses the trace for the edit sequence computation and returns the -// "snakes" that make up the solution. A "snake" is a single deletion or -// insertion followed by zero or diagonals. -func backtrack(trace [][]int, x, y, offset int) [][]int { - snakes := make([][]int, len(trace)) - d := len(trace) - 1 - for ; x > 0 && y > 0 && d > 0; d-- { - V := trace[d] - if len(V) == 0 { - continue - } - snakes[d] = []int{x, y} - - k := x - y - - var kPrev int - if k == -d || (k != d && V[k-1+offset] < V[k+1+offset]) { - kPrev = k + 1 - } else { - kPrev = k - 1 - } - - x = V[kPrev+offset] - y = x - kPrev - } - if x < 0 || y < 0 { - return snakes - } - snakes[d] = []int{x, y} - return snakes -} - -// shortestEditSequence returns the shortest edit sequence that converts a into b. -func shortestEditSequence(a, b []string) ([][]int, int) { - M, N := len(a), len(b) - V := make([]int, 2*(N+M)+1) - offset := N + M - trace := make([][]int, N+M+1) - - // Iterate through the maximum possible length of the SES (N+M). - for d := 0; d <= N+M; d++ { - copyV := make([]int, len(V)) - // k lines are represented by the equation y = x - k. We move in - // increments of 2 because end points for even d are on even k lines. - for k := -d; k <= d; k += 2 { - // At each point, we either go down or to the right. We go down if - // k == -d, and we go to the right if k == d. We also prioritize - // the maximum x value, because we prefer deletions to insertions. - var x int - if k == -d || (k != d && V[k-1+offset] < V[k+1+offset]) { - x = V[k+1+offset] // down - } else { - x = V[k-1+offset] + 1 // right - } - - y := x - k - - // Diagonal moves while we have equal contents. - for x < M && y < N && a[x] == b[y] { - x++ - y++ - } - - V[k+offset] = x - - // Return if we've exceeded the maximum values. - if x == M && y == N { - // Makes sure to save the state of the array before returning. - copy(copyV, V) - trace[d] = copyV - return trace, offset - } - } - - // Save the state of the array. - copy(copyV, V) - trace[d] = copyV - } - return nil, 0 -} - -func splitLines(text string) []string { - lines := strings.SplitAfter(text, "\n") - if lines[len(lines)-1] == "" { - lines = lines[:len(lines)-1] - } - return lines -} diff --git a/vendor/github.com/charmbracelet/ultraviolet/README.md b/vendor/github.com/charmbracelet/ultraviolet/README.md index 600a1d9841a5056ab5c4c9db271dfe86a37b2b40..7fb3f7cc60ee35da53dc8c8172333baeda60426e 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/README.md +++ b/vendor/github.com/charmbracelet/ultraviolet/README.md @@ -1,5 +1,7 @@ # Ultraviolet +Charm Ultraviolet +

Latest Release GoDoc diff --git a/vendor/github.com/charmbracelet/ultraviolet/input.go b/vendor/github.com/charmbracelet/ultraviolet/input.go index 7d74cffc734e4ecb7aaae3dac2e6725b8c660477..04524c5ddf5c8094387efbe92a77fb5f2d390956 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/input.go +++ b/vendor/github.com/charmbracelet/ultraviolet/input.go @@ -3,6 +3,7 @@ package uv import ( "context" + "github.com/charmbracelet/x/term" "golang.org/x/sync/errgroup" ) @@ -59,3 +60,30 @@ func (im *InputManager) ReceiveEvents(ctx context.Context, events chan<- Event) // Wait for all receivers to finish return errg.Wait() } + +// InitialSizeReceiver query the initial size of the terminal window and sends +// it to the given event channel. +type InitialSizeReceiver struct { + File term.File +} + +// ReceiveEvents queries the initial size of the terminal window and sends it +// to the given event channel. It stops when event is sent, the context is done +// or an error occurs. +func (r *InitialSizeReceiver) ReceiveEvents(ctx context.Context, events chan<- Event) error { + if r.File == nil { + return nil // No file set, nothing to do. + } + + w, h, err := term.GetSize(r.File.Fd()) + if err != nil { + return err + } + + select { + case <-ctx.Done(): + return ctx.Err() + case events <- WindowSizeEvent{Width: w, Height: h}: + return nil + } +} diff --git a/vendor/github.com/charmbracelet/ultraviolet/terminal.go b/vendor/github.com/charmbracelet/ultraviolet/terminal.go index 6aea2b44f84f63b9469c21eb6872af7db271c3b4..e236d9e25f3e3bf575fcefd629f39b485fc2d33c 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/terminal.go +++ b/vendor/github.com/charmbracelet/ultraviolet/terminal.go @@ -20,6 +20,8 @@ import ( "github.com/muesli/cancelreader" ) +const isWindows = "windows" + var ( // ErrNotTerminal is returned when one of the I/O streams is not a terminal. ErrNotTerminal = fmt.Errorf("not a terminal") @@ -42,8 +44,7 @@ type Terminal struct { inTtyState *term.State outTty term.File outTtyState *term.State - winchTty term.File // The terminal to receive window size changes from. - started bool // Indicates if the terminal has been started. + started bool // Indicates if the terminal has been started. // Terminal type, screen and buffer. termtype string // The $TERM type. @@ -123,7 +124,7 @@ func NewTerminal(in io.Reader, out io.Writer, env []string) *Terminal { // Handle debugging I/O. debug, ok := os.LookupEnv("UV_DEBUG") if ok && len(debug) > 0 { - f, err := os.OpenFile(debug, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o666) + f, err := os.OpenFile(debug, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o600) if err != nil { panic("failed to open debug file: " + err.Error()) } @@ -346,7 +347,7 @@ func (t *Terminal) EnableMode(modes ...ansi.Mode) { for _, m := range modes { t.modes[m] = ansi.ModeSet } - t.scr.WriteString(ansi.SetMode(modes...)) //nolint:errcheck + t.scr.WriteString(ansi.SetMode(modes...)) //nolint:errcheck,gosec } // DisableMode disables the given modes on the terminal. This is typically @@ -362,7 +363,7 @@ func (t *Terminal) DisableMode(modes ...ansi.Mode) { for _, m := range modes { t.modes[m] = ansi.ModeReset } - t.scr.WriteString(ansi.ResetMode(modes...)) //nolint:errcheck + t.scr.WriteString(ansi.ResetMode(modes...)) //nolint:errcheck,gosec } // RequestMode requests the current state of the given modes from the terminal. @@ -372,7 +373,7 @@ func (t *Terminal) DisableMode(modes ...ansi.Mode) { // Note that this won't take any effect until the next [Terminal.Display] or // [Terminal.Flush] call. func (t *Terminal) RequestMode(mode ansi.Mode) { - t.scr.WriteString(ansi.RequestMode(mode)) //nolint:errcheck + t.scr.WriteString(ansi.RequestMode(mode)) //nolint:errcheck,gosec } // MouseMode represents the mouse mode for the terminal. It is used to enable @@ -399,7 +400,7 @@ func (t *Terminal) SetForegroundColor(c color.Color) { t.setFg = c col, ok := colorful.MakeColor(c) if ok { - t.scr.WriteString(ansi.SetForegroundColor(col.Hex())) //nolint:errcheck + t.scr.WriteString(ansi.SetForegroundColor(col.Hex())) //nolint:errcheck,gosec } } @@ -408,7 +409,7 @@ func (t *Terminal) SetForegroundColor(c color.Color) { // Note that this won't take any effect until the next [Terminal.Display] or // [Terminal.Flush] call. func (t *Terminal) RequestForegroundColor() { - t.scr.WriteString(ansi.RequestForegroundColor) //nolint:errcheck + t.scr.WriteString(ansi.RequestForegroundColor) //nolint:errcheck,gosec } // ResetForegroundColor resets the terminal foreground color to the @@ -418,7 +419,7 @@ func (t *Terminal) RequestForegroundColor() { // [Terminal.Flush] call. func (t *Terminal) ResetForegroundColor() { t.setFg = nil - t.scr.WriteString(ansi.ResetForegroundColor) //nolint:errcheck + t.scr.WriteString(ansi.ResetForegroundColor) //nolint:errcheck,gosec } // SetBackgroundColor sets the terminal default background color. @@ -429,7 +430,7 @@ func (t *Terminal) SetBackgroundColor(c color.Color) { t.setBg = c col, ok := colorful.MakeColor(c) if ok { - t.scr.WriteString(ansi.SetBackgroundColor(col.Hex())) //nolint:errcheck + t.scr.WriteString(ansi.SetBackgroundColor(col.Hex())) //nolint:errcheck,gosec } } @@ -438,7 +439,7 @@ func (t *Terminal) SetBackgroundColor(c color.Color) { // Note that this won't take any effect until the next [Terminal.Display] or // [Terminal.Flush] call. func (t *Terminal) RequestBackgroundColor() { - t.scr.WriteString(ansi.RequestBackgroundColor) //nolint:errcheck + t.scr.WriteString(ansi.RequestBackgroundColor) //nolint:errcheck,gosec } // ResetBackgroundColor resets the terminal background color to the @@ -448,7 +449,7 @@ func (t *Terminal) RequestBackgroundColor() { // [Terminal.Flush] call. func (t *Terminal) ResetBackgroundColor() { t.setBg = nil - t.scr.WriteString(ansi.ResetBackgroundColor) //nolint:errcheck + t.scr.WriteString(ansi.ResetBackgroundColor) //nolint:errcheck,gosec } // SetCursorColor sets the terminal cursor color. @@ -459,7 +460,7 @@ func (t *Terminal) SetCursorColor(c color.Color) { t.setCc = c col, ok := colorful.MakeColor(c) if ok { - t.scr.WriteString(ansi.SetCursorColor(col.Hex())) //nolint:errcheck + t.scr.WriteString(ansi.SetCursorColor(col.Hex())) //nolint:errcheck,gosec } } @@ -468,7 +469,7 @@ func (t *Terminal) SetCursorColor(c color.Color) { // Note that this won't take any effect until the next [Terminal.Display] or // [Terminal.Flush] call. func (t *Terminal) RequestCursorColor() { - t.scr.WriteString(ansi.RequestCursorColor) //nolint:errcheck + t.scr.WriteString(ansi.RequestCursorColor) //nolint:errcheck,gosec } // ResetCursorColor resets the terminal cursor color to the @@ -478,7 +479,7 @@ func (t *Terminal) RequestCursorColor() { // [Terminal.Flush] call. func (t *Terminal) ResetCursorColor() { t.setCc = nil - t.scr.WriteString(ansi.ResetCursorColor) //nolint:errcheck + t.scr.WriteString(ansi.ResetCursorColor) //nolint:errcheck,gosec } // SetCursorShape sets the terminal cursor shape and blinking style. @@ -488,7 +489,7 @@ func (t *Terminal) ResetCursorColor() { func (t *Terminal) SetCursorShape(shape CursorShape, blink bool) { style := shape.Encode(blink) t.curStyle = style - t.scr.WriteString(ansi.SetCursorStyle(style)) //nolint:errcheck + t.scr.WriteString(ansi.SetCursorStyle(style)) //nolint:errcheck,gosec } // EnableMouse enables mouse support on the terminal. @@ -520,7 +521,7 @@ func (t *Terminal) EnableMouse(modes ...MouseMode) { mode = ButtonMouseMode | DragMouseMode | AllMouseMode } t.mouseMode = mode - if runtime.GOOS != "windows" { + if runtime.GOOS != isWindows { modes := []ansi.Mode{} if t.mouseMode&AllMouseMode != 0 { modes = append(modes, ansi.AnyEventMouseMode) @@ -532,7 +533,7 @@ func (t *Terminal) EnableMouse(modes ...MouseMode) { modes = append(modes, ansi.SgrExtMouseMode) t.EnableMode(modes...) } - t.enableWindowsMouse() //nolint:errcheck + t.enableWindowsMouse() //nolint:errcheck,gosec } // DisableMouse disables mouse support on the terminal. This will disable mouse @@ -542,7 +543,7 @@ func (t *Terminal) EnableMouse(modes ...MouseMode) { // [Terminal.Display] or [Terminal.Flush] call. func (t *Terminal) DisableMouse() { t.mouseMode = 0 - if runtime.GOOS != "windows" { + if runtime.GOOS != isWindows { var modes []ansi.Mode if t.modes.Get(ansi.AnyEventMouseMode).IsSet() { modes = append(modes, ansi.AnyEventMouseMode) @@ -558,7 +559,7 @@ func (t *Terminal) DisableMouse() { } t.DisableMode(modes...) } - t.disableWindowsMouse() //nolint:errcheck + t.disableWindowsMouse() //nolint:errcheck,gosec } // EnableBracketedPaste enables bracketed paste mode on the terminal. This is @@ -608,9 +609,9 @@ func (t *Terminal) enterAltScreen(cursor bool) { t.scr.EnterAltScreen() if cursor && !altscreen { if t.scr.CursorHidden() { - t.scr.WriteString(ansi.HideCursor) //nolint:errcheck + t.scr.WriteString(ansi.HideCursor) //nolint:errcheck,gosec } else { - t.scr.WriteString(ansi.ShowCursor) //nolint:errcheck + t.scr.WriteString(ansi.ShowCursor) //nolint:errcheck,gosec } } t.scr.SetRelativeCursor(false) @@ -639,9 +640,9 @@ func (t *Terminal) exitAltScreen(cursor bool) { t.scr.ExitAltScreen() if cursor && altscreen { if t.scr.CursorHidden() { - t.scr.WriteString(ansi.HideCursor) //nolint:errcheck + t.scr.WriteString(ansi.HideCursor) //nolint:errcheck,gosec } else { - t.scr.WriteString(ansi.ShowCursor) //nolint:errcheck + t.scr.WriteString(ansi.ShowCursor) //nolint:errcheck,gosec } } t.scr.SetRelativeCursor(true) @@ -725,11 +726,6 @@ func (t *Terminal) Start() error { return ErrNotTerminal } - t.winchTty = t.inTty - if t.winchTty == nil { - t.winchTty = t.outTty - } - // Get the initial terminal size. var err error t.size.Width, t.size.Height, err = t.GetSize() @@ -749,11 +745,11 @@ func (t *Terminal) Start() error { t.configureRenderer() if t.modes.Get(ansi.AltScreenSaveCursorMode).IsSet() { - t.enterAltScreen(false) //nolint:errcheck + t.enterAltScreen(false) } if t.cursorHidden == t.modes.Get(ansi.TextCursorEnableMode).IsReset() { // We always hide the cursor when we start. - t.hideCursor() //nolint:errcheck + t.hideCursor() } // Restore terminal modes. for m, s := range t.modes { @@ -763,7 +759,7 @@ func (t *Terminal) Start() error { continue default: if s.IsSet() { - t.scr.WriteString(ansi.SetMode(m)) //nolint:errcheck + t.scr.WriteString(ansi.SetMode(m)) //nolint:errcheck,gosec } } } @@ -779,21 +775,32 @@ func (t *Terminal) Start() error { if c.colorp != nil && *c.colorp != nil { col, ok := colorful.MakeColor(*c.colorp) if ok { - t.scr.WriteString(c.setter(col.Hex())) //nolint:errcheck + t.scr.WriteString(c.setter(col.Hex())) //nolint:errcheck,gosec } } } if t.curStyle > 1 { - t.scr.WriteString(ansi.SetCursorStyle(t.curStyle)) //nolint:errcheck + t.scr.WriteString(ansi.SetCursorStyle(t.curStyle)) //nolint:errcheck,gosec } if err := t.rd.Start(); err != nil { return fmt.Errorf("error starting terminal: %w", err) } - recvs := []InputReceiver{t.rd} - if runtime.GOOS != "windows" { - t.wrdr = &WinChReceiver{t.winchTty} + var winchTty term.File + if runtime.GOOS == isWindows { + // On Windows, we need to use the console output buffer to get the + // window size. + winchTty = t.outTty + } else { + winchTty = t.inTty + if winchTty == nil { + winchTty = t.outTty + } + } + recvs := []InputReceiver{t.rd, &InitialSizeReceiver{winchTty}} + if runtime.GOOS != isWindows { + t.wrdr = &WinChReceiver{winchTty} if err := t.wrdr.Start(); err != nil { return fmt.Errorf("error starting window size receiver: %w", err) } @@ -818,13 +825,13 @@ func (t *Terminal) Start() error { func (t *Terminal) Restore() error { if t.inTtyState != nil { if err := term.Restore(t.inTty.Fd(), t.inTtyState); err != nil { - return err + return fmt.Errorf("error restoring input terminal state: %w", err) } t.inTtyState = nil } if t.outTtyState != nil { if err := term.Restore(t.outTty.Fd(), t.outTtyState); err != nil { - return err + return fmt.Errorf("error restoring output terminal state: %w", err) } t.outTtyState = nil } @@ -835,10 +842,10 @@ func (t *Terminal) Restore() error { t.scr.MoveTo(0, t.buf.Height()-1) } if altscreen { - t.exitAltScreen(false) //nolint:errcheck + t.exitAltScreen(false) } if cursorHidden { - t.showCursor() //nolint:errcheck + t.showCursor() // Override the cursor hidden state so that we can auto hide it again // when the terminal resumes using [Terminal.Start]. t.cursorHidden = false diff --git a/vendor/github.com/charmbracelet/ultraviolet/terminal_reader.go b/vendor/github.com/charmbracelet/ultraviolet/terminal_reader.go index 987b3c6f8e3902c2b8f48936dee1991ffc6926f7..ec944d8c5c84b4e5b6aa3931e6bb7ec7d8f0adfb 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/terminal_reader.go +++ b/vendor/github.com/charmbracelet/ultraviolet/terminal_reader.go @@ -259,17 +259,22 @@ func (d *TerminalReader) run() { // - "\x1b^" (alt+^ key press) esc := n > 0 && n <= 2 && readBuf[0] == ansi.ESC if esc { - d.esc.Store(true) - d.timeout.Reset(d.EscTimeout) + d.resetEsc() } d.notify <- readBuf[:n] } } +func (d *TerminalReader) resetEsc() { + // Reset the escape sequence state and timer. + d.esc.Store(true) + d.timeout.Reset(d.EscTimeout) +} + func (d *TerminalReader) sendEvents(events chan<- Event) { // Lookup table first - if d.lookup && d.timedout.Load() && len(d.buf) > 0 && d.buf[0] == ansi.ESC { + if d.lookup && d.timedout.Load() && len(d.buf) > 2 && d.buf[0] == ansi.ESC { if k, ok := d.table[string(d.buf)]; ok { events <- KeyPressEvent(k) d.buf = d.buf[:0] @@ -309,8 +314,7 @@ LOOP: if slices.Contains([]byte{ ansi.ESC, ansi.CSI, ansi.OSC, ansi.DCS, ansi.APC, ansi.SOS, ansi.PM, }, d.buf[0]) { - d.esc.Store(true) - d.timeout.Reset(d.EscTimeout) + d.resetEsc() } } // If this is the entire buffer, we can break and assume this diff --git a/vendor/github.com/charmbracelet/ultraviolet/winch_unix.go b/vendor/github.com/charmbracelet/ultraviolet/winch_unix.go index 8ba33e896c4f7d9c7c8631b755508d239b9217f5..0e2f7d2a5e4ab89822884c8916df3f7e185d6e88 100644 --- a/vendor/github.com/charmbracelet/ultraviolet/winch_unix.go +++ b/vendor/github.com/charmbracelet/ultraviolet/winch_unix.go @@ -18,6 +18,8 @@ func (l *WinChReceiver) receiveEvents(ctx context.Context, f term.File, evch cha sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGWINCH) + defer signal.Stop(sig) + sendWinSize := func(w, h int) { select { case <-ctx.Done(): @@ -32,31 +34,8 @@ func (l *WinChReceiver) receiveEvents(ctx context.Context, f term.File, evch cha } } - defer signal.Stop(sig) - - // Send the initial window size. - winsize, err := termios.GetWinsize(int(f.Fd())) - if err != nil { - return err - } - - var wg sync.WaitGroup - wg.Add(1) - go func() { - defer wg.Done() - sendWinSize(int(winsize.Col), int(winsize.Row)) - }() - - wg.Add(1) - go func() { - defer wg.Done() - sendPixelSize(int(winsize.Xpixel), int(winsize.Ypixel)) - }() - - // Wait for all goroutines to finish before continuing. - wg.Wait() - // Listen for window size changes. + var wg sync.WaitGroup for { select { case <-ctx.Done(): diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index cb6bb9ad3ba9f8c5a36b2b68429d33a5ffc1430a..1d8cffae8cfc872e5c3748e4394da5ec1a763ccf 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -12,8 +12,6 @@ package errgroup import ( "context" "fmt" - "runtime" - "runtime/debug" "sync" ) @@ -33,10 +31,6 @@ type Group struct { errOnce sync.Once err error - - mu sync.Mutex - panicValue any // = PanicError | PanicValue; non-nil if some Group.Go goroutine panicked. - abnormal bool // some Group.Go goroutine terminated abnormally (panic or goexit). } func (g *Group) done() { @@ -56,22 +50,13 @@ func WithContext(ctx context.Context) (*Group, context.Context) { return &Group{cancel: cancel}, ctx } -// Wait blocks until all function calls from the Go method have returned -// normally, then returns the first non-nil error (if any) from them. -// -// If any of the calls panics, Wait panics with a [PanicValue]; -// and if any of them calls [runtime.Goexit], Wait calls runtime.Goexit. +// Wait blocks until all function calls from the Go method have returned, then +// returns the first non-nil error (if any) from them. func (g *Group) Wait() error { g.wg.Wait() if g.cancel != nil { g.cancel(g.err) } - if g.panicValue != nil { - panic(g.panicValue) - } - if g.abnormal { - runtime.Goexit() - } return g.err } @@ -81,53 +66,31 @@ func (g *Group) Wait() error { // It blocks until the new goroutine can be added without the number of // goroutines in the group exceeding the configured limit. // -// The first goroutine in the group that returns a non-nil error, panics, or -// invokes [runtime.Goexit] will cancel the associated Context, if any. +// The first goroutine in the group that returns a non-nil error will +// cancel the associated Context, if any. The error will be returned +// by Wait. func (g *Group) Go(f func() error) { if g.sem != nil { g.sem <- token{} } - g.add(f) -} - -func (g *Group) add(f func() error) { g.wg.Add(1) go func() { defer g.done() - normalReturn := false - defer func() { - if normalReturn { - return - } - v := recover() - g.mu.Lock() - defer g.mu.Unlock() - if !g.abnormal { - if g.cancel != nil { - g.cancel(g.err) - } - g.abnormal = true - } - if v != nil && g.panicValue == nil { - switch v := v.(type) { - case error: - g.panicValue = PanicError{ - Recovered: v, - Stack: debug.Stack(), - } - default: - g.panicValue = PanicValue{ - Recovered: v, - Stack: debug.Stack(), - } - } - } - }() - err := f() - normalReturn = true - if err != nil { + // It is tempting to propagate panics from f() + // up to the goroutine that calls Wait, but + // it creates more problems than it solves: + // - it delays panics arbitrarily, + // making bugs harder to detect; + // - it turns f's panic stack into a mere value, + // hiding it from crash-monitoring tools; + // - it risks deadlocks that hide the panic entirely, + // if f's panic leaves the program in a state + // that prevents the Wait call from being reached. + // See #53757, #74275, #74304, #74306. + + if err := f(); err != nil { g.errOnce.Do(func() { g.err = err if g.cancel != nil { @@ -152,7 +115,19 @@ func (g *Group) TryGo(f func() error) bool { } } - g.add(f) + g.wg.Add(1) + go func() { + defer g.done() + + if err := f(); err != nil { + g.errOnce.Do(func() { + g.err = err + if g.cancel != nil { + g.cancel(g.err) + } + }) + } + }() return true } @@ -174,34 +149,3 @@ func (g *Group) SetLimit(n int) { } g.sem = make(chan token, n) } - -// PanicError wraps an error recovered from an unhandled panic -// when calling a function passed to Go or TryGo. -type PanicError struct { - Recovered error - Stack []byte // result of call to [debug.Stack] -} - -func (p PanicError) Error() string { - if len(p.Stack) > 0 { - return fmt.Sprintf("recovered from errgroup.Group: %v\n%s", p.Recovered, p.Stack) - } - return fmt.Sprintf("recovered from errgroup.Group: %v", p.Recovered) -} - -func (p PanicError) Unwrap() error { return p.Recovered } - -// PanicValue wraps a value that does not implement the error interface, -// recovered from an unhandled panic when calling a function passed to Go or -// TryGo. -type PanicValue struct { - Recovered any - Stack []byte // result of call to [debug.Stack] -} - -func (p PanicValue) String() string { - if len(p.Stack) > 0 { - return fmt.Sprintf("recovered from errgroup.Group: %v\n%s", p.Recovered, p.Stack) - } - return fmt.Sprintf("recovered from errgroup.Group: %v", p.Recovered) -} diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 4f432bfe8feeee77862ace1bbfbed983d72f6e76..9e7a6c5a4fcaa11e4ceffdc79deee209162444a3 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -319,6 +319,7 @@ const ( AUDIT_INTEGRITY_POLICY_RULE = 0x70f AUDIT_INTEGRITY_RULE = 0x70d AUDIT_INTEGRITY_STATUS = 0x70a + AUDIT_INTEGRITY_USERSPACE = 0x710 AUDIT_IPC = 0x517 AUDIT_IPC_SET_PERM = 0x51f AUDIT_IPE_ACCESS = 0x58c @@ -843,9 +844,9 @@ const ( DM_UUID_FLAG = 0x4000 DM_UUID_LEN = 0x81 DM_VERSION = 0xc138fd00 - DM_VERSION_EXTRA = "-ioctl (2023-03-01)" + DM_VERSION_EXTRA = "-ioctl (2025-01-17)" DM_VERSION_MAJOR = 0x4 - DM_VERSION_MINOR = 0x30 + DM_VERSION_MINOR = 0x31 DM_VERSION_PATCHLEVEL = 0x0 DT_BLK = 0x6 DT_CHR = 0x2 @@ -941,6 +942,8 @@ const ( ETHER_FLOW = 0x12 ETHTOOL_BUSINFO_LEN = 0x20 ETHTOOL_EROMVERS_LEN = 0x20 + ETHTOOL_FAMILY_NAME = "ethtool" + ETHTOOL_FAMILY_VERSION = 0x1 ETHTOOL_FEC_AUTO = 0x2 ETHTOOL_FEC_BASER = 0x10 ETHTOOL_FEC_LLRS = 0x20 @@ -1203,6 +1206,9 @@ const ( FAN_DENY = 0x2 FAN_ENABLE_AUDIT = 0x40 FAN_EPIDFD = -0x2 + FAN_ERRNO_BITS = 0x8 + FAN_ERRNO_MASK = 0xff + FAN_ERRNO_SHIFT = 0x18 FAN_EVENT_INFO_TYPE_DFID = 0x3 FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2 FAN_EVENT_INFO_TYPE_ERROR = 0x5 @@ -1210,6 +1216,7 @@ const ( FAN_EVENT_INFO_TYPE_NEW_DFID_NAME = 0xc FAN_EVENT_INFO_TYPE_OLD_DFID_NAME = 0xa FAN_EVENT_INFO_TYPE_PIDFD = 0x4 + FAN_EVENT_INFO_TYPE_RANGE = 0x6 FAN_EVENT_METADATA_LEN = 0x18 FAN_EVENT_ON_CHILD = 0x8000000 FAN_FS_ERROR = 0x8000 @@ -1240,6 +1247,7 @@ const ( FAN_OPEN_EXEC = 0x1000 FAN_OPEN_EXEC_PERM = 0x40000 FAN_OPEN_PERM = 0x10000 + FAN_PRE_ACCESS = 0x100000 FAN_Q_OVERFLOW = 0x4000 FAN_RENAME = 0x10000000 FAN_REPORT_DFID_NAME = 0xc00 @@ -2787,7 +2795,7 @@ const ( RTAX_UNSPEC = 0x0 RTAX_WINDOW = 0x3 RTA_ALIGNTO = 0x4 - RTA_MAX = 0x1e + RTA_MAX = 0x1f RTCF_DIRECTSRC = 0x4000000 RTCF_DOREDIRECT = 0x1000000 RTCF_LOG = 0x2000000 @@ -2864,10 +2872,12 @@ const ( RTM_DELACTION = 0x31 RTM_DELADDR = 0x15 RTM_DELADDRLABEL = 0x49 + RTM_DELANYCAST = 0x3d RTM_DELCHAIN = 0x65 RTM_DELLINK = 0x11 RTM_DELLINKPROP = 0x6d RTM_DELMDB = 0x55 + RTM_DELMULTICAST = 0x39 RTM_DELNEIGH = 0x1d RTM_DELNETCONF = 0x51 RTM_DELNEXTHOP = 0x69 @@ -2917,11 +2927,13 @@ const ( RTM_NEWACTION = 0x30 RTM_NEWADDR = 0x14 RTM_NEWADDRLABEL = 0x48 + RTM_NEWANYCAST = 0x3c RTM_NEWCACHEREPORT = 0x60 RTM_NEWCHAIN = 0x64 RTM_NEWLINK = 0x10 RTM_NEWLINKPROP = 0x6c RTM_NEWMDB = 0x54 + RTM_NEWMULTICAST = 0x38 RTM_NEWNDUSEROPT = 0x44 RTM_NEWNEIGH = 0x1c RTM_NEWNEIGHTBL = 0x40 @@ -2987,11 +2999,12 @@ const ( RUSAGE_THREAD = 0x1 RWF_APPEND = 0x10 RWF_ATOMIC = 0x40 + RWF_DONTCACHE = 0x80 RWF_DSYNC = 0x2 RWF_HIPRI = 0x1 RWF_NOAPPEND = 0x20 RWF_NOWAIT = 0x8 - RWF_SUPPORTED = 0x7f + RWF_SUPPORTED = 0xff RWF_SYNC = 0x4 RWF_WRITE_LIFE_NOT_SET = 0x0 SCHED_BATCH = 0x3 @@ -3271,6 +3284,7 @@ const ( STATX_BTIME = 0x800 STATX_CTIME = 0x80 STATX_DIOALIGN = 0x2000 + STATX_DIO_READ_ALIGN = 0x20000 STATX_GID = 0x10 STATX_INO = 0x100 STATX_MNT_ID = 0x1000 @@ -3322,7 +3336,7 @@ const ( TASKSTATS_GENL_NAME = "TASKSTATS" TASKSTATS_GENL_VERSION = 0x1 TASKSTATS_TYPE_MAX = 0x6 - TASKSTATS_VERSION = 0xe + TASKSTATS_VERSION = 0xf TCIFLUSH = 0x0 TCIOFF = 0x2 TCIOFLUSH = 0x2 @@ -3503,6 +3517,7 @@ const ( TP_STATUS_WRONG_FORMAT = 0x4 TRACEFS_MAGIC = 0x74726163 TS_COMM_LEN = 0x20 + UBI_IOCECNFO = 0xc01c6f06 UDF_SUPER_MAGIC = 0x15013346 UDP_CORK = 0x1 UDP_ENCAP = 0x64 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index 75207613c785dbe3fb5e9afd152330e4ff342de3..a8c421e29b5e826eb534a43f0b086f03f39acfcd 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -372,6 +372,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index c68acda53522d124fc1ef7c7dc889394ca4103ab..9a88d18130feaf562932beec1595745ef321b20c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -373,6 +373,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index a8c607ab86b51b1e69629a7131b674a533c1a05f..7cb6a867efd5a5b4ece27aac9644d40d516872b1 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -378,6 +378,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 18563dd8d33a0f8e7a343377cd529ddf3eeb47fc..d0ecd2c583bffabc6652463ce671031b50c7c34d 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index 22912cdaa94483d6a5a2759d4d05b72663fce96b..7a2940ae0a358ac724d219cd0836f434d454d983 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -365,6 +365,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index 29344eb37ab55a5982a044ccd388638be2ce0f23..d14ca8f2ecf7b0f93b1ba83d862232d1faad6209 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index 20d51fb96a897f5c675d91b1107efa1b0956c3b0..2da1bac1e3dab099a764218cc7a70f1b2723f911 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 321b60902ae5cd5686f44b8dcf9d742a6df9d30c..28727514b5f20a747f63a6eadfd711164bece529 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 9bacdf1e27910f1e8f2cb8c582b37f7c54467224..7f287b54b5dd33cf5cc7c7cff1ced51b17f89e1c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -371,6 +371,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x1004 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x1006 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x1006 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index c2242726156a94e77d1b3a6b5c8f5e0f61b643f7..7e5f9e6aa8de95fe161dce70fd6582b4fdeaa4f6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -426,6 +426,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index 6270c8ee13e3f5ac37b6954b36ca972696ad092c..37c87952fcb6fed8f0b11904d4060ef734c22381 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -430,6 +430,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index 9966c1941f8301450c052e12184340b465ad204e..5220133613a928f7e2936ce38abaa4d7e7abd24b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -430,6 +430,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x10 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x12 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x12 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 848e5fcc42e6f2f5dcc59d5a5d79199e57a856cb..4bfe2b5b6e6b6d56f758c755f1efbddc7521e23c 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -362,6 +362,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 669b2adb80b778d9daf8400dd00cbab41c0ea5d1..e3cffb869a3d606bdfcf0982d5934d3b1aa4506e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -434,6 +434,7 @@ const ( SO_RCVBUFFORCE = 0x21 SO_RCVLOWAT = 0x12 SO_RCVMARK = 0x4b + SO_RCVPRIORITY = 0x52 SO_RCVTIMEO = 0x14 SO_RCVTIMEO_NEW = 0x42 SO_RCVTIMEO_OLD = 0x14 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index 4834e57514e44a7f8ca60a6a29e241ac1dba1c77..c219c8db39609bab1e94e9127bb90183ed314a45 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -473,6 +473,7 @@ const ( SO_RCVBUFFORCE = 0x100b SO_RCVLOWAT = 0x800 SO_RCVMARK = 0x54 + SO_RCVPRIORITY = 0x5b SO_RCVTIMEO = 0x2000 SO_RCVTIMEO_NEW = 0x44 SO_RCVTIMEO_OLD = 0x2000 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index a46abe64720547a72a90330c2aa29113b4ef0552..8bcac2835f6a62bfbd9fdea4c531fdecac3e790f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -114,7 +114,7 @@ type Statx_t struct { Atomic_write_unit_min uint32 Atomic_write_unit_max uint32 Atomic_write_segments_max uint32 - _ [1]uint32 + Dio_read_offset_align uint32 _ [9]uint64 } @@ -2226,8 +2226,11 @@ const ( NFT_PAYLOAD_LL_HEADER = 0x0 NFT_PAYLOAD_NETWORK_HEADER = 0x1 NFT_PAYLOAD_TRANSPORT_HEADER = 0x2 + NFT_PAYLOAD_INNER_HEADER = 0x3 + NFT_PAYLOAD_TUN_HEADER = 0x4 NFT_PAYLOAD_CSUM_NONE = 0x0 NFT_PAYLOAD_CSUM_INET = 0x1 + NFT_PAYLOAD_CSUM_SCTP = 0x2 NFT_PAYLOAD_L4CSUM_PSEUDOHDR = 0x1 NFTA_PAYLOAD_UNSPEC = 0x0 NFTA_PAYLOAD_DREG = 0x1 @@ -3802,7 +3805,16 @@ const ( ETHTOOL_MSG_PSE_GET = 0x24 ETHTOOL_MSG_PSE_SET = 0x25 ETHTOOL_MSG_RSS_GET = 0x26 - ETHTOOL_MSG_USER_MAX = 0x2d + ETHTOOL_MSG_PLCA_GET_CFG = 0x27 + ETHTOOL_MSG_PLCA_SET_CFG = 0x28 + ETHTOOL_MSG_PLCA_GET_STATUS = 0x29 + ETHTOOL_MSG_MM_GET = 0x2a + ETHTOOL_MSG_MM_SET = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_ACT = 0x2c + ETHTOOL_MSG_PHY_GET = 0x2d + ETHTOOL_MSG_TSCONFIG_GET = 0x2e + ETHTOOL_MSG_TSCONFIG_SET = 0x2f + ETHTOOL_MSG_USER_MAX = 0x2f ETHTOOL_MSG_KERNEL_NONE = 0x0 ETHTOOL_MSG_STRSET_GET_REPLY = 0x1 ETHTOOL_MSG_LINKINFO_GET_REPLY = 0x2 @@ -3842,7 +3854,17 @@ const ( ETHTOOL_MSG_MODULE_NTF = 0x24 ETHTOOL_MSG_PSE_GET_REPLY = 0x25 ETHTOOL_MSG_RSS_GET_REPLY = 0x26 - ETHTOOL_MSG_KERNEL_MAX = 0x2e + ETHTOOL_MSG_PLCA_GET_CFG_REPLY = 0x27 + ETHTOOL_MSG_PLCA_GET_STATUS_REPLY = 0x28 + ETHTOOL_MSG_PLCA_NTF = 0x29 + ETHTOOL_MSG_MM_GET_REPLY = 0x2a + ETHTOOL_MSG_MM_NTF = 0x2b + ETHTOOL_MSG_MODULE_FW_FLASH_NTF = 0x2c + ETHTOOL_MSG_PHY_GET_REPLY = 0x2d + ETHTOOL_MSG_PHY_NTF = 0x2e + ETHTOOL_MSG_TSCONFIG_GET_REPLY = 0x2f + ETHTOOL_MSG_TSCONFIG_SET_REPLY = 0x30 + ETHTOOL_MSG_KERNEL_MAX = 0x30 ETHTOOL_FLAG_COMPACT_BITSETS = 0x1 ETHTOOL_FLAG_OMIT_REPLY = 0x2 ETHTOOL_FLAG_STATS = 0x4 @@ -3949,7 +3971,12 @@ const ( ETHTOOL_A_RINGS_TCP_DATA_SPLIT = 0xb ETHTOOL_A_RINGS_CQE_SIZE = 0xc ETHTOOL_A_RINGS_TX_PUSH = 0xd - ETHTOOL_A_RINGS_MAX = 0x10 + ETHTOOL_A_RINGS_RX_PUSH = 0xe + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN = 0xf + ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX = 0x10 + ETHTOOL_A_RINGS_HDS_THRESH = 0x11 + ETHTOOL_A_RINGS_HDS_THRESH_MAX = 0x12 + ETHTOOL_A_RINGS_MAX = 0x12 ETHTOOL_A_CHANNELS_UNSPEC = 0x0 ETHTOOL_A_CHANNELS_HEADER = 0x1 ETHTOOL_A_CHANNELS_RX_MAX = 0x2 @@ -4015,7 +4042,9 @@ const ( ETHTOOL_A_TSINFO_TX_TYPES = 0x3 ETHTOOL_A_TSINFO_RX_FILTERS = 0x4 ETHTOOL_A_TSINFO_PHC_INDEX = 0x5 - ETHTOOL_A_TSINFO_MAX = 0x6 + ETHTOOL_A_TSINFO_STATS = 0x6 + ETHTOOL_A_TSINFO_HWTSTAMP_PROVIDER = 0x7 + ETHTOOL_A_TSINFO_MAX = 0x7 ETHTOOL_A_CABLE_TEST_UNSPEC = 0x0 ETHTOOL_A_CABLE_TEST_HEADER = 0x1 ETHTOOL_A_CABLE_TEST_MAX = 0x1 @@ -4613,6 +4642,7 @@ const ( NL80211_ATTR_AKM_SUITES = 0x4c NL80211_ATTR_AP_ISOLATE = 0x60 NL80211_ATTR_AP_SETTINGS_FLAGS = 0x135 + NL80211_ATTR_ASSOC_SPP_AMSDU = 0x14a NL80211_ATTR_AUTH_DATA = 0x9c NL80211_ATTR_AUTH_TYPE = 0x35 NL80211_ATTR_BANDS = 0xef @@ -4623,6 +4653,7 @@ const ( NL80211_ATTR_BSS_BASIC_RATES = 0x24 NL80211_ATTR_BSS = 0x2f NL80211_ATTR_BSS_CTS_PROT = 0x1c + NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA = 0x147 NL80211_ATTR_BSS_HT_OPMODE = 0x6d NL80211_ATTR_BSSID = 0xf5 NL80211_ATTR_BSS_SELECT = 0xe3 @@ -4682,6 +4713,7 @@ const ( NL80211_ATTR_DTIM_PERIOD = 0xd NL80211_ATTR_DURATION = 0x57 NL80211_ATTR_EHT_CAPABILITY = 0x136 + NL80211_ATTR_EMA_RNR_ELEMS = 0x145 NL80211_ATTR_EML_CAPABILITY = 0x13d NL80211_ATTR_EXT_CAPA = 0xa9 NL80211_ATTR_EXT_CAPA_MASK = 0xaa @@ -4717,6 +4749,7 @@ const ( NL80211_ATTR_HIDDEN_SSID = 0x7e NL80211_ATTR_HT_CAPABILITY = 0x1f NL80211_ATTR_HT_CAPABILITY_MASK = 0x94 + NL80211_ATTR_HW_TIMESTAMP_ENABLED = 0x144 NL80211_ATTR_IE_ASSOC_RESP = 0x80 NL80211_ATTR_IE = 0x2a NL80211_ATTR_IE_PROBE_RESP = 0x7f @@ -4747,9 +4780,10 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x14d + NL80211_ATTR_MAX = 0x150 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce + NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS = 0x143 NL80211_ATTR_MAX_MATCH_SETS = 0x85 NL80211_ATTR_MAX_NUM_AKM_SUITES = 0x13c NL80211_ATTR_MAX_NUM_PMKIDS = 0x56 @@ -4774,9 +4808,12 @@ const ( NL80211_ATTR_MGMT_SUBTYPE = 0x29 NL80211_ATTR_MLD_ADDR = 0x13a NL80211_ATTR_MLD_CAPA_AND_OPS = 0x13e + NL80211_ATTR_MLO_LINK_DISABLED = 0x146 NL80211_ATTR_MLO_LINK_ID = 0x139 NL80211_ATTR_MLO_LINKS = 0x138 NL80211_ATTR_MLO_SUPPORT = 0x13b + NL80211_ATTR_MLO_TTLM_DLINK = 0x148 + NL80211_ATTR_MLO_TTLM_ULINK = 0x149 NL80211_ATTR_MNTR_FLAGS = 0x17 NL80211_ATTR_MPATH_INFO = 0x1b NL80211_ATTR_MPATH_NEXT_HOP = 0x1a @@ -4809,12 +4846,14 @@ const ( NL80211_ATTR_PORT_AUTHORIZED = 0x103 NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN = 0x5 NL80211_ATTR_POWER_RULE_MAX_EIRP = 0x6 + NL80211_ATTR_POWER_RULE_PSD = 0x8 NL80211_ATTR_PREV_BSSID = 0x4f NL80211_ATTR_PRIVACY = 0x46 NL80211_ATTR_PROBE_RESP = 0x91 NL80211_ATTR_PROBE_RESP_OFFLOAD = 0x90 NL80211_ATTR_PROTOCOL_FEATURES = 0xad NL80211_ATTR_PS_STATE = 0x5d + NL80211_ATTR_PUNCT_BITMAP = 0x142 NL80211_ATTR_QOS_MAP = 0xc7 NL80211_ATTR_RADAR_BACKGROUND = 0x134 NL80211_ATTR_RADAR_EVENT = 0xa8 @@ -4943,7 +4982,9 @@ const ( NL80211_ATTR_WIPHY_FREQ = 0x26 NL80211_ATTR_WIPHY_FREQ_HINT = 0xc9 NL80211_ATTR_WIPHY_FREQ_OFFSET = 0x122 + NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS = 0x14c NL80211_ATTR_WIPHY_NAME = 0x2 + NL80211_ATTR_WIPHY_RADIOS = 0x14b NL80211_ATTR_WIPHY_RETRY_LONG = 0x3e NL80211_ATTR_WIPHY_RETRY_SHORT = 0x3d NL80211_ATTR_WIPHY_RTS_THRESHOLD = 0x40 @@ -4978,6 +5019,8 @@ const ( NL80211_BAND_ATTR_IFTYPE_DATA = 0x9 NL80211_BAND_ATTR_MAX = 0xd NL80211_BAND_ATTR_RATES = 0x2 + NL80211_BAND_ATTR_S1G_CAPA = 0xd + NL80211_BAND_ATTR_S1G_MCS_NSS_SET = 0xc NL80211_BAND_ATTR_VHT_CAPA = 0x8 NL80211_BAND_ATTR_VHT_MCS_SET = 0x7 NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC = 0x8 @@ -5001,6 +5044,10 @@ const ( NL80211_BSS_BEACON_INTERVAL = 0x4 NL80211_BSS_BEACON_TSF = 0xd NL80211_BSS_BSSID = 0x1 + NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH = 0x2 + NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY = 0x1 + NL80211_BSS_CANNOT_USE_REASONS = 0x18 + NL80211_BSS_CANNOT_USE_UHB_PWR_MISMATCH = 0x2 NL80211_BSS_CAPABILITY = 0x5 NL80211_BSS_CHAIN_SIGNAL = 0x13 NL80211_BSS_CHAN_WIDTH_10 = 0x1 @@ -5032,6 +5079,9 @@ const ( NL80211_BSS_STATUS = 0x9 NL80211_BSS_STATUS_IBSS_JOINED = 0x2 NL80211_BSS_TSF = 0x3 + NL80211_BSS_USE_FOR = 0x17 + NL80211_BSS_USE_FOR_MLD_LINK = 0x2 + NL80211_BSS_USE_FOR_NORMAL = 0x1 NL80211_CHAN_HT20 = 0x1 NL80211_CHAN_HT40MINUS = 0x2 NL80211_CHAN_HT40PLUS = 0x3 @@ -5117,7 +5167,8 @@ const ( NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_OCB = 0x6d - NL80211_CMD_MAX = 0x9b + NL80211_CMD_LINKS_REMOVED = 0x9a + NL80211_CMD_MAX = 0x9d NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_NAN_MATCH = 0x78 @@ -5161,6 +5212,7 @@ const ( NL80211_CMD_SET_COALESCE = 0x65 NL80211_CMD_SET_CQM = 0x3f NL80211_CMD_SET_FILS_AAD = 0x92 + NL80211_CMD_SET_HW_TIMESTAMP = 0x99 NL80211_CMD_SET_INTERFACE = 0x6 NL80211_CMD_SET_KEY = 0xa NL80211_CMD_SET_MAC_ACL = 0x5d @@ -5180,6 +5232,7 @@ const ( NL80211_CMD_SET_SAR_SPECS = 0x8c NL80211_CMD_SET_STATION = 0x12 NL80211_CMD_SET_TID_CONFIG = 0x89 + NL80211_CMD_SET_TID_TO_LINK_MAPPING = 0x9b NL80211_CMD_SET_TX_BITRATE_MASK = 0x39 NL80211_CMD_SET_WDS_PEER = 0x42 NL80211_CMD_SET_WIPHY = 0x2 @@ -5247,6 +5300,7 @@ const ( NL80211_EXT_FEATURE_AIRTIME_FAIRNESS = 0x21 NL80211_EXT_FEATURE_AP_PMKSA_CACHING = 0x22 NL80211_EXT_FEATURE_AQL = 0x28 + NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA = 0x40 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT = 0x2e NL80211_EXT_FEATURE_BEACON_PROTECTION = 0x29 NL80211_EXT_FEATURE_BEACON_RATE_HE = 0x36 @@ -5262,6 +5316,7 @@ const ( NL80211_EXT_FEATURE_CQM_RSSI_LIST = 0xd NL80211_EXT_FEATURE_DATA_ACK_SIGNAL_SUPPORT = 0x1b NL80211_EXT_FEATURE_DEL_IBSS_STA = 0x2c + NL80211_EXT_FEATURE_DFS_CONCURRENT = 0x43 NL80211_EXT_FEATURE_DFS_OFFLOAD = 0x19 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER = 0x20 NL80211_EXT_FEATURE_EXT_KEY_ID = 0x24 @@ -5281,9 +5336,12 @@ const ( NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 0x14 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE = 0x13 NL80211_EXT_FEATURE_OPERATING_CHANNEL_VALIDATION = 0x31 + NL80211_EXT_FEATURE_OWE_OFFLOAD_AP = 0x42 + NL80211_EXT_FEATURE_OWE_OFFLOAD = 0x41 NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE = 0x3d NL80211_EXT_FEATURE_PROTECTED_TWT = 0x2b NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE = 0x39 + NL80211_EXT_FEATURE_PUNCT = 0x3e NL80211_EXT_FEATURE_RADAR_BACKGROUND = 0x3c NL80211_EXT_FEATURE_RRM = 0x1 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP = 0x33 @@ -5295,8 +5353,10 @@ const ( NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD = 0x23 NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI = 0xc NL80211_EXT_FEATURE_SECURE_LTF = 0x37 + NL80211_EXT_FEATURE_SECURE_NAN = 0x3f NL80211_EXT_FEATURE_SECURE_RTT = 0x38 NL80211_EXT_FEATURE_SET_SCAN_DWELL = 0x5 + NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT = 0x44 NL80211_EXT_FEATURE_STA_TX_PWR = 0x25 NL80211_EXT_FEATURE_TXQS = 0x1c NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP = 0x35 @@ -5343,7 +5403,10 @@ const ( NL80211_FREQUENCY_ATTR_2MHZ = 0x16 NL80211_FREQUENCY_ATTR_4MHZ = 0x17 NL80211_FREQUENCY_ATTR_8MHZ = 0x18 + NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP = 0x21 + NL80211_FREQUENCY_ATTR_CAN_MONITOR = 0x20 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME = 0xd + NL80211_FREQUENCY_ATTR_DFS_CONCURRENT = 0x1d NL80211_FREQUENCY_ATTR_DFS_STATE = 0x7 NL80211_FREQUENCY_ATTR_DFS_TIME = 0x8 NL80211_FREQUENCY_ATTR_DISABLED = 0x2 @@ -5357,6 +5420,8 @@ const ( NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc NL80211_FREQUENCY_ATTR_NO_20MHZ = 0x10 NL80211_FREQUENCY_ATTR_NO_320MHZ = 0x1a + NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_NO_80MHZ = 0xb NL80211_FREQUENCY_ATTR_NO_EHT = 0x1b NL80211_FREQUENCY_ATTR_NO_HE = 0x13 @@ -5364,8 +5429,11 @@ const ( NL80211_FREQUENCY_ATTR_NO_HT40_PLUS = 0xa NL80211_FREQUENCY_ATTR_NO_IBSS = 0x3 NL80211_FREQUENCY_ATTR_NO_IR = 0x3 + NL80211_FREQUENCY_ATTR_NO_UHB_AFC_CLIENT = 0x1f + NL80211_FREQUENCY_ATTR_NO_UHB_VLP_CLIENT = 0x1e NL80211_FREQUENCY_ATTR_OFFSET = 0x14 NL80211_FREQUENCY_ATTR_PASSIVE_SCAN = 0x3 + NL80211_FREQUENCY_ATTR_PSD = 0x1c NL80211_FREQUENCY_ATTR_RADAR = 0x5 NL80211_FREQUENCY_ATTR_WMM = 0x12 NL80211_FTM_RESP_ATTR_CIVICLOC = 0x3 @@ -5430,6 +5498,7 @@ const ( NL80211_IFTYPE_STATION = 0x2 NL80211_IFTYPE_UNSPECIFIED = 0x0 NL80211_IFTYPE_WDS = 0x5 + NL80211_KCK_EXT_LEN_32 = 0x20 NL80211_KCK_EXT_LEN = 0x18 NL80211_KCK_LEN = 0x10 NL80211_KEK_EXT_LEN = 0x20 @@ -5458,6 +5527,7 @@ const ( NL80211_MAX_SUPP_HT_RATES = 0x4d NL80211_MAX_SUPP_RATES = 0x20 NL80211_MAX_SUPP_REG_RULES = 0x80 + NL80211_MAX_SUPP_SELECTORS = 0x80 NL80211_MBSSID_CONFIG_ATTR_EMA = 0x5 NL80211_MBSSID_CONFIG_ATTR_INDEX = 0x3 NL80211_MBSSID_CONFIG_ATTR_MAX = 0x5 @@ -5703,11 +5773,16 @@ const ( NL80211_RADAR_PRE_CAC_EXPIRED = 0x4 NL80211_RATE_INFO_10_MHZ_WIDTH = 0xb NL80211_RATE_INFO_160_MHZ_WIDTH = 0xa + NL80211_RATE_INFO_16_MHZ_WIDTH = 0x1d + NL80211_RATE_INFO_1_MHZ_WIDTH = 0x19 + NL80211_RATE_INFO_2_MHZ_WIDTH = 0x1a NL80211_RATE_INFO_320_MHZ_WIDTH = 0x12 NL80211_RATE_INFO_40_MHZ_WIDTH = 0x3 + NL80211_RATE_INFO_4_MHZ_WIDTH = 0x1b NL80211_RATE_INFO_5_MHZ_WIDTH = 0xc NL80211_RATE_INFO_80_MHZ_WIDTH = 0x8 NL80211_RATE_INFO_80P80_MHZ_WIDTH = 0x9 + NL80211_RATE_INFO_8_MHZ_WIDTH = 0x1c NL80211_RATE_INFO_BITRATE32 = 0x5 NL80211_RATE_INFO_BITRATE = 0x1 NL80211_RATE_INFO_EHT_GI_0_8 = 0x0 @@ -5753,6 +5828,8 @@ const ( NL80211_RATE_INFO_HE_RU_ALLOC = 0x11 NL80211_RATE_INFO_MAX = 0x1d NL80211_RATE_INFO_MCS = 0x2 + NL80211_RATE_INFO_S1G_MCS = 0x17 + NL80211_RATE_INFO_S1G_NSS = 0x18 NL80211_RATE_INFO_SHORT_GI = 0x4 NL80211_RATE_INFO_VHT_MCS = 0x6 NL80211_RATE_INFO_VHT_NSS = 0x7 @@ -5770,14 +5847,19 @@ const ( NL80211_REKEY_DATA_KEK = 0x1 NL80211_REKEY_DATA_REPLAY_CTR = 0x3 NL80211_REPLAY_CTR_LEN = 0x8 + NL80211_RRF_ALLOW_6GHZ_VLP_AP = 0x1000000 NL80211_RRF_AUTO_BW = 0x800 NL80211_RRF_DFS = 0x10 + NL80211_RRF_DFS_CONCURRENT = 0x200000 NL80211_RRF_GO_CONCURRENT = 0x1000 NL80211_RRF_IR_CONCURRENT = 0x1000 NL80211_RRF_NO_160MHZ = 0x10000 NL80211_RRF_NO_320MHZ = 0x40000 + NL80211_RRF_NO_6GHZ_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_6GHZ_VLP_CLIENT = 0x400000 NL80211_RRF_NO_80MHZ = 0x8000 NL80211_RRF_NO_CCK = 0x2 + NL80211_RRF_NO_EHT = 0x80000 NL80211_RRF_NO_HE = 0x20000 NL80211_RRF_NO_HT40 = 0x6000 NL80211_RRF_NO_HT40MINUS = 0x2000 @@ -5788,7 +5870,10 @@ const ( NL80211_RRF_NO_IR = 0x80 NL80211_RRF_NO_OFDM = 0x1 NL80211_RRF_NO_OUTDOOR = 0x8 + NL80211_RRF_NO_UHB_AFC_CLIENT = 0x800000 + NL80211_RRF_NO_UHB_VLP_CLIENT = 0x400000 NL80211_RRF_PASSIVE_SCAN = 0x80 + NL80211_RRF_PSD = 0x100000 NL80211_RRF_PTMP_ONLY = 0x40 NL80211_RRF_PTP_ONLY = 0x20 NL80211_RXMGMT_FLAG_ANSWERED = 0x1 @@ -5849,6 +5934,7 @@ const ( NL80211_STA_FLAG_MAX_OLD_API = 0x6 NL80211_STA_FLAG_MFP = 0x4 NL80211_STA_FLAG_SHORT_PREAMBLE = 0x2 + NL80211_STA_FLAG_SPP_AMSDU = 0x8 NL80211_STA_FLAG_TDLS_PEER = 0x6 NL80211_STA_FLAG_WME = 0x3 NL80211_STA_INFO_ACK_SIGNAL_AVG = 0x23 @@ -6007,6 +6093,13 @@ const ( NL80211_VHT_CAPABILITY_LEN = 0xc NL80211_VHT_NSS_MAX = 0x8 NL80211_WIPHY_NAME_MAXLEN = 0x40 + NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE = 0x2 + NL80211_WIPHY_RADIO_ATTR_INDEX = 0x1 + NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION = 0x3 + NL80211_WIPHY_RADIO_ATTR_MAX = 0x4 + NL80211_WIPHY_RADIO_FREQ_ATTR_END = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = 0x2 + NL80211_WIPHY_RADIO_FREQ_ATTR_START = 0x1 NL80211_WMMR_AIFSN = 0x3 NL80211_WMMR_CW_MAX = 0x2 NL80211_WMMR_CW_MIN = 0x1 @@ -6038,6 +6131,7 @@ const ( NL80211_WOWLAN_TRIG_PKT_PATTERN = 0x4 NL80211_WOWLAN_TRIG_RFKILL_RELEASE = 0x9 NL80211_WOWLAN_TRIG_TCP_CONNECTION = 0xe + NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC = 0x14 NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 = 0xa NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN = 0xb NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 = 0xc diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go index fd402da43fce18a993f6ec554d7936594abbeedf..62db85f6cb72a8f5432500b52ca4b0ed762ee589 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_386.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_386.go @@ -285,10 +285,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -324,11 +330,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -336,8 +348,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go index eb7a5e1864adae057314f1a4007adcabe376a202..7d89d648d9aa6cdc35ecba70c043a62c2352e2e1 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go @@ -300,10 +300,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -338,19 +344,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go index d78ac108b6c263fa7466ced80303c7838745d75a..9c0b39eec761445defdfea9eb04f03967049e0b1 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm.go @@ -276,10 +276,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -315,11 +321,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -327,8 +339,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go index cd06d47f1f7c76e70ca481f25b17aa5b3c0b0c02..de9c7ff36cfeabc751e96b887078bf5c9459f0d6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go @@ -279,10 +279,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -317,19 +323,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go index 2f28fe26c1a533d7d5b988c6615163e0c26d3c15..2336bd2bf0994352f7cd9772ca1f53c04b6b64bc 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_loong64.go @@ -280,10 +280,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -318,19 +324,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go index 71d6cac2f1aabdb4c4d01c529cb81cd1a23d8cf6..4711f0be16d508bbd958888f31321a0755e95c7b 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips.go @@ -281,10 +281,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -320,11 +326,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -332,8 +344,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go index 8596d45356387339625784fe527ce211010f5177..ab99a34b99651d78ac7bc15db9ae24ba5de39e47 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go @@ -282,10 +282,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -320,19 +326,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go index cd60ea18662bfc9389fc47b21247438f8ae066b4..04c9866e3cf8c17d30e405b6ca254e7b32564737 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go @@ -282,10 +282,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -320,19 +326,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go index b0ae420c489d6bbd779af1654ce3c8de9456a03f..60aa69f618c7ef63c80635acb01858b085c00edf 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go @@ -281,10 +281,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -320,11 +326,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -332,8 +344,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go index 8359728759bcfd3056781eea34bda15f2baad939..cb4fad785d13d467c88f9c211573e4dd7441e3aa 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc.go @@ -288,10 +288,16 @@ type Taskstats struct { _ [4]byte Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -327,11 +333,17 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 _ [4]byte Ac_tgetime uint64 @@ -339,8 +351,12 @@ type Taskstats struct { Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint32 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go index 69eb6a5c6892f527b6bdac2424915de142d6125c..60272cfce86beaca8c6de5948b1c393f75fc5c8d 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go @@ -289,10 +289,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -327,19 +333,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go index 5f583cb62bf304c9d82386aad07e8c481df6183b..3f5b91bc0d50ebfab05956eca6a65eec24204eae 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go @@ -289,10 +289,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -327,19 +333,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index ad05b51a60364994ecb52341160202a800f98ddc..51550f15a637111d655a64701eb6a09070a560b5 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -307,10 +307,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]uint8 @@ -345,19 +351,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go index cf3ce90037704d303eadbfebdb87edb0de4c3d6a..3239e50e0e22c6b284517ccd0f0947213ca1adeb 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go @@ -302,10 +302,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -340,19 +346,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go index 590b56739c5b3356de134089d3c26e64f8f5dd95..faf20027831ae59fc1e2309062ef5d4d7dba778e 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_sparc64.go @@ -284,10 +284,16 @@ type Taskstats struct { Ac_nice uint8 Cpu_count uint64 Cpu_delay_total uint64 + Cpu_delay_max uint64 + Cpu_delay_min uint64 Blkio_count uint64 Blkio_delay_total uint64 + Blkio_delay_max uint64 + Blkio_delay_min uint64 Swapin_count uint64 Swapin_delay_total uint64 + Swapin_delay_max uint64 + Swapin_delay_min uint64 Cpu_run_real_total uint64 Cpu_run_virtual_total uint64 Ac_comm [32]int8 @@ -322,19 +328,29 @@ type Taskstats struct { Cpu_scaled_run_real_total uint64 Freepages_count uint64 Freepages_delay_total uint64 + Freepages_delay_max uint64 + Freepages_delay_min uint64 Thrashing_count uint64 Thrashing_delay_total uint64 + Thrashing_delay_max uint64 + Thrashing_delay_min uint64 Ac_btime64 uint64 Compact_count uint64 Compact_delay_total uint64 + Compact_delay_max uint64 + Compact_delay_min uint64 Ac_tgid uint32 Ac_tgetime uint64 Ac_exe_dev uint64 Ac_exe_inode uint64 Wpcopy_count uint64 Wpcopy_delay_total uint64 + Wpcopy_delay_max uint64 + Wpcopy_delay_min uint64 Irq_count uint64 Irq_delay_total uint64 + Irq_delay_max uint64 + Irq_delay_min uint64 } type cpuMask uint64 diff --git a/vendor/modules.txt b/vendor/modules.txt index ebdc8318f987500b38cb989a7a0de6bea45caf5f..58b333ebb2ad42f6e6f8c426e8281ab8ce369cab 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -229,7 +229,6 @@ github.com/aymanbagabas/go-osc52/v2 ## explicit; go 1.23 github.com/aymanbagabas/go-udiff github.com/aymanbagabas/go-udiff/lcs -github.com/aymanbagabas/go-udiff/myers # github.com/aymerick/douceur v0.2.0 ## explicit github.com/aymerick/douceur/css @@ -277,7 +276,7 @@ github.com/charmbracelet/lipgloss/v2/tree # github.com/charmbracelet/log/v2 v2.0.0-20250226163916-c379e29ff706 ## explicit; go 1.19 github.com/charmbracelet/log/v2 -# github.com/charmbracelet/ultraviolet v0.0.0-20250708152637-0fe0235c8db9 +# github.com/charmbracelet/ultraviolet v0.0.0-20250716141307-2fae2b322afb ## explicit; go 1.24.0 github.com/charmbracelet/ultraviolet # github.com/charmbracelet/x/ansi v0.9.3 @@ -682,10 +681,10 @@ golang.org/x/net/idna golang.org/x/net/internal/httpcommon golang.org/x/net/internal/timeseries golang.org/x/net/trace -# golang.org/x/sync v0.15.0 +# golang.org/x/sync v0.16.0 ## explicit; go 1.23.0 golang.org/x/sync/errgroup -# golang.org/x/sys v0.33.0 +# golang.org/x/sys v0.34.0 ## explicit; go 1.23.0 golang.org/x/sys/cpu golang.org/x/sys/plan9 From 241909006abdfc43513c19c8385d3b31a88126b2 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 16 Jul 2025 10:31:37 -0400 Subject: [PATCH 18/25] chore: bump dependencies --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3a3c61dc11d7f60e6af41b55a5b0a6be96523547..d28bb8b1d169151a68aa35c84f585c81275ff675 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,9 @@ module github.com/charmbracelet/crush go 1.24.3 -replace github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595 +replace github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250716142813-5d1379f56ba2 -replace github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb +replace github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250716143013-48f34cb75679 require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 diff --git a/go.sum b/go.sum index 07fabb9e21563d1c5bcd9c875a395f3ebd392f56..fcda20ce8845005b128c6b8db337eb07b3ca8d8a 100644 --- a/go.sum +++ b/go.sum @@ -70,16 +70,16 @@ github.com/charlievieth/fastwalk v1.0.11 h1:5sLT/q9+d9xMdpKExawLppqvXFZCVKf6JHnr github.com/charlievieth/fastwalk v1.0.11/go.mod h1:yGy1zbxog41ZVMcKA/i8ojXLFsuayX5VvwhQVoj9PBI= github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198 h1:CkMS9Ah9ac1Ego5JDC5NJyZyAAqu23Z+O0yDwsa3IxM= github.com/charmbracelet/bubbles/v2 v2.0.0-beta.1.0.20250710161907-a4c42b579198/go.mod h1:6HamsBKWqEC/FVHuQMHgQL+knPyvHH55HwJDHl/adMw= -github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595 h1:wLMjzOqrwoM7Em9UR9sGbn4375G8WuxcwFB3kjZiqHo= -github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595/go.mod h1:+Tl7rePElw6OKt382t04zXwtPFoPXxAaJzNrYmtsLds= +github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250716142813-5d1379f56ba2 h1:Gj/vSk7h96TxUU/GSuwbYkr9H0ze+ElAQjcl25wB0+U= +github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250716142813-5d1379f56ba2/go.mod h1:m240IQxo1/eDQ7klblSzOCAUyc3LddHcV3Rc/YEGAgw= github.com/charmbracelet/colorprofile v0.3.1 h1:k8dTHMd7fgw4bnFd7jXTLZrSU/CQrKnL3m+AxCzDz40= github.com/charmbracelet/colorprofile v0.3.1/go.mod h1:/GkGusxNs8VB/RSOh3fu0TJmQ4ICMMPApIIVn0KszZ0= github.com/charmbracelet/fang v0.3.1-0.20250711140230-d5ebb8c1d674 h1:+Cz+VfxD5DO+JT1LlswXWhre0HYLj6l2HW8HVGfMuC0= github.com/charmbracelet/fang v0.3.1-0.20250711140230-d5ebb8c1d674/go.mod h1:9gCUAHmVx5BwSafeyNr3GI0GgvlB1WYjL21SkPp1jyU= github.com/charmbracelet/glamour/v2 v2.0.0-20250516160903-6f1e2c8f9ebe h1:i6ce4CcAlPpTj2ER69m1DBeLZ3RRcHnKExuwhKa3GfY= github.com/charmbracelet/glamour/v2 v2.0.0-20250516160903-6f1e2c8f9ebe/go.mod h1:p3Q+aN4eQKeM5jhrmXPMgPrlKbmc59rWSnMsSA3udhk= -github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb h1:lswj7CYZVYbLn2OhYJsXOMRQQGdRIfyuSnh5FdVSMr0= -github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb/go.mod h1:wEc/TRrTAIDJYjVCg3+y8WeKaN+F88gpYfGbUuP6W3A= +github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250716143013-48f34cb75679 h1:z0og40Sck650PjX51SmiTP8Div2OSugiZJBPZyJInOg= +github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250716143013-48f34cb75679/go.mod h1:BXY7j7rZgAprFwzNcO698++5KTd6GKI6lU83Pr4o0r0= github.com/charmbracelet/log/v2 v2.0.0-20250226163916-c379e29ff706 h1:WkwO6Ks3mSIGnGuSdKl9qDSyfbYK50z2wc2gGMggegE= github.com/charmbracelet/log/v2 v2.0.0-20250226163916-c379e29ff706/go.mod h1:mjJGp00cxcfvD5xdCa+bso251Jt4owrQvuimJtVmEmM= github.com/charmbracelet/ultraviolet v0.0.0-20250716141307-2fae2b322afb h1:fMyaSpuEyPP+uuTu98Wx2S/7OY52uhjF+kYfM5w7x+s= From 0a5339a4b94a3b3bacecba34cbd5b05e5932ad4b Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 16 Jul 2025 10:31:45 -0400 Subject: [PATCH 19/25] chore: update vendors --- .../charmbracelet/bubbletea/v2/tea.go | 2 - .../charmbracelet/lipgloss/v2/canvas.go | 59 ++++++++++++++----- vendor/modules.txt | 8 +-- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/vendor/github.com/charmbracelet/bubbletea/v2/tea.go b/vendor/github.com/charmbracelet/bubbletea/v2/tea.go index 1a6be630366d40aaac4706f9ee1e775306091c4e..b680ede248932b1288937611dec8bc95bd9cc114 100644 --- a/vendor/github.com/charmbracelet/bubbletea/v2/tea.go +++ b/vendor/github.com/charmbracelet/bubbletea/v2/tea.go @@ -320,12 +320,10 @@ type Program struct { // where to read inputs from, this will usually be os.Stdin. input io.Reader - mu sync.Mutex // ttyInput is null if input is not a TTY. ttyInput term.File previousTtyInputState *term.State inputReader *uv.TerminalReader - traceInput bool // true if input should be traced readLoopDone chan struct{} mouseMode bool // indicates whether we should enable mouse on Windows diff --git a/vendor/github.com/charmbracelet/lipgloss/v2/canvas.go b/vendor/github.com/charmbracelet/lipgloss/v2/canvas.go index 587ba044e02c54d7ba197853ed8433ed5602b8d4..f67460b9963193bd11886d13af819a79d35ae5ef 100644 --- a/vendor/github.com/charmbracelet/lipgloss/v2/canvas.go +++ b/vendor/github.com/charmbracelet/lipgloss/v2/canvas.go @@ -1,6 +1,7 @@ package lipgloss import ( + "fmt" "image" "sort" @@ -94,17 +95,14 @@ type Layer struct { zIndex int children []*Layer id string - content string + content uv.Drawable } // NewLayer creates a new Layer with the given content. It calculates the size // based on the widest line and the number of lines in the content. -func NewLayer(content string) (l *Layer) { +func NewLayer(content any) (l *Layer) { l = new(Layer) - l.content = content - height := Height(content) - width := Width(content) - l.rect = image.Rect(0, 0, width, height) + l.SetContent(content) return l } @@ -216,23 +214,56 @@ func (l *Layer) AddLayers(layers ...*Layer) *Layer { } // SetContent sets the content of the Layer. -func (l *Layer) SetContent(content string) *Layer { - l.content = content +func (l *Layer) SetContent(content any) *Layer { + var drawable uv.Drawable + var rect image.Rectangle + switch c := content.(type) { + case uv.Drawable: + drawable = c + switch c := c.(type) { + case interface{ Bounds() image.Rectangle }: + rect.Max.X = c.Bounds().Dx() + rect.Max.Y = c.Bounds().Dy() + case interface { + Width() int + Height() int + }: + rect.Max.X = c.Width() + rect.Max.Y = c.Height() + } + case fmt.Stringer: + s := c.String() + drawable = uv.NewStyledString(s) + rect = image.Rect(0, 0, Width(s), Height(s)) + case string: + drawable = uv.NewStyledString(c) + rect = image.Rect(0, 0, Width(c), Height(c)) + default: + s := fmt.Sprint(content) + drawable = uv.NewStyledString(s) + rect = image.Rect(0, 0, Width(s), Height(s)) + } + l.content = drawable + l.rect = rect return l } // Content returns the content of the Layer. -func (l *Layer) Content() string { +func (l *Layer) Content() any { return l.content } // Draw draws the Layer onto the given screen buffer. -func (l *Layer) Draw(scr uv.Screen, _ image.Rectangle) { - ss := uv.NewStyledString(l.content) - ss.Draw(scr, l.Bounds()) +func (l *Layer) Draw(scr uv.Screen, area image.Rectangle) { + if l.content == nil { + return + } + l.content.Draw(scr, area.Intersect(l.Bounds())) for _, child := range l.children { - ss := uv.NewStyledString(child.content) - ss.Draw(scr, child.Bounds()) + if child.content == nil { + continue + } + child.content.Draw(scr, area.Intersect(child.Bounds())) } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 58b333ebb2ad42f6e6f8c426e8281ab8ce369cab..05b8504bdbb4df51e69c5a5eb7d49aec857144a3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -253,7 +253,7 @@ github.com/charmbracelet/bubbles/v2/spinner github.com/charmbracelet/bubbles/v2/textarea github.com/charmbracelet/bubbles/v2/textinput github.com/charmbracelet/bubbles/v2/viewport -# github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.1 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595 +# github.com/charmbracelet/bubbletea/v2 v2.0.0-beta.1 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250716142813-5d1379f56ba2 ## explicit; go 1.24.0 github.com/charmbracelet/bubbletea/v2 # github.com/charmbracelet/colorprofile v0.3.1 @@ -268,7 +268,7 @@ github.com/charmbracelet/glamour/v2 github.com/charmbracelet/glamour/v2/ansi github.com/charmbracelet/glamour/v2/internal/autolink github.com/charmbracelet/glamour/v2/styles -# github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.3 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb +# github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.3 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250716143013-48f34cb75679 ## explicit; go 1.24.2 github.com/charmbracelet/lipgloss/v2 github.com/charmbracelet/lipgloss/v2/table @@ -837,5 +837,5 @@ mvdan.cc/sh/v3/fileutil mvdan.cc/sh/v3/interp mvdan.cc/sh/v3/pattern mvdan.cc/sh/v3/syntax -# github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250710185017-3c0ffd25e595 -# github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250710185058-03664cb9cecb +# github.com/charmbracelet/bubbletea/v2 => github.com/charmbracelet/bubbletea-internal/v2 v2.0.0-20250716142813-5d1379f56ba2 +# github.com/charmbracelet/lipgloss/v2 => github.com/charmbracelet/lipgloss-internal/v2 v2.0.0-20250716143013-48f34cb75679 From 39c637385f05d0187dc6877f17402eea6b93f85d Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Wed, 16 Jul 2025 15:46:13 -0300 Subject: [PATCH 20/25] chore: update `Co-Authored-By` address to `crush@charm.land` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 💘 Crush --- internal/llm/tools/bash.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/llm/tools/bash.go b/internal/llm/tools/bash.go index 3b6d94de7687a0a0842c44b64fc3d0ab55a785c3..abc5deb3dc8d80401f452a57c9735128dd5e91d1 100644 --- a/internal/llm/tools/bash.go +++ b/internal/llm/tools/bash.go @@ -188,7 +188,7 @@ When the user asks you to create a new git commit, follow these steps carefully: 4. Create the commit with a message ending with: 💘 Generated with Crush -Co-Authored-By: Crush +Co-Authored-By: Crush - In order to ensure good formatting, ALWAYS pass the commit message via a HEREDOC, a la this example: @@ -196,7 +196,7 @@ git commit -m "$(cat <<'EOF' Commit message here. 💘 Generated with Crush - Co-Authored-By: 💘 Crush + Co-Authored-By: 💘 Crush EOF )" From 41efff793642f2def97fef1dbf5264eee1d895dc Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Tue, 15 Jul 2025 11:17:12 -0400 Subject: [PATCH 21/25] fix(tui): completions: close and reset completions on cancel key This change ensures that when the cancel key is pressed, the completions component is closed and reset, preventing any lingering state that could affect subsequent interactions. --- internal/tui/components/completions/completions.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/internal/tui/components/completions/completions.go b/internal/tui/components/completions/completions.go index dd39fa834c053d752289d608faabdbe0a199ca37..aa98caae380df109662c33dcaa1a766e9acdfdb1 100644 --- a/internal/tui/components/completions/completions.go +++ b/internal/tui/components/completions/completions.go @@ -118,10 +118,7 @@ func (c *completionsCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { Value: selectedItem, }) case key.Matches(msg, c.keyMap.Cancel): - if c.open { - c.open = false - return c, util.CmdHandler(CompletionsClosedMsg{}) - } + return c, util.CmdHandler(CloseCompletionsMsg{}) } case CloseCompletionsMsg: c.open = false From acf354ec9dcdbe75ebf1e9cdae79e2fbcfac46a2 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 16 Jul 2025 16:22:50 -0400 Subject: [PATCH 22/25] fix(tui): escape control characters in tool call content --- .../tui/components/chat/messages/renderer.go | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/internal/tui/components/chat/messages/renderer.go b/internal/tui/components/chat/messages/renderer.go index 87eb2c8476655fe7d11fc8c787e73b32d4584de4..162b98aec2da8fd2b98ae9c46ebc64cb9effec8e 100644 --- a/internal/tui/components/chat/messages/renderer.go +++ b/internal/tui/components/chat/messages/renderer.go @@ -655,6 +655,7 @@ func joinHeaderBody(header, body string) string { func renderPlainContent(v *toolCallCmp, content string) string { t := styles.CurrentTheme() + content = strings.ReplaceAll(content, "\r\n", "\n") // Normalize line endings content = strings.TrimSpace(content) lines := strings.Split(content, "\n") @@ -664,6 +665,7 @@ func renderPlainContent(v *toolCallCmp, content string) string { if i >= responseContextHeight { break } + ln = escapeContent(ln) ln = " " + ln // left padding if len(ln) > width { ln = v.fit(ln, width) @@ -680,6 +682,7 @@ func renderPlainContent(v *toolCallCmp, content string) string { Width(width). Render(fmt.Sprintf("… (%d lines)", len(lines)-responseContextHeight))) } + return strings.Join(out, "\n") } @@ -694,10 +697,17 @@ func pad(v any, width int) string { func renderCodeContent(v *toolCallCmp, path, content string, offset int) string { t := styles.CurrentTheme() + content = strings.ReplaceAll(content, "\r\n", "\n") // Normalize line endings + content = strings.ReplaceAll(content, "\t", " ") // Replace tabs with spaces truncated := truncateHeight(content, responseContextHeight) - highlighted, _ := highlight.SyntaxHighlight(truncated, path, t.BgBase) - lines := strings.Split(highlighted, "\n") + lines := strings.Split(truncated, "\n") + for i, ln := range lines { + lines[i] = escapeContent(ln) + } + + highlighted, _ := highlight.SyntaxHighlight(strings.Join(lines, "\n"), path, t.BgBase) + lines = strings.Split(highlighted, "\n") if len(strings.Split(content, "\n")) > responseContextHeight { lines = append(lines, t.S().Muted. @@ -721,6 +731,7 @@ func renderCodeContent(v *toolCallCmp, path, content string, offset int) string PaddingLeft(1). Render(v.fit(ln, w-1))) } + return lipgloss.JoinVertical(lipgloss.Left, lines...) } @@ -766,3 +777,20 @@ func prettifyToolName(name string) string { return name } } + +// escapeContent replaces control characters with their Unicode Control Picture +// representations to ensure they are displayed correctly in the UI. +func escapeContent(content string) string { + var sb strings.Builder + for _, r := range content { + switch { + case r >= 0 && r <= 0x1f: // Control characters 0x00-0x1F + sb.WriteRune('\u2400' + r) + case r == ansi.DEL: + sb.WriteRune('\u2421') + default: + sb.WriteRune(r) + } + } + return sb.String() +} From 08c5b4c1327783b2c674d93600604e90cc4d4410 Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Wed, 16 Jul 2025 22:31:14 +0200 Subject: [PATCH 23/25] fix(logs): limit the logs output --- cmd/logs.go | 168 ++++++++++++++++++++++++++++------------------------ 1 file changed, 89 insertions(+), 79 deletions(-) diff --git a/cmd/logs.go b/cmd/logs.go index bb0aaf9d7b8c2cbcf1da8823c2848002f6d2e252..aef7639a5d0ad9ed97756fbf204319fb9c274952 100644 --- a/cmd/logs.go +++ b/cmd/logs.go @@ -1,14 +1,13 @@ package cmd import ( - "bufio" + "context" "encoding/json" "fmt" "io" "os" "path/filepath" "slices" - "strings" "time" "github.com/charmbracelet/crush/internal/config" @@ -17,6 +16,8 @@ import ( "github.com/spf13/cobra" ) +const defaultTailLines = 1000 + var logsCmd = &cobra.Command{ Use: "logs", Short: "View crush logs", @@ -38,7 +39,6 @@ var logsCmd = &cobra.Command{ } log.SetLevel(log.DebugLevel) - // Configure log to output to stdout instead of stderr log.SetOutput(os.Stdout) cfg, err := config.Load(cwd, false) @@ -53,104 +53,114 @@ var logsCmd = &cobra.Command{ } if follow { - // Follow mode - tail the file continuously - t, err := tail.TailFile(logsFile, tail.Config{Follow: true, ReOpen: true, Logger: tail.DiscardingLogger}) - if err != nil { - return fmt.Errorf("failed to tail log file: %v", err) - } - - // Print the text of each received line - for line := range t.Lines { - printLogLine(line.Text) - } - } else if tailLines > 0 { - // Tail mode - show last N lines - lines, err := readLastNLines(logsFile, tailLines) - if err != nil { - return fmt.Errorf("failed to read last %d lines: %v", tailLines, err) - } - for _, line := range lines { - printLogLine(line) - } - } else { - // Oneshot mode - read the entire file once - file, err := os.Open(logsFile) - if err != nil { - return fmt.Errorf("failed to open log file: %v", err) - } - defer file.Close() - - reader := bufio.NewReader(file) - for { - line, err := reader.ReadString('\n') - if err != nil { - if err == io.EOF && line != "" { - // Handle last line without newline - printLogLine(line) - } - break - } - // Remove trailing newline - line = strings.TrimSuffix(line, "\n") - printLogLine(line) - } + return followLogs(cmd.Context(), logsFile, tailLines) } - return nil + return showLogs(logsFile, tailLines) }, } func init() { logsCmd.Flags().BoolP("follow", "f", false, "Follow log output") - logsCmd.Flags().IntP("tail", "t", 0, "Show only the last N lines") + logsCmd.Flags().IntP("tail", "t", defaultTailLines, "Show only the last N lines default: 1000 for performance") rootCmd.AddCommand(logsCmd) } -// readLastNLines reads the last N lines from a file using a simple circular buffer approach -func readLastNLines(filename string, n int) ([]string, error) { - file, err := os.Open(filename) +func followLogs(ctx context.Context, logsFile string, tailLines int) error { + t, err := tail.TailFile(logsFile, tail.Config{ + Follow: false, + ReOpen: false, + Logger: tail.DiscardingLogger, + }) if err != nil { - return nil, err + return fmt.Errorf("failed to tail log file: %v", err) } - defer file.Close() - // Use a circular buffer to keep only the last N lines - lines := make([]string, n) - count := 0 - index := 0 + var lines []string + lineCount := 0 + for line := range t.Lines { + if line.Err != nil { + continue + } + lines = append(lines, line.Text) + lineCount++ + if lineCount >= tailLines { + if len(lines) > tailLines { + lines = lines[len(lines)-tailLines:] + } + } + } + t.Stop() + + for _, line := range lines { + printLogLine(line) + } + + if len(lines) == tailLines { + fmt.Fprintf(os.Stderr, "\nShowing last %d lines. Full logs available at: %s\n", tailLines, logsFile) + fmt.Fprintf(os.Stderr, "Following new log entries...\n\n") + } + + t, err = tail.TailFile(logsFile, tail.Config{ + Follow: true, + ReOpen: true, + Logger: tail.DiscardingLogger, + Location: &tail.SeekInfo{Offset: 0, Whence: io.SeekEnd}, + }) + if err != nil { + return fmt.Errorf("failed to tail log file: %v", err) + } + defer t.Stop() - reader := bufio.NewReader(file) for { - line, err := reader.ReadString('\n') - if err != nil { - if err == io.EOF && line != "" { - // Handle last line without newline - line = strings.TrimSuffix(line, "\n") - lines[index] = line - count++ - index = (index + 1) % n + select { + case line := <-t.Lines: + if line.Err != nil { + continue + } + printLogLine(line.Text) + case <-ctx.Done(): + return nil + } + } +} + +func showLogs(logsFile string, tailLines int) error { + t, err := tail.TailFile(logsFile, tail.Config{ + Follow: false, + ReOpen: false, + Logger: tail.DiscardingLogger, + MaxLineSize: 0, + }) + if err != nil { + return fmt.Errorf("failed to tail log file: %v", err) + } + defer t.Stop() + + var lines []string + lineCount := 0 + for line := range t.Lines { + if line.Err != nil { + continue + } + lines = append(lines, line.Text) + lineCount++ + if lineCount >= tailLines { + if len(lines) > tailLines { + lines = lines[len(lines)-tailLines:] } - break } - // Remove trailing newline - line = strings.TrimSuffix(line, "\n") - lines[index] = line - count++ - index = (index + 1) % n } - // Extract the last N lines in correct order - if count <= n { - // We have fewer lines than requested, return them all - return lines[:count], nil + for _, line := range lines { + printLogLine(line) } - // We have more lines than requested, extract from circular buffer - result := make([]string, n) - for i := range n { - result[i] = lines[(index+i)%n] + if len(lines) == tailLines { + fmt.Fprintf(os.Stderr, "\nShowing last %d lines. Full logs available at: %s\n", tailLines, logsFile) } - return result, nil + + return nil } func printLogLine(lineText string) { From e953ded616943c35018b1af7f76fc708a5b14b40 Mon Sep 17 00:00:00 2001 From: Kujtim Hoxha Date: Wed, 16 Jul 2025 23:12:34 +0200 Subject: [PATCH 24/25] chore: fix permissions dialog --- internal/tui/components/dialogs/permissions/permissions.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/tui/components/dialogs/permissions/permissions.go b/internal/tui/components/dialogs/permissions/permissions.go index 7e0d27eb46ea398d34f5b8073dc1413df9cce828..dd8668ad393fefdb0161a933f6baf7e7250ce05d 100644 --- a/internal/tui/components/dialogs/permissions/permissions.go +++ b/internal/tui/components/dialogs/permissions/permissions.go @@ -16,6 +16,7 @@ import ( "github.com/charmbracelet/crush/internal/tui/styles" "github.com/charmbracelet/crush/internal/tui/util" "github.com/charmbracelet/lipgloss/v2" + "github.com/charmbracelet/x/ansi" ) type PermissionAction string From 78aea799d9e569b6471ecf4aa68f930ebbacac96 Mon Sep 17 00:00:00 2001 From: gjergj Date: Wed, 16 Jul 2025 23:31:50 +0200 Subject: [PATCH 25/25] fix nil pointer dereference when there's no provider for specific model --- internal/llm/agent/agent.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/llm/agent/agent.go b/internal/llm/agent/agent.go index 107bdd0a23529a8a1e441ab5d55714a0315c7473..4e8070158652f04205f51ca6d38ba1f5db81ef2a 100644 --- a/internal/llm/agent/agent.go +++ b/internal/llm/agent/agent.go @@ -859,7 +859,7 @@ func (a *agent) UpdateModel() error { // Get current provider configuration currentProviderCfg := cfg.GetProviderForModel(a.agentCfg.Model) - if currentProviderCfg.ID == "" { + if currentProviderCfg == nil || currentProviderCfg.ID == "" { return fmt.Errorf("provider for agent %s not found in config", a.agentCfg.Name) }