summaryrefslogtreecommitdiffhomepage
path: root/packages/tui/internal
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-07-15 00:05:54 -0400
committerDax Raad <[email protected]>2025-07-15 00:05:54 -0400
commit4b2ce14ff322c4a6437d490500e71b6082acb2c2 (patch)
treeedf6d2b511ad805b17101cc011955b32ba0e4d49 /packages/tui/internal
parent294a11752e8cc4b315b22a4df320ef5ce9fa5345 (diff)
downloadopencode-4b2ce14ff322c4a6437d490500e71b6082acb2c2.tar.gz
opencode-4b2ce14ff322c4a6437d490500e71b6082acb2c2.zip
bring back task tool
Diffstat (limited to 'packages/tui/internal')
-rw-r--r--packages/tui/internal/components/chat/message.go229
1 files changed, 111 insertions, 118 deletions
diff --git a/packages/tui/internal/components/chat/message.go b/packages/tui/internal/components/chat/message.go
index b2a5d7166..f6a4604c3 100644
--- a/packages/tui/internal/components/chat/message.go
+++ b/packages/tui/internal/components/chat/message.go
@@ -305,10 +305,8 @@ func renderToolDetails(
return ""
}
- if toolCall.State.Status == opencode.ToolPartStateStatusPending ||
- toolCall.State.Status == opencode.ToolPartStateStatusRunning {
+ if toolCall.State.Status == opencode.ToolPartStateStatusPending {
title := renderToolTitle(toolCall, width)
- title = styles.NewStyle().Width(width - 6).Render(title)
return renderContentBlock(app, title, highlight, width)
}
@@ -339,128 +337,124 @@ func renderToolDetails(
borderColor = t.BorderActive()
}
- if toolCall.State.Status == opencode.ToolPartStateStatusCompleted {
- metadata := toolCall.State.Metadata.(map[string]any)
- switch toolCall.Tool {
- case "read":
- preview := metadata["preview"]
- if preview != nil && toolInputMap["filePath"] != nil {
- filename := toolInputMap["filePath"].(string)
- body = preview.(string)
- body = util.RenderFile(filename, body, width, util.WithTruncate(6))
- }
- case "edit":
- if filename, ok := toolInputMap["filePath"].(string); ok {
- diffField := metadata["diff"]
- if diffField != nil {
- patch := diffField.(string)
- var formattedDiff string
- formattedDiff, _ = diff.FormatUnifiedDiff(
- filename,
- patch,
- diff.WithWidth(width-2),
- )
- body = strings.TrimSpace(formattedDiff)
- style := styles.NewStyle().
- Background(backgroundColor).
- Foreground(t.TextMuted()).
- Padding(1, 2).
- Width(width - 4)
- if highlight {
- style = style.Foreground(t.Text()).Bold(true)
- }
-
- if diagnostics := renderDiagnostics(metadata, filename); diagnostics != "" {
- diagnostics = style.Render(diagnostics)
- body += "\n" + diagnostics
- }
-
- title := renderToolTitle(toolCall, width)
- title = style.Render(title)
- content := title + "\n" + body
- content = renderContentBlock(
- app,
- content,
- highlight,
- width,
- WithPadding(0),
- WithBorderColor(borderColor),
- )
- return content
+ metadata := toolCall.State.Metadata.(map[string]any)
+ switch toolCall.Tool {
+ case "read":
+ preview := metadata["preview"]
+ if preview != nil && toolInputMap["filePath"] != nil {
+ filename := toolInputMap["filePath"].(string)
+ body = preview.(string)
+ body = util.RenderFile(filename, body, width, util.WithTruncate(6))
+ }
+ case "edit":
+ if filename, ok := toolInputMap["filePath"].(string); ok {
+ diffField := metadata["diff"]
+ if diffField != nil {
+ patch := diffField.(string)
+ var formattedDiff string
+ formattedDiff, _ = diff.FormatUnifiedDiff(
+ filename,
+ patch,
+ diff.WithWidth(width-2),
+ )
+ body = strings.TrimSpace(formattedDiff)
+ style := styles.NewStyle().
+ Background(backgroundColor).
+ Foreground(t.TextMuted()).
+ Padding(1, 2).
+ Width(width - 4)
+ if highlight {
+ style = style.Foreground(t.Text()).Bold(true)
}
- }
- case "write":
- if filename, ok := toolInputMap["filePath"].(string); ok {
- if content, ok := toolInputMap["content"].(string); ok {
- body = util.RenderFile(filename, content, width)
- if diagnostics := renderDiagnostics(metadata, filename); diagnostics != "" {
- body += "\n\n" + diagnostics
- }
+
+ if diagnostics := renderDiagnostics(metadata, filename); diagnostics != "" {
+ diagnostics = style.Render(diagnostics)
+ body += "\n" + diagnostics
}
+
+ title := renderToolTitle(toolCall, width)
+ title = style.Render(title)
+ content := title + "\n" + body
+ content = renderContentBlock(
+ app,
+ content,
+ highlight,
+ width,
+ WithPadding(0),
+ WithBorderColor(borderColor),
+ )
+ return content
}
- case "bash":
- stdout := metadata["stdout"]
- if stdout != nil {
- command := toolInputMap["command"].(string)
- body = fmt.Sprintf("```console\n> %s\n%s```", command, stdout)
- body = util.ToMarkdown(body, width, backgroundColor)
- }
- case "webfetch":
- if format, ok := toolInputMap["format"].(string); ok && result != nil {
- body = *result
- body = util.TruncateHeight(body, 10)
- if format == "html" || format == "markdown" {
- body = util.ToMarkdown(body, width, backgroundColor)
+ }
+ case "write":
+ if filename, ok := toolInputMap["filePath"].(string); ok {
+ if content, ok := toolInputMap["content"].(string); ok {
+ body = util.RenderFile(filename, content, width)
+ if diagnostics := renderDiagnostics(metadata, filename); diagnostics != "" {
+ body += "\n\n" + diagnostics
}
}
- case "todowrite":
- todos := metadata["todos"]
- if todos != nil {
- for _, item := range todos.([]any) {
- todo := item.(map[string]any)
- content := todo["content"].(string)
- switch todo["status"] {
- case "completed":
- body += fmt.Sprintf("- [x] %s\n", content)
- case "cancelled":
- // strike through cancelled todo
- body += fmt.Sprintf("- [~] ~~%s~~\n", content)
- case "in_progress":
- // highlight in progress todo
- body += fmt.Sprintf("- [ ] `%s`\n", content)
- default:
- body += fmt.Sprintf("- [ ] %s\n", content)
- }
- }
+ }
+ case "bash":
+ stdout := metadata["stdout"]
+ if stdout != nil {
+ command := toolInputMap["command"].(string)
+ body = fmt.Sprintf("```console\n> %s\n%s```", command, stdout)
+ body = util.ToMarkdown(body, width, backgroundColor)
+ }
+ case "webfetch":
+ if format, ok := toolInputMap["format"].(string); ok && result != nil {
+ body = *result
+ body = util.TruncateHeight(body, 10)
+ if format == "html" || format == "markdown" {
body = util.ToMarkdown(body, width, backgroundColor)
}
- case "task":
- summary := metadata["summary"]
- if summary != nil {
- toolcalls := summary.([]any)
- steps := []string{}
- for _, toolcall := range toolcalls {
- call := toolcall.(map[string]any)
- if toolInvocation, ok := call["toolInvocation"].(map[string]any); ok {
- data, _ := json.Marshal(toolInvocation)
- var toolCall opencode.ToolPart
- _ = json.Unmarshal(data, &toolCall)
- step := renderToolTitle(toolCall, width)
- step = "∟ " + step
- steps = append(steps, step)
- }
+ }
+ case "todowrite":
+ todos := metadata["todos"]
+ if todos != nil {
+ for _, item := range todos.([]any) {
+ todo := item.(map[string]any)
+ content := todo["content"].(string)
+ switch todo["status"] {
+ case "completed":
+ body += fmt.Sprintf("- [x] %s\n", content)
+ case "cancelled":
+ // strike through cancelled todo
+ body += fmt.Sprintf("- [~] ~~%s~~\n", content)
+ case "in_progress":
+ // highlight in progress todo
+ body += fmt.Sprintf("- [ ] `%s`\n", content)
+ default:
+ body += fmt.Sprintf("- [ ] %s\n", content)
}
- body = strings.Join(steps, "\n")
}
- default:
- if result == nil {
- empty := ""
- result = &empty
+ body = util.ToMarkdown(body, width, backgroundColor)
+ }
+ case "task":
+ summary := metadata["summary"]
+ if summary != nil {
+ toolcalls := summary.([]any)
+ steps := []string{}
+ for _, item := range toolcalls {
+ data, _ := json.Marshal(item)
+ var toolCall opencode.ToolPart
+ _ = json.Unmarshal(data, &toolCall)
+ step := renderToolTitle(toolCall, width)
+ step = "∟ " + step
+ steps = append(steps, step)
}
- body = *result
- body = util.TruncateHeight(body, 10)
- body = styles.NewStyle().Width(width - 6).Render(body)
+ body = strings.Join(steps, "\n")
}
+ body = styles.NewStyle().Width(width - 6).Render(body)
+ default:
+ if result == nil {
+ empty := ""
+ result = &empty
+ }
+ body = *result
+ body = util.TruncateHeight(body, 10)
+ body = styles.NewStyle().Width(width - 6).Render(body)
}
error := ""
@@ -539,10 +533,9 @@ func renderToolTitle(
toolCall opencode.ToolPart,
width int,
) string {
- // TODO: handle truncate to width
-
if toolCall.State.Status == opencode.ToolPartStateStatusPending {
- return renderToolAction(toolCall.Tool)
+ title := renderToolAction(toolCall.Tool)
+ return styles.NewStyle().Width(width - 6).Render(title)
}
toolArgs := ""
@@ -596,7 +589,7 @@ func renderToolTitle(
func renderToolAction(name string) string {
switch name {
case "task":
- return "Searching..."
+ return "Planning..."
case "bash":
return "Writing command..."
case "edit":