Parcourir la source

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

Aiden Cline il y a 7 mois
Parent
commit
97a31ddffc
1 fichiers modifiés avec 44 ajouts et 7 suppressions
  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":
 					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)