@danhachuel/thunderbolt 0.2.98 → 0.2.100

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/app/main.py +14 -10
  2. package/package.json +1 -1
package/app/main.py CHANGED
@@ -38,6 +38,7 @@ from hermes_ui.music import list_music_files, materialize_suno_audio, request_su
38
38
  from hermes_ui.media_downloader import AUDIO_FORMATS, VIDEO_CONTAINERS, VIDEO_QUALITY_OPTIONS, MediaDownloadError, build_download_options, clear_media_download_history, dependency_status, download_media, list_media_downloads, media_download_file
39
39
  from hermes_ui.notifications import clear_notifications, list_notifications, mark_all_notifications_read, mark_notification_read, notification_event_catalog, notification_preferences, record_notification, reconcile_persisted_notifications, save_notification_preferences, unread_notification_count
40
40
  from hermes_ui.languages import LANGUAGE_CODES, LANGUAGE_FLAG_DATA_URIS, language_code, language_label, ui_language_menu_label, ui_text, video_language_label, video_language_options
41
+
41
42
  from hermes_ui.script_documents import list_script_documents, read_script_document, save_script_document, script_storage_path
42
43
  from hermes_ui.script_generation import generate_script_document
43
44
  from hermes_ui.voice_preview import DEFAULT_SAMPLE, load_preview_file, synthesize_preview
@@ -55,6 +56,8 @@ from integrations.local_runtime import MoneyPrinterRuntime
55
56
  from integrations.moneyprinter_config import sync_moneyprinter_config
56
57
  from integrations.openai_model_discovery import DEFAULT_NVIDIA_NIM_BASE_URL, ModelDiscoveryError, fetch_openai_compatible_models
57
58
 
