Skip to content

Commit 0f95e9a

Browse files
committed
feat: internationalize task metadata fallback names
- Add translation support to taskMetadata.ts using t() function - Add 'incomplete' and 'no_messages' keys to all supported locales - Replace hardcoded English strings with i18n keys: - 'Task #{{taskNumber}} (Incomplete)' → 'common:tasks.incomplete' - 'Task #{{taskNumber}} (No messages)' → 'common:tasks.no_messages' - Translations added for all 16 supported languages: ca, de, en, es, fr, hi, it, ja, ko, nl, pl, pt-BR, ru, tr, vi, zh-CN, zh-TW - Verified complete translation coverage with missing translations script Addresses internationalization of task history display names
1 parent 0585487 commit 0f95e9a

File tree

18 files changed

+96
-63
lines changed

18 files changed

+96
-63
lines changed

src/core/task-persistence/taskMetadata.ts

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { combineCommandSequences } from "../../shared/combineCommandSequences"
88
import { getApiMetrics } from "../../shared/getApiMetrics"
99
import { findLastIndex } from "../../shared/array"
1010
import { getTaskDirectoryPath } from "../../utils/storage"
11+
import { t } from "../../i18n"
1112

1213
const taskSizeCache = new NodeCache({ stdTTL: 30, checkperiod: 5 * 60 })
1314

