|
@@ -423,9 +423,11 @@ func renderToolDetails(
|
|
|
case "completed":
|
|
case "completed":
|
|
|
body += fmt.Sprintf("- [x] %s\n", content)
|
|
body += fmt.Sprintf("- [x] %s\n", content)
|
|
|
case "cancelled":
|
|
case "cancelled":
|
|
|
- body += fmt.Sprintf("- [~] %s\n", content)
|
|
|
|
|
- // case "in-progress":
|
|
|
|
|
- // body += fmt.Sprintf("- [ ] %s\n", content)
|
|
|
|
|
|
|
+ // strike through cancelled todo
|
|
|
|
|
+ body += fmt.Sprintf("- [~] ~~%s~~\n", content)
|
|
|
|
|
+ case "in_progress":
|
|
|
|
|
+ // highlight in progress todo
|
|
|
|
|
+ body += fmt.Sprintf("- [ ] `%s`\n", content)
|
|
|
default:
|
|
default:
|
|
|
body += fmt.Sprintf("- [ ] %s\n", content)
|
|
body += fmt.Sprintf("- [ ] %s\n", content)
|
|
|
}
|
|
}
|
|
@@ -489,8 +491,6 @@ func renderToolName(name string) string {
|
|
|
switch name {
|
|
switch name {
|
|
|
case "webfetch":
|
|
case "webfetch":
|
|
|
return "Fetch"
|
|
return "Fetch"
|
|
|
- case "todowrite", "todoread":
|
|
|
|
|
- return "Plan"
|
|
|
|
|
default:
|
|
default:
|
|
|
normalizedName := name
|
|
normalizedName := name
|
|
|
if after, ok := strings.CutPrefix(name, "opencode_"); ok {
|
|
if after, ok := strings.CutPrefix(name, "opencode_"); ok {
|
|
@@ -500,6 +500,41 @@ func renderToolName(name string) string {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func getTodoPhase(metadata map[string]any) string {
|
|
|
|
|
+ todos, ok := metadata["todos"].([]any)
|
|
|
|
|
+ if !ok || len(todos) == 0 {
|
|
|
|
|
+ return "Plan"
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ counts := map[string]int{"pending": 0, "completed": 0}
|
|
|
|
|
+ for _, item := range todos {
|
|
|
|
|
+ if todo, ok := item.(map[string]any); ok {
|
|
|
|
|
+ if status, ok := todo["status"].(string); ok {
|
|
|
|
|
+ counts[status]++
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ total := len(todos)
|
|
|
|
|
+ switch {
|
|
|
|
|
+ case counts["pending"] == total:
|
|
|
|
|
+ return "Creating plan"
|
|
|
|
|
+ case counts["completed"] == total:
|
|
|
|
|
+ return "Completing plan"
|
|
|
|
|
+ default:
|
|
|
|
|
+ return "Updating plan"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func getTodoTitle(toolCall opencode.ToolPart) string {
|
|
|
|
|
+ if toolCall.State.Status == opencode.ToolPartStateStatusCompleted {
|
|
|
|
|
+ if metadata, ok := toolCall.State.Metadata.(map[string]any); ok {
|
|
|
|
|
+ return getTodoPhase(metadata)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return "Plan"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func renderToolTitle(
|
|
func renderToolTitle(
|
|
|
toolCall opencode.ToolPart,
|
|
toolCall opencode.ToolPart,
|
|
|
width int,
|
|
width int,
|
|
@@ -547,8 +582,10 @@ func renderToolTitle(
|
|
|
case "webfetch":
|
|
case "webfetch":
|
|
|
toolArgs = renderArgs(&toolArgsMap, "url")
|
|
toolArgs = renderArgs(&toolArgsMap, "url")
|
|
|
title = fmt.Sprintf("%s %s", title, toolArgs)
|
|
title = fmt.Sprintf("%s %s", title, toolArgs)
|
|
|
- case "todowrite", "todoread":
|
|
|
|
|
- // title is just the tool name
|
|
|
|
|
|
|
+ case "todowrite":
|
|
|
|
|
+ title = getTodoTitle(toolCall)
|
|
|
|
|
+ case "todoread":
|
|
|
|
|
+ return "Plan"
|
|
|
default:
|
|
default:
|
|
|
toolName := renderToolName(toolCall.Tool)
|
|
toolName := renderToolName(toolCall.Tool)
|
|
|
title = fmt.Sprintf("%s %s", toolName, toolArgs)
|
|
title = fmt.Sprintf("%s %s", toolName, toolArgs)
|