feat(i18n): localize all queue command messages across 7 locales

This commit is contained in:
gordonlu
2026-06-02 10:46:13 +08:00
committed by Hunter B
parent ddae7584f8
commit 6ab77eaba3
2 changed files with 250 additions and 37 deletions
+94 -37
View File
@@ -1,5 +1,6 @@
//! Queue commands: queue list/edit/drop/clear
use crate::localization::{Locale, MessageId, tr};
use crate::tui::app::App;
use super::CommandResult;
@@ -7,6 +8,7 @@ use super::CommandResult;
const PREVIEW_LIMIT: usize = 120;
pub fn queue(app: &mut App, args: Option<&str>) -> CommandResult {
let locale = app.ui_locale;
let arg = args.unwrap_or("").trim();
if arg.is_empty() || arg.eq_ignore_ascii_case("list") {
return list_queue(app);
@@ -19,27 +21,28 @@ pub fn queue(app: &mut App, args: Option<&str>) -> CommandResult {
"edit" => edit_queue(app, parts.next()),
"drop" | "remove" | "rm" => drop_queue(app, parts.next()),
"clear" => clear_queue(app),
_ => CommandResult::error("Usage: /queue [list|edit <n>|drop <n>|clear]"),
_ => CommandResult::error(tr(locale, MessageId::CmdQueueUsage)),
}
}
fn list_queue(app: &mut App) -> CommandResult {
let locale = app.ui_locale;
let mut lines = Vec::new();
let queued = app.queued_message_count();
if let Some(draft) = app.queued_draft.as_ref() {
lines.push("Editing queued message:".to_string());
lines.push(format!("- {}", truncate_preview(&draft.display)));
let header = tr(locale, MessageId::CmdQueueDraftHeader);
lines.push(format!("{} {}", header, truncate_preview(&draft.display)));
}
if queued == 0 {
if lines.is_empty() {
return CommandResult::message("No queued messages");
return CommandResult::message(tr(locale, MessageId::CmdQueueNoMessages));
}
return CommandResult::message(lines.join("\n"));
}
lines.push(format!("Queued messages ({queued}):"));
lines.push(tr(locale, MessageId::CmdQueueListHeader).replace("{count}", &queued.to_string()));
for (idx, message) in app.queued_messages.iter().enumerate() {
lines.push(format!(
"{}. {}",
@@ -48,70 +51,74 @@ fn list_queue(app: &mut App) -> CommandResult {
));
}
lines.push("Tip: /queue edit <n> to edit, /queue drop <n> to remove".to_string());
lines.push(tr(locale, MessageId::CmdQueueTip).to_string());
CommandResult::message(lines.join("\n"))
}
fn edit_queue(app: &mut App, index: Option<&str>) -> CommandResult {
let locale = app.ui_locale;
if app.queued_draft.is_some() {
return CommandResult::error(
"Already editing a queued message. Send it or /queue clear to discard.",
);
return CommandResult::error(tr(locale, MessageId::CmdQueueAlreadyEditing));
}
let index = match parse_index(index) {
let index = match parse_index(index, locale) {
Ok(index) => index,
Err(err) => return CommandResult::error(err),
};
let Some(message) = app.remove_queued_message(index) else {
return CommandResult::error("Queued message not found");
return CommandResult::error(tr(locale, MessageId::CmdQueueNotFound));
};
app.input = message.display.clone();
app.cursor_position = app.input.len();
app.queued_draft = Some(message);
app.status_message = Some(format!("Editing queued message {}", index + 1));
let status =
tr(locale, MessageId::CmdQueueEditingStatus).replace("{index}", &(index + 1).to_string());
app.status_message = Some(status);
CommandResult::message(format!(
"Editing queued message {} (press Enter to re-queue/send)",
index + 1
))
CommandResult::message(
tr(locale, MessageId::CmdQueueEditingMessage).replace("{index}", &(index + 1).to_string()),
)
}
fn drop_queue(app: &mut App, index: Option<&str>) -> CommandResult {
let index = match parse_index(index) {
let locale = app.ui_locale;
let index = match parse_index(index, locale) {
Ok(index) => index,
Err(err) => return CommandResult::error(err),
};
if app.remove_queued_message(index).is_none() {
return CommandResult::error("Queued message not found");
return CommandResult::error(tr(locale, MessageId::CmdQueueNotFound));
}
CommandResult::message(format!("Dropped queued message {}", index + 1))
CommandResult::message(
tr(locale, MessageId::CmdQueueDropped).replace("{index}", &(index + 1).to_string()),
)
}
fn clear_queue(app: &mut App) -> CommandResult {
let locale = app.ui_locale;
let queued = app.queued_message_count();
let had_draft = app.queued_draft.take().is_some();
app.queued_messages.clear();
if queued == 0 && !had_draft {
return CommandResult::message("Queue already empty");
return CommandResult::message(tr(locale, MessageId::CmdQueueAlreadyEmpty));
}
CommandResult::message("Queue cleared")
CommandResult::message(tr(locale, MessageId::CmdQueueCleared))
}
fn parse_index(input: Option<&str>) -> Result<usize, &'static str> {
fn parse_index(input: Option<&str>, locale: Locale) -> Result<usize, String> {
let Some(input) = input else {
return Err("Missing index. Usage: /queue edit <n> or /queue drop <n>");
return Err(tr(locale, MessageId::CmdQueueMissingIndex).to_string());
};
let raw = input
.parse::<usize>()
.map_err(|_| "Index must be a positive number")?;
.map_err(|_| tr(locale, MessageId::CmdQueueIndexPositive).to_string())?;
if raw == 0 {
return Err("Index must be >= 1");
return Err(tr(locale, MessageId::CmdQueueIndexMin).to_string());
}
Ok(raw - 1)
}
@@ -164,16 +171,18 @@ mod tests {
fn test_queue_list_empty() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
let result = queue(&mut app, None);
assert!(result.message.is_some());
let msg = result.message.unwrap();
assert!(msg.contains("No queued messages"));
assert!(msg.contains(tr(app.ui_locale, MessageId::CmdQueueNoMessages)));
}
#[test]
fn test_queue_list_with_messages() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
app.queued_messages
.push_back(QueuedMessage::new("First message".to_string(), None));
app.queued_messages
@@ -181,7 +190,9 @@ mod tests {
let result = queue(&mut app, Some("list"));
assert!(result.message.is_some());
let msg = result.message.unwrap();
assert!(msg.contains("Queued messages (2)"));
assert!(
msg.contains(&tr(app.ui_locale, MessageId::CmdQueueListHeader).replace("{count}", "2"))
);
assert!(msg.contains("1. First message"));
assert!(msg.contains("2. Second message"));
}
@@ -190,24 +201,29 @@ mod tests {
fn test_queue_edit_missing_index() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
app.queued_messages
.push_back(QueuedMessage::new("Test".to_string(), None));
let result = queue(&mut app, Some("edit"));
assert!(result.message.is_some());
assert!(result.message.unwrap().contains("Missing index"));
let msg = result.message.unwrap();
assert!(
msg.contains(tr(Locale::En, MessageId::CmdQueueMissingIndex)),
"msg={msg:?}"
);
}
#[test]
fn test_queue_edit_invalid_index() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
let result = queue(&mut app, Some("edit abc"));
assert!(result.message.is_some());
let msg = result.message.unwrap();
assert!(
result
.message
.unwrap()
.contains("must be a positive number")
msg.contains(tr(Locale::En, MessageId::CmdQueueIndexPositive)),
"msg={msg:?}"
);
}
@@ -215,15 +231,21 @@ mod tests {
fn test_queue_edit_not_found() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
let result = queue(&mut app, Some("edit 1"));
assert!(result.message.is_some());
assert!(result.message.unwrap().contains("not found"));
let msg = result.message.unwrap();
assert!(
msg.contains(tr(Locale::En, MessageId::CmdQueueNotFound)),
"msg={msg:?}"
);
}
#[test]
fn test_queue_edit_already_editing() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
app.queued_messages
.push_back(QueuedMessage::new("First".to_string(), None));
app.queued_messages
@@ -233,13 +255,18 @@ mod tests {
// Try to edit another
let result = queue(&mut app, Some("edit 2"));
assert!(result.message.is_some());
assert!(result.message.unwrap().contains("Already editing"));
let msg = result.message.unwrap();
assert!(
msg.contains(tr(Locale::En, MessageId::CmdQueueAlreadyEditing)),
"msg={msg:?}"
);
}
#[test]
fn test_queue_edit_success() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
app.queued_messages
.push_back(QueuedMessage::new("Original message".to_string(), None));
let result = queue(&mut app, Some("edit 1"));
@@ -253,12 +280,17 @@ mod tests {
fn test_queue_drop_success() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
app.queued_messages
.push_back(QueuedMessage::new("To drop".to_string(), None));
let initial_count = app.queued_messages.len();
let result = queue(&mut app, Some("drop 1"));
assert!(result.message.is_some());
assert!(result.message.unwrap().contains("Dropped queued message"));
let msg = result.message.unwrap();
assert!(
msg.contains(&tr(Locale::En, MessageId::CmdQueueDropped).replace("{index}", "1")),
"msg={msg:?}"
);
assert_eq!(app.queued_messages.len(), initial_count - 1);
}
@@ -266,13 +298,18 @@ mod tests {
fn test_queue_clear() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
app.queued_messages
.push_back(QueuedMessage::new("Message 1".to_string(), None));
app.queued_messages
.push_back(QueuedMessage::new("Message 2".to_string(), None));
let result = queue(&mut app, Some("clear"));
assert!(result.message.is_some());
assert!(result.message.unwrap().contains("Queue cleared"));
let msg = result.message.unwrap();
assert!(
msg.contains(tr(Locale::En, MessageId::CmdQueueCleared)),
"msg={msg:?}"
);
assert!(app.queued_messages.is_empty());
}
@@ -280,9 +317,29 @@ mod tests {
fn test_queue_clear_already_empty() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::En;
let result = queue(&mut app, Some("clear"));
assert!(result.message.is_some());
assert!(result.message.unwrap().contains("Queue already empty"));
let msg = result.message.unwrap();
assert!(
msg.contains(tr(Locale::En, MessageId::CmdQueueAlreadyEmpty)),
"msg={msg:?}"
);
}
#[test]
fn queue_messages_are_localized() {
let tmpdir = TempDir::new().unwrap();
let mut app = create_test_app_with_tmpdir(&tmpdir);
app.ui_locale = Locale::ZhHans;
app.queued_messages
.push_back(QueuedMessage::new("M1".to_string(), None));
app.queued_messages
.push_back(QueuedMessage::new("M2".to_string(), None));
let result = queue(&mut app, Some("list"));
let msg = result.message.unwrap();
assert!(msg.contains("已排队的消息"), "zh list header: {msg}");
assert!(msg.contains("提示"), "zh tip: {msg}");
}
#[test]
+156
View File
@@ -290,6 +290,21 @@ pub enum MessageId {
CmdThemeDescription,
CmdProviderDescription,
CmdQueueDescription,
CmdQueueUsage,
CmdQueueDraftHeader,
CmdQueueNoMessages,
CmdQueueListHeader,
CmdQueueTip,
CmdQueueAlreadyEditing,
CmdQueueNotFound,
CmdQueueEditingStatus,
CmdQueueEditingMessage,
CmdQueueDropped,
CmdQueueAlreadyEmpty,
CmdQueueCleared,
CmdQueueMissingIndex,
CmdQueueIndexPositive,
CmdQueueIndexMin,
CmdRecallDescription,
CmdRelayDescription,
CmdRenameDescription,
@@ -554,6 +569,21 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[
MessageId::CmdNoteDescription,
MessageId::CmdProviderDescription,
MessageId::CmdQueueDescription,
MessageId::CmdQueueUsage,
MessageId::CmdQueueDraftHeader,
MessageId::CmdQueueNoMessages,
MessageId::CmdQueueListHeader,
MessageId::CmdQueueTip,
MessageId::CmdQueueAlreadyEditing,
MessageId::CmdQueueNotFound,
MessageId::CmdQueueEditingStatus,
MessageId::CmdQueueEditingMessage,
MessageId::CmdQueueDropped,
MessageId::CmdQueueAlreadyEmpty,
MessageId::CmdQueueCleared,
MessageId::CmdQueueMissingIndex,
MessageId::CmdQueueIndexPositive,
MessageId::CmdQueueIndexMin,
MessageId::CmdRecallDescription,
MessageId::CmdRelayDescription,
MessageId::CmdRenameDescription,
@@ -1035,6 +1065,27 @@ fn english(id: MessageId) -> &'static str {
"Switch or view the active LLM backend (deepseek | nvidia-nim | ollama)"
}
MessageId::CmdQueueDescription => "View or edit queued messages",
MessageId::CmdQueueUsage => "Usage: /queue [list|edit <n>|drop <n>|clear]",
MessageId::CmdQueueDraftHeader => "Editing queued message:",
MessageId::CmdQueueNoMessages => "No queued messages",
MessageId::CmdQueueListHeader => "Queued messages ({count}):",
MessageId::CmdQueueTip => "Tip: /queue edit <n> to edit, /queue drop <n> to remove",
MessageId::CmdQueueAlreadyEditing => {
"Already editing a queued message. Send it or /queue clear to discard."
}
MessageId::CmdQueueNotFound => "Queued message not found",
MessageId::CmdQueueEditingStatus => "Editing queued message {index}",
MessageId::CmdQueueEditingMessage => {
"Editing queued message {index} (press Enter to re-queue/send)"
}
MessageId::CmdQueueDropped => "Dropped queued message {index}",
MessageId::CmdQueueAlreadyEmpty => "Queue already empty",
MessageId::CmdQueueCleared => "Queue cleared",
MessageId::CmdQueueMissingIndex => {
"Missing index. Usage: /queue edit <n> or /queue drop <n>"
}
MessageId::CmdQueueIndexPositive => "Index must be a positive number",
MessageId::CmdQueueIndexMin => "Index must be >= 1",
MessageId::CmdRecallDescription => "Search prior cycle archives (BM25 over message text)",
MessageId::CmdRelayDescription => "Create a session relay (接力) for a fresh thread",
MessageId::CmdRenameDescription => "Rename the current session",
@@ -1443,6 +1494,27 @@ fn vietnamese(id: MessageId) -> Option<&'static str> {
"Chuyển đổi hoặc xem backend LLM đang hoạt động (deepseek | nvidia-nim | ollama)"
}
MessageId::CmdQueueDescription => "Xem hoặc chỉnh sửa các tin nhắn đang chờ xử lý",
MessageId::CmdQueueUsage => "Cách dùng: /queue [list|edit <n>|drop <n>|clear]",
MessageId::CmdQueueDraftHeader => "Đang chỉnh sửa tin nhắn đang chờ:",
MessageId::CmdQueueNoMessages => "Không có tin nhắn đang chờ",
MessageId::CmdQueueListHeader => "Tin nhắn đang chờ ({count}):",
MessageId::CmdQueueTip => "Mẹo: /queue edit <n> để sửa, /queue drop <n> để xóa",
MessageId::CmdQueueAlreadyEditing => {
"Đã đang chỉnh sửa một tin nhắn đang chờ. Hãy gửi nó hoặc dùng /queue clear để hủy."
}
MessageId::CmdQueueNotFound => "Không tìm thấy tin nhắn đang chờ",
MessageId::CmdQueueEditingStatus => "Đang chỉnh sửa tin nhắn đang chờ {index}",
MessageId::CmdQueueEditingMessage => {
"Đang chỉnh sửa tin nhắn đang chờ {index} (nhấn Enter để xếp lại hàng/gửi)"
}
MessageId::CmdQueueDropped => "Đã xóa tin nhắn đang chờ {index}",
MessageId::CmdQueueAlreadyEmpty => "Hàng đợi đã trống",
MessageId::CmdQueueCleared => "Đã xóa hàng đợi",
MessageId::CmdQueueMissingIndex => {
"Thiếu chỉ mục. Cách dùng: /queue edit <n> hoặc /queue drop <n>"
}
MessageId::CmdQueueIndexPositive => "Chỉ mục phải là số dương",
MessageId::CmdQueueIndexMin => "Chỉ mục phải >= 1",
MessageId::CmdRecallDescription => {
"Tìm kiếm kho lưu trữ chu kỳ trước (BM25 trên văn bản tin nhắn)"
}
@@ -1878,6 +1950,27 @@ fn japanese(id: MessageId) -> Option<&'static str> {
"現在の LLM バックエンドを切り替え・確認(deepseek | nvidia-nim | ollama"
}
MessageId::CmdQueueDescription => "キューされたメッセージを確認・編集",
MessageId::CmdQueueUsage => "使用方法: /queue [list|edit <n>|drop <n>|clear]",
MessageId::CmdQueueDraftHeader => "キューされたメッセージを編集中:",
MessageId::CmdQueueNoMessages => "キューされたメッセージはありません",
MessageId::CmdQueueListHeader => "キューされたメッセージ ({count}):",
MessageId::CmdQueueTip => "ヒント: /queue edit <n> で編集、/queue drop <n> で削除",
MessageId::CmdQueueAlreadyEditing => {
"すでにキューされたメッセージを編集中です。送信するか /queue clear で破棄してください。"
}
MessageId::CmdQueueNotFound => "キューされたメッセージが見つかりません",
MessageId::CmdQueueEditingStatus => "キューされたメッセージ {index} を編集中",
MessageId::CmdQueueEditingMessage => {
"キューされたメッセージ {index} を編集中(Enter で再キュー/送信)"
}
MessageId::CmdQueueDropped => "キューされたメッセージ {index} を削除しました",
MessageId::CmdQueueAlreadyEmpty => "キューはすでに空です",
MessageId::CmdQueueCleared => "キューをクリアしました",
MessageId::CmdQueueMissingIndex => {
"インデックスが指定されていません。使用方法: /queue edit <n> または /queue drop <n>"
}
MessageId::CmdQueueIndexPositive => "インデックスは正の数値である必要があります",
MessageId::CmdQueueIndexMin => "インデックスは 1 以上である必要があります",
MessageId::CmdRecallDescription => {
"過去のサイクルアーカイブを検索(メッセージ本文への BM25 検索)"
}
@@ -2253,6 +2346,25 @@ fn chinese_simplified(id: MessageId) -> Option<&'static str> {
"切换或查看当前 LLM 后端(deepseek | nvidia-nim | ollama"
}
MessageId::CmdQueueDescription => "查看或编辑已排队的消息",
MessageId::CmdQueueUsage => "用法: /queue [list|edit <n>|drop <n>|clear]",
MessageId::CmdQueueDraftHeader => "正在编辑已排队的消息:",
MessageId::CmdQueueNoMessages => "没有已排队的消息",
MessageId::CmdQueueListHeader => "已排队的消息 ({count}):",
MessageId::CmdQueueTip => "提示: /queue edit <n> 编辑, /queue drop <n> 删除",
MessageId::CmdQueueAlreadyEditing => {
"已在编辑一条已排队的消息。请先发送或使用 /queue clear 放弃。"
}
MessageId::CmdQueueNotFound => "未找到已排队的消息",
MessageId::CmdQueueEditingStatus => "正在编辑已排队的消息 {index}",
MessageId::CmdQueueEditingMessage => {
"正在编辑已排队的消息 {index}(按 Enter 重新排队/发送)"
}
MessageId::CmdQueueDropped => "已删除已排队的消息 {index}",
MessageId::CmdQueueAlreadyEmpty => "队列已空",
MessageId::CmdQueueCleared => "队列已清空",
MessageId::CmdQueueMissingIndex => "缺少索引。用法: /queue edit <n> 或 /queue drop <n>",
MessageId::CmdQueueIndexPositive => "索引必须为正数",
MessageId::CmdQueueIndexMin => "索引必须 >= 1",
MessageId::CmdRecallDescription => "搜索此前的循环归档(基于消息文本的 BM25 检索)",
MessageId::CmdRelayDescription => "为新线程创建会话接力摘要",
MessageId::CmdRenameDescription => "重命名当前会话",
@@ -2614,6 +2726,27 @@ fn portuguese_brazil(id: MessageId) -> Option<&'static str> {
"Trocar ou exibir o backend LLM ativo (deepseek | nvidia-nim | ollama)"
}
MessageId::CmdQueueDescription => "Ver ou editar mensagens enfileiradas",
MessageId::CmdQueueUsage => "Uso: /queue [list|edit <n>|drop <n>|clear]",
MessageId::CmdQueueDraftHeader => "Editando mensagem enfileirada:",
MessageId::CmdQueueNoMessages => "Nenhuma mensagem enfileirada",
MessageId::CmdQueueListHeader => "Mensagens enfileiradas ({count}):",
MessageId::CmdQueueTip => "Dica: /queue edit <n> para editar, /queue drop <n> para remover",
MessageId::CmdQueueAlreadyEditing => {
"Já está editando uma mensagem enfileirada. Envie-a ou use /queue clear para descartar."
}
MessageId::CmdQueueNotFound => "Mensagem enfileirada não encontrada",
MessageId::CmdQueueEditingStatus => "Editando mensagem enfileirada {index}",
MessageId::CmdQueueEditingMessage => {
"Editando mensagem enfileirada {index} (pressione Enter para re-enfileirar/enviar)"
}
MessageId::CmdQueueDropped => "Mensagem enfileirada {index} removida",
MessageId::CmdQueueAlreadyEmpty => "Fila já está vazia",
MessageId::CmdQueueCleared => "Fila limpa",
MessageId::CmdQueueMissingIndex => {
"Índice ausente. Uso: /queue edit <n> ou /queue drop <n>"
}
MessageId::CmdQueueIndexPositive => "O índice deve ser um número positivo",
MessageId::CmdQueueIndexMin => "O índice deve ser >= 1",
MessageId::CmdRecallDescription => {
"Buscar arquivos de ciclos anteriores (BM25 sobre o texto das mensagens)"
}
@@ -3039,6 +3172,29 @@ fn spanish_latin_america(id: MessageId) -> Option<&'static str> {
"Cambiar o mostrar el backend LLM activo (deepseek | nvidia-nim | ollama)"
}
MessageId::CmdQueueDescription => "Ver o editar mensajes en cola",
MessageId::CmdQueueUsage => "Uso: /queue [list|edit <n>|drop <n>|clear]",
MessageId::CmdQueueDraftHeader => "Editando mensaje en cola:",
MessageId::CmdQueueNoMessages => "No hay mensajes en cola",
MessageId::CmdQueueListHeader => "Mensajes en cola ({count}):",
MessageId::CmdQueueTip => {
"Consejo: /queue edit <n> para editar, /queue drop <n> para eliminar"
}
MessageId::CmdQueueAlreadyEditing => {
"Ya estás editando un mensaje en cola. Envíalo o usa /queue clear para descartarlo."
}
MessageId::CmdQueueNotFound => "Mensaje en cola no encontrado",
MessageId::CmdQueueEditingStatus => "Editando mensaje en cola {index}",
MessageId::CmdQueueEditingMessage => {
"Editando mensaje en cola {index} (presiona Enter para re-encolar/enviar)"
}
MessageId::CmdQueueDropped => "Mensaje en cola {index} eliminado",
MessageId::CmdQueueAlreadyEmpty => "La cola ya está vacía",
MessageId::CmdQueueCleared => "Cola limpiada",
MessageId::CmdQueueMissingIndex => {
"Índice faltante. Uso: /queue edit <n> o /queue drop <n>"
}
MessageId::CmdQueueIndexPositive => "El índice debe ser un número positivo",
MessageId::CmdQueueIndexMin => "El índice debe ser >= 1",
MessageId::CmdRecallDescription => {
"Buscar archivos de ciclos anteriores (BM25 sobre el texto de los mensajes)"
}