@@ -28,64 +29,62 @@ export async function taskMetadata({
2829
}: TaskMetadataOptions) {
2930
const taskDir = await getTaskDirectoryPath(globalStoragePath, taskId)
3031

31-
// Handle edge case where there are no messages at all
32-
if (!messages || messages.length === 0) {
33-
const historyItem: HistoryItem = {
34-
id: taskId,
35-
number: taskNumber,
36-
ts: Date.now(),
37-
task: `Task #${taskNumber} (No messages)`,
38-
tokensIn: 0,
39-
tokensOut: 0,
40-
cacheWrites: 0,
41-
cacheReads: 0,
32+
// Determine message availability upfront
33+
const hasMessages = messages && messages.length > 0
34+
35+
// Pre-calculate all values based on availability
36+
let timestamp: number
37+
let tokenUsage: ReturnType<typeof getApiMetrics>
38+
let taskDirSize: number
39+
let taskMessage: ClineMessage | undefined
40+
41+
if (!hasMessages) {
42+
// Handle no messages case
43+
timestamp = Date.now()
44+
tokenUsage = {
45+
totalTokensIn: 0,
46+
totalTokensOut: 0,
47+
totalCacheWrites: 0,
48+
totalCacheReads: 0,
4249
totalCost: 0,
43-
size: 0,
44-
workspace,
50+
contextTokens: 0,
4551
}
46-
return {
47-
historyItem,
48-
tokenUsage: {
49-
totalTokensIn: 0,
50-
totalTokensOut: 0,
51-
totalCacheWrites: 0,
52-
totalCacheReads: 0,
53-
totalCost: 0,
54-
contextTokens: 0,
55-
},
56-
}
57-
}
52+
taskDirSize = 0
53+
} else {
54+
// Handle messages case
55+
taskMessage = messages[0] // First message is always the task say.
5856

59-
const taskMessage = messages[0] // First message is always the task say.
57+
const lastRelevantMessage =
58+
messages[findLastIndex(messages, (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"))] ||
59+
taskMessage
6060

61-
const lastRelevantMessage =
62-
messages[findLastIndex(messages, (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"))] ||
63-
messages[0]
61+
timestamp = lastRelevantMessage.ts
6462

65-
let taskDirSize = taskSizeCache.get<number>(taskDir)
63+
tokenUsage = getApiMetrics(combineApiRequests(combineCommandSequences(messages.slice(1))))
6664

67-
if (taskDirSize === undefined) {
68-
try {
69-
taskDirSize = await getFolderSize.loose(taskDir)
70-
taskSizeCache.set<number>(taskDir, taskDirSize)
71-
} catch (error) {
72-
taskDirSize = 0
73-
}
74-
}
65+
// Get task directory size
66+
const cachedSize = taskSizeCache.get<number>(taskDir)
7567

76-
const tokenUsage = getApiMetrics(combineApiRequests(combineCommandSequences(messages.slice(1))))
77-
78-
// Ensure task name is never blank - provide fallback names
79-
let taskName = taskMessage.text?.trim() || ""
80-
if (!taskName) {
81-
taskName = `Task #${taskNumber} (Incomplete)`
68+
if (cachedSize === undefined) {
69+
try {
70+
taskDirSize = await getFolderSize.loose(taskDir)
71+
taskSizeCache.set<number>(taskDir, taskDirSize)
72+
} catch (error) {
73+
taskDirSize = 0
74+
}
75+
} else {
76+
taskDirSize = cachedSize
77+
}
8278
}
8379

80+
// Create historyItem once with pre-calculated values
8481
const historyItem: HistoryItem = {
8582
id: taskId,
8683
number: taskNumber,
87-
ts: lastRelevantMessage.ts,
88-
task: taskName,
84+
ts: timestamp,
85+
task: hasMessages
86+
? taskMessage!.text?.trim() || t("common:tasks.incomplete", { taskNumber })
87+
: t("common:tasks.no_messages", { taskNumber }),
8988
tokensIn: tokenUsage.totalTokensIn,
9089
tokensOut: tokenUsage.totalTokensOut,
9190
cacheWrites: tokenUsage.totalCacheWrites,

src/i18n/locales/ca/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@
101101
},
102102
"tasks": {
103103
"canceled": "Error de tasca: Ha estat aturada i cancel·lada per l'usuari.",
104-
"deleted": "Fallada de tasca: Ha estat aturada i eliminada per l'usuari."
104+
"deleted": "Fallada de tasca: Ha estat aturada i eliminada per l'usuari.",
105+
"incomplete": "Tasca #{{taskNumber}} (Incompleta)",
106+
"no_messages": "Tasca #{{taskNumber}} (Sense missatges)"
105107
},
106108
"storage": {
107109
"prompt_custom_path": "Introdueix una ruta d'emmagatzematge personalitzada per a l'historial de converses o deixa-ho buit per utilitzar la ubicació predeterminada",

src/i18n/locales/de/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
},
9898
"tasks": {
9999
"canceled": "Aufgabenfehler: Die Aufgabe wurde vom Benutzer gestoppt und abgebrochen.",
100-
"deleted": "Aufgabenfehler: Die Aufgabe wurde vom Benutzer gestoppt und gelöscht."
100+
"deleted": "Aufgabenfehler: Die Aufgabe wurde vom Benutzer gestoppt und gelöscht.",
101+
"incomplete": "Aufgabe #{{taskNumber}} (Unvollständig)",
102+
"no_messages": "Aufgabe #{{taskNumber}} (Keine Nachrichten)"
101103
},
102104
"storage": {
103105
"prompt_custom_path": "Gib den benutzerdefinierten Speicherpfad für den Gesprächsverlauf ein, leer lassen für Standardspeicherort",

src/i18n/locales/en/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
},
9898
"tasks": {
9999
"canceled": "Task error: It was stopped and canceled by the user.",
100-
"deleted": "Task failure: It was stopped and deleted by the user."
100+
"deleted": "Task failure: It was stopped and deleted by the user.",
101+
"incomplete": "Task #{{taskNumber}} (Incomplete)",
102+
"no_messages": "Task #{{taskNumber}} (No messages)"
101103
},
102104
"storage": {
103105
"prompt_custom_path": "Enter custom conversation history storage path, leave empty to use default location",

src/i18n/locales/es/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
},
9898
"tasks": {
9999
"canceled": "Error de tarea: Fue detenida y cancelada por el usuario.",
100-
"deleted": "Fallo de tarea: Fue detenida y eliminada por el usuario."
100+
"deleted": "Fallo de tarea: Fue detenida y eliminada por el usuario.",
101+
"incomplete": "Tarea #{{taskNumber}} (Incompleta)",
102+
"no_messages": "Tarea #{{taskNumber}} (Sin mensajes)"
101103
},
102104
"storage": {
103105
"prompt_custom_path": "Ingresa la ruta de almacenamiento personalizada para el historial de conversaciones, déjala vacía para usar la ubicación predeterminada",

src/i18n/locales/fr/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
},
9898
"tasks": {
9999
"canceled": "Erreur de tâche : Elle a été arrêtée et annulée par l'utilisateur.",
100-
"deleted": "Échec de la tâche : Elle a été arrêtée et supprimée par l'utilisateur."
100+
"deleted": "Échec de la tâche : Elle a été arrêtée et supprimée par l'utilisateur.",
101+
"incomplete": "Tâche #{{taskNumber}} (Incomplète)",
102+
"no_messages": "Tâche #{{taskNumber}} (Aucun message)"
101103
},
102104
"storage": {
103105
"prompt_custom_path": "Entrez le chemin de stockage personnalisé pour l'historique des conversations, laissez vide pour utiliser l'emplacement par défaut",

src/i18n/locales/hi/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
},
9898
"tasks": {
9999
"canceled": "टास्क त्रुटि: इसे उपयोगकर्ता द्वारा रोका और रद्द किया गया था।",
100-
"deleted": "टास्क विफलता: इसे उपयोगकर्ता द्वारा रोका और हटाया गया था।"
100+
"deleted": "टास्क विफलता: इसे उपयोगकर्ता द्वारा रोका और हटाया गया था।",
101+
"incomplete": "टास्क #{{taskNumber}} (अधूरा)",
102+
"no_messages": "टास्क #{{taskNumber}} (कोई संदेश नहीं)"
101103
},
102104
"storage": {
103105
"prompt_custom_path": "वार्तालाप इतिहास के लिए कस्टम स्टोरेज पाथ दर्ज करें, डिफ़ॉल्ट स्थान का उपयोग करने के लिए खाली छोड़ दें",

src/i18n/locales/it/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
},
9898
"tasks": {
9999
"canceled": "Errore attività: È stata interrotta e annullata dall'utente.",
100-
"deleted": "Fallimento attività: È stata interrotta ed eliminata dall'utente."
100+
"deleted": "Fallimento attività: È stata interrotta ed eliminata dall'utente.",
101+
"incomplete": "Attività #{{taskNumber}} (Incompleta)",
102+
"no_messages": "Attività #{{taskNumber}} (Nessun messaggio)"
101103
},
102104
"storage": {
103105
"prompt_custom_path": "Inserisci il percorso di archiviazione personalizzato per la cronologia delle conversazioni, lascia vuoto per utilizzare la posizione predefinita",

src/i18n/locales/ja/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
},
9898
"tasks": {
9999
"canceled": "タスクエラー:ユーザーによって停止およびキャンセルされました。",
100-
"deleted": "タスク失敗:ユーザーによって停止および削除されました。"
100+
"deleted": "タスク失敗:ユーザーによって停止および削除されました。",
101+
"incomplete": "タスク #{{taskNumber}} (未完了)",
102+
"no_messages": "タスク #{{taskNumber}} (メッセージなし)"
101103
},
102104
"storage": {
103105
"prompt_custom_path": "会話履歴のカスタムストレージパスを入力してください。デフォルトの場所を使用する場合は空のままにしてください",

src/i18n/locales/ko/common.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@
9797
},
9898
"tasks": {
9999
"canceled": "작업 오류: 사용자에 의해 중지 및 취소되었습니다.",
100-
"deleted": "작업 실패: 사용자에 의해 중지 및 삭제되었습니다."
100+
"deleted": "작업 실패: 사용자에 의해 중지 및 삭제되었습니다.",
101+
"incomplete": "작업 #{{taskNumber}} (미완료)",
102+
"no_messages": "작업 #{{taskNumber}} (메시지 없음)"
101103
},
102104
"storage": {
103105
"prompt_custom_path": "대화 내역을 위한 사용자 지정 저장 경로를 입력하세요. 기본 위치를 사용하려면 비워두세요",

0 commit comments

Comments
 (0)