|
| 1 | +import type { HistoryItem } from "@roo-code/types" |
| 2 | + |
| 3 | +import type { ClineProvider } from "./ClineProvider" |
| 4 | +import type { WebviewMessage } from "../../shared/WebviewMessage" |
| 5 | + |
| 6 | +/** |
| 7 | + * Normalizes a title string by trimming whitespace and returning undefined for empty strings. |
| 8 | + */ |
| 9 | +function normalizeTitle(title: string | undefined | null): string | undefined { |
| 10 | + if (!title) return undefined |
| 11 | + const trimmed = title.trim() |
| 12 | + return trimmed.length > 0 ? trimmed : undefined |
| 13 | +} |
| 14 | + |
| 15 | +/** |
| 16 | + * Handles the setTaskTitle webview message. |
| 17 | + * Updates task titles for one or more history items, with deduplication and no-op detection. |
| 18 | + */ |
| 19 | +export async function handleSetTaskTitle(provider: ClineProvider, message: WebviewMessage): Promise<void> { |
| 20 | + // 1. Validate and deduplicate incoming task IDs |
| 21 | + const ids = Array.isArray(message.ids) |
| 22 | + ? Array.from(new Set(message.ids.filter((id): id is string => typeof id === "string" && id.trim().length > 0))) |
| 23 | + : [] |
| 24 | + |
| 25 | + if (ids.length === 0) { |
| 26 | + return |
| 27 | + } |
| 28 | + |
| 29 | + // 2. Normalize the incoming title |
| 30 | + const normalizedTitle = normalizeTitle(message.text) |
| 31 | + |
| 32 | + // 3. Get task history from state |
| 33 | + const { taskHistory } = await provider.getState() |
| 34 | + if (!Array.isArray(taskHistory) || taskHistory.length === 0) { |
| 35 | + return |
| 36 | + } |
| 37 | + |
| 38 | + // 4. Create a map for O(1) lookups |
| 39 | + const historyById = new Map(taskHistory.map((item) => [item.id, item] as const)) |
| 40 | + |
| 41 | + // 5. Process each ID, skipping no-ops |
| 42 | + let hasUpdates = false |
| 43 | + |
| 44 | + for (const id of ids) { |
| 45 | + const existingItem = historyById.get(id) |
| 46 | + if (!existingItem) { |
| 47 | + console.warn(`[setTaskTitle] Unable to locate task history item with id ${id}`) |
| 48 | + continue |
| 49 | + } |
| 50 | + |
| 51 | + // Normalize existing title for comparison |
| 52 | + const normalizedExistingTitle = normalizeTitle(existingItem.title) |
| 53 | + |
| 54 | + // Skip if title is unchanged |
| 55 | + if (normalizedExistingTitle === normalizedTitle) { |
| 56 | + continue |
| 57 | + } |
| 58 | + |
| 59 | + // Update the history item |
| 60 | + const updatedItem: HistoryItem = { |
| 61 | + ...existingItem, |
| 62 | + title: normalizedTitle, |
| 63 | + } |
| 64 | + |
| 65 | + await provider.updateTaskHistory(updatedItem) |
| 66 | + hasUpdates = true |
| 67 | + } |
| 68 | + |
| 69 | + // 6. Sync webview state if there were changes |
| 70 | + if (hasUpdates) { |
| 71 | + await provider.postStateToWebview() |
| 72 | + } |
| 73 | +} |
0 commit comments