Просмотр исходного кода

tweak: plan interactions should match web (TUI) (#895)

Aiden Cline 7 месяцев назад
Родитель
Сommit
97a31ddffc
1 измененных файлов с 44 добавлено и 7 удалено
  1. 44 7
      packages/tui/internal/components/chat/message.go

+ 44 - 7
packages/tui/internal/components/chat/message.go

@@ -423,9 +423,11 @@ func renderToolDetails(
 					case "completed":
 						body += fmt.Sprintf("- [x] %s\n", content)
 					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:
 						body += fmt.Sprintf("- [ ] %s\n", content)
 					}
@@ -489,8 +491,6 @@ func renderToolName(name string) string {
 	switch name {
 	case "webfetch":
 		return "Fetch"
-	case "todowrite", "todoread":
-		return "Plan"
 	default:
 		normalizedName := name
 		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(
 	toolCall opencode.ToolPart,
 	width int,
@@ -547,8 +582,10 @@ func renderToolTitle(
 	case "webfetch":
 		toolArgs = renderArgs(&toolArgsMap, "url")
 		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:
 		toolName := renderToolName(toolCall.Tool)
 		title = fmt.Sprintf("%s %s", toolName, toolArgs)