59
+ DEFAULT_UI_LANGUAGE = "en"
60
+
58
61
  AI_STYLE_OPTIONS = [
59
62
  "Natural Realista",
60
63
  "Cocomelon style",
@@ -229,8 +232,9 @@ def current_ui_language() -> str:
229
232
  if requested:
230
233
  normalized = language_code(requested)
231
234
  else:
232
- settings = read_json("settings.json", {})
233
- normalized = language_code(settings.get("ui_language") or "pt")
235
+ # A raiz do launcher é o idioma padrão do sistema. A mudança explícita
236
+ # de idioma continua a chegar por ?lang=..., incluindo a rota /en.
237
+ normalized = DEFAULT_UI_LANGUAGE
234
238
  st.session_state["ui_language"] = normalized
235
239
  return normalized
236
240
 
@@ -3579,7 +3583,7 @@ def render_settings():
3579
3583
  st.subheader("API Keys")
3580
3584
  port = st.number_input("Porta Streamlit", 1, 65535, int(settings.get("port", 3030)))
3581
3585
  moneyprinter_path = st.text_input("Pasta do motor de vídeo", settings.get("moneyprinter_path", ""), key="settings_moneyprinter_path")
3582
- with st.expander("Niche Finder — execução remota no Kaggle", expanded=True):
3586
+ with st.expander("Niche Finder — execução remota no Kaggle", expanded=False):
3583
3587
  st.caption("O dataset permanece no Kaggle. O Thunderbolt usa estas credenciais apenas para publicar/executar a kernel e obter os resultados pequenos da análise.")
3584
3588
  kaggle_cols = st.columns(3)
3585
3589
  with kaggle_cols[0]:
@@ -3589,7 +3593,7 @@ def render_settings():
3589
3593
  with kaggle_cols[2]:
3590
3594
  kaggle_kernel_slug = text_setting("Slug da kernel", "kaggle_kernel_slug", help_text="Identificador da kernel remota, por exemplo thunderbolt-niche-finder.")
3591
3595
 
3592
- with st.expander("Niche Finder — execução através da Apify", expanded=True):
3596
+ with st.expander("Niche Finder — execução através da Apify", expanded=False):
3593
3597
  st.caption("O token fica guardado apenas no storage local. A aba Niche Finder Apify só usa este serviço depois de clicar no botão de pesquisa.")
3594
3598
  apify_cols = st.columns(4)
3595
3599
  with apify_cols[0]:
@@ -3601,7 +3605,7 @@ def render_settings():
3601
3605
  with apify_cols[3]:
3602
3606
  apify_run_timeout = st.number_input("Limite da execução (s)", min_value=30, max_value=7200, value=int(settings.get("apify_run_timeout_seconds", 900)), step=30)
3603
3607
 
3604
- with st.expander("Nano Banana — geração de thumbnails", expanded=True):
3608
+ with st.expander("Nano Banana — geração de thumbnails", expanded=False):
3605
3609
  st.caption("A Nano Banana gera a imagem final das thumbnails a partir da variante escolhida. A chave é guardada apenas no storage local e é distinta da chave do Gemini usado como LLM textual.")
3606
3610
  nano_cols = st.columns(2)
3607
3611
  with nano_cols[0]:
@@ -3611,7 +3615,7 @@ def render_settings():
3611
3615
  gemini_image_aspect_ratio = st.selectbox("Proporção da thumbnail", ["16:9", "9:16", "1:1", "4:5"], index=["16:9", "9:16", "1:1", "4:5"].index(str(settings.get("gemini_image_aspect_ratio") or "16:9")) if str(settings.get("gemini_image_aspect_ratio") or "16:9") in {"16:9", "9:16", "1:1", "4:5"} else 0)
3612
3616
  gemini_image_size = st.selectbox("Tamanho da imagem", ["1K", "2K", "4K"], index=["1K", "2K", "4K"].index(str(settings.get("gemini_image_size") or "1K")) if str(settings.get("gemini_image_size") or "1K") in {"1K", "2K", "4K"} else 0)
3613
3617
 
3614
- with st.expander("LLM — providers e modelos", expanded=True):
3618
+ with st.expander("LLM — providers e modelos", expanded=False):
3615
3619
  provider_options = ["openai", "moonshot", "shengsuanyun", "gemini", "deepseek", "qwen", "azure", "volcengine", "grok", "minimax", "mimo", "cloudflare", "modelscope", "aihubmix", "aimlapi", "evolink", "ollama", "oneapi", "litellm", "groq", "pollinations"]
3616
3620
  current_llm_provider = str(settings.get("llm_provider") or DEFAULT_LLM_PROVIDER).strip().lower()
3617
3621
  llm_provider = st.selectbox("LLM provider", provider_options, index=provider_options.index(current_llm_provider) if current_llm_provider in provider_options else 0)
@@ -3667,7 +3671,7 @@ def render_settings():
3667
3671
  with cols[2]:
3668
3672
  settings[f"{prefix}_model_name"] = text_setting("Model", f"{prefix}_model_name")
3669
3673
 
3670
- with st.expander("Voz, TTS e música — Azure Speech, restantes serviços e Suno", expanded=True):
3674
+ with st.expander("Voz, TTS e música — Azure Speech, restantes serviços e Suno", expanded=False):
3671
3675
  cols = st.columns(2)
3672
3676
  with cols[0]:
3673
3677
  azure_speech_key = text_setting("Azure Speech key", "azure_speech_key", secret=True)
@@ -3690,19 +3694,19 @@ def render_settings():
3690
3694
  suno_api_base_url = text_setting("Suno API Base URL", "suno_api_base_url", help_text="Use o endpoint compatível fornecido pelo seu acesso Suno; não é inventado pelo Thunderbolt.")
3691
3695
  suno_api_endpoint = text_setting("Suno API endpoint", "suno_api_endpoint", help_text="Ex.: /api/generate")
3692
3696
 
3693
- with st.expander("TikTok for Developers — Client ID e Client Secret", expanded=True):
3697
+ with st.expander("TikTok for Developers — Client ID e Client Secret", expanded=False):
3694
3698
  st.caption("Apenas as credenciais da aplicação ficam nesta UI. Redirect URI, scopes, autorização e tokens são geridos no TikTok for Developers Playground.")
3695
3699
  tiktok_client_key = text_setting("TikTok Client ID", "tiktok_client_key", secret=True)
3696
3700
  tiktok_client_secret = text_setting("TikTok Client Secret", "tiktok_client_secret", secret=True)
3697
3701
 
3698
- with st.expander("Publicação através do Upload-Post"):
3702
+ with st.expander("Publicação através do Upload-Post", expanded=False):
3699
3703
  upload_post_enabled = st.checkbox("Activar Upload-Post", bool(settings.get("upload_post_enabled", False)))
3700
3704
  upload_post_api_key = text_setting("Upload-Post API key", "upload_post_api_key", secret=True)
3701
3705
  upload_post_username = text_setting("Upload-Post username", "upload_post_username")
3702
3706
  upload_post_platforms = text_setting("Plataformas Upload-Post", "upload_post_platforms")
3703
3707
  upload_post_auto_upload = st.checkbox("Publicar automaticamente após gerar", bool(settings.get("upload_post_auto_upload", False)))
3704
3708
 
3705
- with st.expander("Postiz — API key, integração e MCP", expanded=True):
3709
+ with st.expander("Postiz — API key, integração e MCP", expanded=False):
3706
3710
  st.caption("O Thunderbolt é o cliente. A API key é enviada exclusivamente ao servidor Postiz configurado; não é colocada em URLs, logs ou repositório.")
3707
3711
  postiz_enabled = st.checkbox("Activar Postiz como fallback final", bool(settings.get("postiz_enabled", False)))
3708
3712
  postiz_mode = st.selectbox("Modo de ligação", ["api", "mcp"], index=0 if settings.get("postiz_mode", "api") != "mcp" else 1, help="API é o modo determinístico de upload. MCP fica disponível para uma ligação compatível com Streamable HTTP.")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.2.98",
3
+ "version": "0.2.100",
4
4
  "description": "Thunderbolt — interface local para operação de canais faceless e motor MoneyPrinterTurbo",
5
5
  "license": "MIT",
6
6
  "main": "scripts/cli.mjs",