bash.go

 1package chat
 2
 3import (
 4	"encoding/json"
 5	"strings"
 6
 7	"github.com/charmbracelet/crush/internal/agent/tools"
 8	"github.com/charmbracelet/crush/internal/ui/styles"
 9)
10
11// BashToolRenderer renders a bash tool call.
12func BashToolRenderer(sty *styles.Styles, width int, opts *ToolRenderOpts) string {
13	cappedWidth := cappedMessageWidth(width)
14	const toolName = "Bash"
15	if !opts.ToolCall.Finished && !opts.Canceled {
16		return pendingTool(sty, toolName, opts.Anim)
17	}
18
19	var params tools.BashParams
20	var cmd string
21	err := json.Unmarshal([]byte(opts.ToolCall.Input), &params)
22
23	if err != nil {
24		cmd = "failed to parse command"
25	} else {
26		cmd = strings.ReplaceAll(params.Command, "\n", " ")
27		cmd = strings.ReplaceAll(cmd, "\t", "    ")
28	}
29
30	// TODO: if the tool is being run in the background use the background job renderer
31
32	toolParams := []string{
33		cmd,
34	}
35
36	if params.RunInBackground {
37		toolParams = append(toolParams, "background", "true")
38	}
39
40	header := toolHeader(sty, opts.Status(), "Bash", cappedWidth, toolParams...)
41
42	if opts.Nested {
43		return header
44	}
45
46	earlyStateContent, ok := toolEarlyStateContent(sty, opts, cappedWidth)
47
48	// If this is OK that means that the tool is not done yet or it was canceled
49	if ok {
50		return strings.Join([]string{header, "", earlyStateContent}, "\n")
51	}
52
53	if opts.Result == nil {
54		// We should not get here!
55		return header
56	}
57
58	var meta tools.BashResponseMetadata
59	err = json.Unmarshal([]byte(opts.Result.Metadata), &meta)
60
61	var output string
62	if err != nil {
63		output = "failed to parse output"
64	}
65	output = meta.Output
66	if output == "" && opts.Result.Content != tools.BashNoOutput {
67		output = opts.Result.Content
68	}
69
70	if output == "" {
71		return header
72	}
73
74	bodyWidth := cappedWidth - toolBodyLeftPaddingTotal
75
76	output = sty.Tool.Body.Render(toolOutputPlainContent(sty, output, bodyWidth, opts.Expanded))
77
78	return strings.Join([]string{header, "", output}, "\n")
79}