feat(i18n): translate --workspace-file help, Examples header, and model warnings

This commit is contained in:
criss717 2026-08-24 18:23:24 +02:00
parent fbf94387b9
commit 27cf85f849
5 changed files with 70 additions and 15 deletions

View file

@ -77,8 +77,8 @@ def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description=t("cli.description"),
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
epilog=f"""
{t("cli.examples_header")}
# Web application penetration test
strix --target https://example.com
@ -175,11 +175,7 @@ Examples:
type=str,
action="append",
metavar="PATH[:DEST]",
help="Place a file from this machine into the sandbox workspace before the scan "
"starts, for example a wordlist, an API specification, or notes. Repeat the option "
"for more files. DEST is the path inside /workspace and defaults to the file name "
"(for example '--workspace-file ./wordlist.txt:lists/wordlist.txt'). The file is "
"read-only inside the sandbox and lands outside every target directory.",
help=t("cli.workspace_file_help"),
)
parser.add_argument(

View file

@ -156,17 +156,16 @@ async def warm_up_llm(show_model_warning: bool = True) -> None:
and not llm.api_base
):
warn_text = Text()
warn_text.append("UNKNOWN MODEL NAME", style="bold yellow")
warn_text.append(t("cli.unknown_model"), style="bold yellow")
warn_text.append("\n\n", style="white")
warn_text.append(f"'{raw_model}'", style="bold cyan")
warn_text.append(
" is not a known OpenAI model. Bare names route to OpenAI by default.\n"
"If you meant a non-OpenAI provider, use the '",
t("cli.unknown_model_body"),
style="white",
)
warn_text.append("<provider>/<model>", style="bold cyan")
warn_text.append(
"' form, e.g. 'anthropic/claude-opus-4-7', 'deepseek/deepseek-v4-pro'.",
t("cli.unknown_model_hint"),
style="white",
)
console.print(
@ -182,18 +181,17 @@ async def warm_up_llm(show_model_warning: bool = True) -> None:
if show_model_warning and raw_model and not is_recommended_or_frontier_model(raw_model):
warn_text = Text()
warn_text.append("MODEL QUALITY WARNING", style="bold yellow")
warn_text.append(t("cli.model_quality_warning"), style="bold yellow")
warn_text.append("\n\n", style="white")
warn_text.append(f"'{raw_model}'", style="bold cyan")
warn_text.append(
" is not a recommended frontier model for Strix.\nSecurity scans work best with:\n",
t("cli.model_quality_warning_body"),
style="white",
)
for recommended_model in RECOMMENDED_MODEL_NAMES:
warn_text.append(f"• {recommended_model}\n", style="bold cyan")
warn_text.append(
"\nYou can continue, but weaker models may miss vulnerabilities "
"or produce lower-quality findings.",
t("cli.model_quality_warning_footer"),
style="white",
)
console.print(

View file

@ -13,6 +13,8 @@
"cli.max_turns_help": "Maximum turns per agent (> 0, default %(default)s). Each agent is force-stopped when it reaches this limit, with graduated wrap-up warnings as it is approached.",
"cli.resume_help": "Resume a prior scan by its run name (the dir under ./strix_runs/). Picks up the root + every non-terminal subagent's full LLM history and agent topology. Skips fresh run-name generation.",
"cli.language_help": "Language for UI and agent responses (e.g., 'en', 'es'). Default: auto-detect from environment.",
"cli.workspace_file_help": "Place a file from this machine into the sandbox workspace before the scan starts, for example a wordlist, an API specification, or notes. Repeat the option for more files. DEST is the path inside /workspace and defaults to the file name (for example '--workspace-file ./wordlist.txt:lists/wordlist.txt'). The file is read-only inside the sandbox and lands outside every target directory.",
"cli.examples_header": "Examples:",
"cli.update_help": "Update strix to the latest version and exit. Self-updates the standalone binary install; for pip/pipx/uv installs, prints the matching upgrade command instead.",
"cli.version_help": "Show version and exit.",
"cli.error_no_target": "No target specified. Use --target or --target-list.",
@ -53,7 +55,11 @@
"cli.llm_check_config": "Please check your configuration and try again.",
"cli.model_not_available": "MODEL NOT AVAILABLE ON SUBSCRIPTION",
"cli.unknown_model": "UNKNOWN MODEL NAME",
"cli.unknown_model_body": " is not a known OpenAI model. Bare names route to OpenAI by default.\nIf you meant a non-OpenAI provider, use the '",
"cli.unknown_model_hint": "' form, e.g. 'anthropic/claude-opus-4-7', 'deepseek/deepseek-v4-pro'.",
"cli.model_quality_warning": "MODEL QUALITY WARNING",
"cli.model_quality_warning_body": " is not a recommended frontier model for Strix.\nSecurity scans work best with:\n",
"cli.model_quality_warning_footer": "\nYou can continue, but weaker models may miss vulnerabilities or produce lower-quality findings.",
"cli.interactive_setup_unavailable": "INTERACTIVE SETUP UNAVAILABLE",
"cli.scan_preparation_failed": "SCAN PREPARATION FAILED",
"cli.test_initiated": "Penetration test initiated",

View file

@ -13,6 +13,8 @@
"cli.max_turns_help": "Máximo de turnos por agente (> 0, por defecto %(default)s). Cada agente se detiene forzosamente al alcanzar este límite, con advertencias graduales al acercarse.",
"cli.resume_help": "Reanudar un escaneo anterior por nombre de ejecución (el directorio bajo ./strix_runs/). Retoma el historial LLM completo del agente raíz y subagentes no terminados. Omite la generación de nombre nuevo.",
"cli.language_help": "Idioma para la interfaz y respuestas de agentes (ej: 'en', 'es'). Por defecto: auto-detectar del entorno.",
"cli.workspace_file_help": "Coloca un archivo de esta máquina en el workspace del sandbox antes de que comience el escaneo, por ejemplo una wordlist, una especificación de API o notas. Repite la opción para más archivos. DEST es la ruta dentro de /workspace y por defecto usa el nombre del archivo (por ejemplo '--workspace-file ./wordlist.txt:lists/wordlist.txt'). El archivo es de solo lectura dentro del sandbox y queda fuera de cada directorio de objetivo.",
"cli.examples_header": "Ejemplos:",
"cli.update_help": "Actualizar strix a la última versión y salir. Auto-actualiza la instalación binaria; para instalaciones pip/pipx/uv, muestra el comando de actualización correspondiente.",
"cli.version_help": "Mostrar versión y salir.",
"cli.error_no_target": "No se especificó objetivo. Use --target o --target-list.",
@ -53,7 +55,11 @@
"cli.llm_check_config": "Verifique su configuración e intente nuevamente.",
"cli.model_not_available": "MODELO NO DISPONIBLE EN SUSCRIPCIÓN",
"cli.unknown_model": "NOMBRE DE MODELO DESCONOCIDO",
"cli.unknown_model_body": " no es un modelo de OpenAI conocido. Los nombres simples se enrutan a OpenAI por defecto.\nSi te referías a un proveedor distinto de OpenAI, usa '",
"cli.unknown_model_hint": "', por ejemplo 'anthropic/claude-opus-4-7', 'deepseek/deepseek-v4-pro'.",
"cli.model_quality_warning": "ADVERTENCIA DE CALIDAD DEL MODELO",
"cli.model_quality_warning_body": " no es un modelo frontier recomendado para Strix.\nLos escaneos de seguridad funcionan mejor con:\n",
"cli.model_quality_warning_footer": "\nPuedes continuar, pero los modelos más débiles pueden omitir vulnerabilidades o producir hallazgos de menor calidad.",
"cli.interactive_setup_unavailable": "CONFIGURACIÓN INTERACTIVA NO DISPONIBLE",
"cli.scan_preparation_failed": "FALLO EN PREPARACIÓN DEL ESCANEO",
"cli.test_initiated": "Prueba de penetración iniciada",

View file

@ -203,6 +203,55 @@ class TestLocaleKeyConsistency:
assert locale_file.exists(), f"Missing locale file: {locale_file}"
class TestCliHelpKeys:
"""The CLI help and model-warning strings must translate in both locales."""
def test_workspace_file_help_translates(self):
set_language("en")
en_value = t("cli.workspace_file_help")
assert "sandbox workspace" in en_value
set_language("es")
es_value = t("cli.workspace_file_help")
assert "workspace del sandbox" in es_value
assert es_value != "cli.workspace_file_help"
def test_examples_header_translates(self):
set_language("es")
assert t("cli.examples_header") == "Ejemplos:"
set_language("en")
assert t("cli.examples_header") == "Examples:"
def test_model_quality_warning_body_translates(self):
set_language("en")
assert "frontier model" in t("cli.model_quality_warning_body")
set_language("es")
es_value = t("cli.model_quality_warning_body")
assert "modelo frontier" in es_value
assert es_value != "cli.model_quality_warning_body"
def test_model_quality_warning_footer_translates(self):
set_language("en")
assert "weaker models" in t("cli.model_quality_warning_footer")
set_language("es")
es_value = t("cli.model_quality_warning_footer")
assert "modelos más débiles" in es_value
def test_unknown_model_body_translates(self):
set_language("en")
assert "known OpenAI model" in t("cli.unknown_model_body")
set_language("es")
es_value = t("cli.unknown_model_body")
assert "modelo de OpenAI conocido" in es_value
def test_unknown_model_hint_translates(self):
set_language("en")
assert "form, e.g." in t("cli.unknown_model_hint")
set_language("es")
es_value = t("cli.unknown_model_hint")
assert "por ejemplo" in es_value
class TestSettingsLanguageField:
def test_settings_has_language_field(self):
s = Settings()