@danhachuel/thunderbolt 0.2.61 → 0.2.63

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 (64) hide show
  1. package/app/main.py +83 -2
  2. package/hermes_ui/storage.py +28 -1
  3. package/package.json +3 -1
  4. package/scripts/install.mjs +16 -0
  5. package/seed/prompt_masters/2Dstickman.md +193 -0
  6. package/seed/prompt_masters/3Dskeletoncharacter.md +1 -0
  7. package/seed/prompt_masters/ANIMALMOUNTEDCAMERA.md +299 -0
  8. package/seed/prompt_masters/ASMR.md +74 -0
  9. package/seed/prompt_masters/ASMRDEBOCACOMDOCES.md +130 -0
  10. package/seed/prompt_masters/AnimalX-Ray.md +136 -0
  11. package/seed/prompt_masters/CAREVOLUTION.md +176 -0
  12. package/seed/prompt_masters/CINEMATICBUNKERSURVIVAL.md +180 -0
  13. package/seed/prompt_masters/CINEMATICSLUMTRANSFORMATIONENGINE.md +212 -0
  14. package/seed/prompt_masters/CINEMATOGR/303/201FICOS3D.md +207 -0
  15. package/seed/prompt_masters/CartoonNostalgia.md +131 -0
  16. package/seed/prompt_masters/EPOXYFLOORTRANSFORMATION.md +254 -0
  17. package/seed/prompt_masters/Edgar'sHouseofTerrorsChooseYourStory.md +134 -0
  18. package/seed/prompt_masters/FOODBABYFACECHARACTER.md +141 -0
  19. package/seed/prompt_masters/FuitNovels.md +166 -0
  20. package/seed/prompt_masters/KIDSSTORYCREATOR(PROMODE).md +235 -0
  21. package/seed/prompt_masters/MatchstickPrompt.md +86 -0
  22. package/seed/prompt_masters/PERSONAGENSABANDONADOS.md +208 -0
  23. package/seed/prompt_masters/Pixar-styleanimated.md +193 -0
  24. package/seed/prompt_masters/RESTORATIONTIMELAPSE.md +262 -0
  25. package/seed/prompt_masters/RUSTREMOVAL.md +275 -0
  26. package/seed/prompt_masters/ReceitasIndianas.md +60 -0
  27. package/seed/prompt_masters/SkyscraperMonster.md +140 -0
  28. package/seed/prompt_masters/TIMETRAVELVLOG.md +264 -0
  29. package/seed/prompt_masters/Tarot.md +58 -0
  30. package/seed/prompt_masters/UFOs(OVNIs).md +63 -0
  31. package/seed/prompt_masters/VisualCraftSequenceGenerator.md +284 -0
  32. package/seed/prompt_masters/craftingStorytellingAI.md +79 -0
  33. package/seed/prompt_masters/hist/303/263riasinfantishoradedormir.md +71 -0
  34. package/seed/prompt_masters/viralTikTokdance.md +77 -0
  35. package/storage/tiktok/prompts_master/2Dstickman.md +193 -0
  36. package/storage/tiktok/prompts_master/3Dskeletoncharacter.md +1 -0
  37. package/storage/tiktok/prompts_master/ANIMALMOUNTEDCAMERA.md +299 -0
  38. package/storage/tiktok/prompts_master/ASMR.md +74 -0
  39. package/storage/tiktok/prompts_master/ASMRDEBOCACOMDOCES.md +130 -0
  40. package/storage/tiktok/prompts_master/AnimalX-Ray.md +136 -0
  41. package/storage/tiktok/prompts_master/CAREVOLUTION.md +176 -0
  42. package/storage/tiktok/prompts_master/CINEMATICBUNKERSURVIVAL.md +180 -0
  43. package/storage/tiktok/prompts_master/CINEMATICSLUMTRANSFORMATIONENGINE.md +212 -0
  44. package/storage/tiktok/prompts_master/CINEMATOGR/303/201FICOS3D.md +207 -0
  45. package/storage/tiktok/prompts_master/CartoonNostalgia.md +131 -0
  46. package/storage/tiktok/prompts_master/EPOXYFLOORTRANSFORMATION.md +254 -0
  47. package/storage/tiktok/prompts_master/Edgar'sHouseofTerrorsChooseYourStory.md +134 -0
  48. package/storage/tiktok/prompts_master/FOODBABYFACECHARACTER.md +141 -0
  49. package/storage/tiktok/prompts_master/FuitNovels.md +166 -0
  50. package/storage/tiktok/prompts_master/KIDSSTORYCREATOR(PROMODE).md +235 -0
  51. package/storage/tiktok/prompts_master/MatchstickPrompt.md +86 -0
  52. package/storage/tiktok/prompts_master/PERSONAGENSABANDONADOS.md +208 -0
  53. package/storage/tiktok/prompts_master/Pixar-styleanimated.md +193 -0
  54. package/storage/tiktok/prompts_master/RESTORATIONTIMELAPSE.md +262 -0
  55. package/storage/tiktok/prompts_master/RUSTREMOVAL.md +275 -0
  56. package/storage/tiktok/prompts_master/ReceitasIndianas.md +60 -0
  57. package/storage/tiktok/prompts_master/SkyscraperMonster.md +140 -0
  58. package/storage/tiktok/prompts_master/TIMETRAVELVLOG.md +264 -0
  59. package/storage/tiktok/prompts_master/Tarot.md +58 -0
  60. package/storage/tiktok/prompts_master/UFOs(OVNIs).md +63 -0
  61. package/storage/tiktok/prompts_master/VisualCraftSequenceGenerator.md +284 -0
  62. package/storage/tiktok/prompts_master/craftingStorytellingAI.md +79 -0
  63. package/storage/tiktok/prompts_master/hist/303/263riasinfantishoradedormir.md +71 -0
  64. package/storage/tiktok/prompts_master/viralTikTokdance.md +77 -0
package/app/main.py CHANGED
@@ -22,7 +22,7 @@ except (OSError, json.JSONDecodeError):
22
22
 
23
23
  from hermes_ui.domain import STAGES, create_batch, create_channel, create_tasks_for_batch, delete_channel, pipeline_summary, set_channel_defaults, transition_task, update_channel, update_channel_video
24
24
  from hermes_ui.automation_worker import load_worker_status
25
- from hermes_ui.storage import BLUEPRINTS, STORAGE, ensure_storage, list_blueprint_files, load_blueprint_file, now, read_json, write_json
25
+ from hermes_ui.storage import BLUEPRINTS, STORAGE, TIKTOK_PROMPT_MASTERS, ensure_storage, list_blueprint_files, list_prompt_master_files, load_blueprint_file, load_prompt_master_file, now, read_json, write_json
26
26
  from app.modules.niche_finder.apify import ApifyError, DEFAULT_ACTOR_ID, abort_actor_run, build_actor_input, get_dataset_items, normalize_video_items, start_actor_run, wait_for_actor_run
27
27
  from app.modules.niche_finder.core import NicheAnalysisError, run_niche_analysis
28
28
  from app.modules.niche_finder.data_loader import DatasetError, download_kaggle_dataset
@@ -711,6 +711,78 @@ def render_blueprints():
711
711
  st.error(str(exc))
712
712
 
713
713
 
714
+ def render_tiktok_prompt_masters():
715
+ st.title("Prompts Master")
716
+ st.caption(f"Biblioteca exclusiva para vídeos TikTok. Os ficheiros ficam em `{TIKTOK_PROMPT_MASTERS}` e nunca entram na pasta de Blueprints YouTube.")
717
+
718
+ upload_tab, library_tab = st.tabs(["Upload", "Biblioteca"])
719
+ with upload_tab:
720
+ st.subheader("Adicionar Prompt Master")
721
+ st.info("Use ficheiros Markdown `.md`. Cada Prompt Master é guardado como um ficheiro independente no storage TikTok.")
722
+ uploaded_prompt = st.file_uploader("Subir Prompt Master (.md)", type=["md"], key="tiktok_prompt_master_upload")
723
+ if uploaded_prompt is not None:
724
+ uploaded_name = Path(uploaded_prompt.name).stem
725
+ prompt_name = st.text_input("Nome do Prompt Master", value=uploaded_name, key="tiktok_prompt_master_name")
726
+ replace_prompt = st.checkbox("Permitir substituir um ficheiro existente", key="tiktok_prompt_master_replace")
727
+ if st.button("Guardar Prompt Master", type="primary", use_container_width=True, key="save_tiktok_prompt_master"):
728
+ safe_stem = re.sub(r"[^A-Za-z0-9À-ÿ._-]+", "-", prompt_name.strip() or uploaded_name).strip(".-") or "prompt-master"
729
+ destination = TIKTOK_PROMPT_MASTERS / f"{safe_stem}.md"
730
+ if destination.exists() and not replace_prompt:
731
+ st.warning("Já existe um Prompt Master com esse nome. Active a substituição para o actualizar.")
732
+ else:
733
+ try:
734
+ content = uploaded_prompt.getvalue().decode("utf-8-sig")
735
+ if not content.strip():
736
+ raise ValueError("O ficheiro Markdown está vazio.")
737
+ destination.write_text(content.rstrip() + "\n", encoding="utf-8")
738
+ st.success(f"Prompt Master guardado em `{destination}`.")
739
+ st.rerun()
740
+ except UnicodeDecodeError:
741
+ st.error("O ficheiro deve estar codificado em UTF-8.")
742
+ except OSError as exc:
743
+ st.error(f"Não foi possível guardar o Prompt Master: {exc}")
744
+
745
+ with library_tab:
746
+ files = list_prompt_master_files()
747
+ st.subheader(f"Prompts Master existentes ({len(files)})")
748
+ search = st.text_input("Pesquisar Prompt Master", key="tiktok_prompt_master_search", placeholder="Nome ou conteúdo")
749
+ visible_files: list[Path] = []
750
+ for path in files:
751
+ try:
752
+ content = load_prompt_master_file(path)
753
+ except (OSError, ValueError):
754
+ content = ""
755
+ if search and search.lower() not in f"{path.name}\n{content}".lower():
756
+ continue
757
+ visible_files.append(path)
758
+ if not visible_files:
759
+ st.info("Ainda não existem Prompt Master que correspondam à pesquisa.")
760
+ for path in visible_files:
761
+ try:
762
+ content = load_prompt_master_file(path)
763
+ heading = next((line.lstrip("#").strip() for line in content.splitlines() if line.startswith("#")), path.stem)
764
+ with st.expander(f"{heading} — {path.name}", expanded=False):
765
+ st.caption(f"Ficheiro TikTok: `{path}`")
766
+ edited_content = st.text_area("Conteúdo Markdown", value=content, height=360, key=f"tiktok_prompt_master_editor_{path.stem}")
767
+ prompt_cols = st.columns(3)
768
+ with prompt_cols[0]:
769
+ if st.button("Guardar alterações", type="primary", use_container_width=True, key=f"save_prompt_master_{path.stem}"):
770
+ path.write_text(edited_content.rstrip() + "\n", encoding="utf-8")
771
+ st.success("Prompt Master actualizado.")
772
+ st.rerun()
773
+ with prompt_cols[1]:
774
+ st.download_button("Descarregar", data=content.encode("utf-8"), file_name=path.name, mime="text/markdown", use_container_width=True, key=f"download_prompt_master_{path.stem}")
775
+ with prompt_cols[2]:
776
+ if st.button("Apagar", use_container_width=True, key=f"delete_prompt_master_{path.stem}"):
777
+ path.unlink(missing_ok=True)
778
+ st.success("Prompt Master removido da biblioteca TikTok.")
779
+ st.rerun()
780
+ st.markdown(content)
781
+ except (OSError, ValueError) as exc:
782
+ with st.expander(f"Ficheiro inválido — {path.name}"):
783
+ st.error(str(exc))
784
+
785
+
714
786
  def render_channels():
715
787
  st.title("Canais Youtube")
716
788
  st.caption("Escolha entre importar dados públicos do YouTube ou preencher o canal manualmente.")
@@ -3276,6 +3348,9 @@ def main():
3276
3348
  ("Roteiros", ":material/article:", "Roteiros"),
3277
3349
  ("Upload", ":material/cloud_upload:", "Upload"),
3278
3350
  ]
3351
+ pipeline_tiktok_items = [
3352
+ ("Prompts Master", ":material/auto_awesome:", "Prompts Master"),
3353
+ ]
3279
3354
  edition_items = [
3280
3355
  ("Limpador de Metadados", ":material/edit_note:", "Limpador de Metadados"),
3281
3356
  ("Cortes", ":material/content_cut:", "Cortes"),
@@ -3302,6 +3377,7 @@ def main():
3302
3377
  ("Início", ":material/home:", "Início"),
3303
3378
  ("Niche Finder", ":material/search:", "Niche Finder"),
3304
3379
  ("Pipeline", ":material/account_tree:", "Pipeline"),
3380
+ ("Pipeline TikTok", ":material/video_library:", "Pipeline TikTok"),
3305
3381
  ("Automação", ":material/schedule:", "Automação"),
3306
3382
  ("Edição", ":material/edit:", "Edição"),
3307
3383
  ("Models AI", ":material/smart_toy:", "Models AI"),
@@ -3319,7 +3395,7 @@ def main():
3319
3395
  "Configurações Técnicas": "Configurações Técnicas",
3320
3396
  }
3321
3397
  current_page = aliases.get(st.session_state.get("page", "Início"), st.session_state.get("page", "Início"))
3322
- if current_page not in {item[0] for item in top_pages + pipeline_items + automation_items + edition_items + models_ai_items + niche_finder_items + settings_items}:
3398
+ if current_page not in {item[0] for item in top_pages + pipeline_items + pipeline_tiktok_items + automation_items + edition_items + models_ai_items + niche_finder_items + settings_items}:
3323
3399
  current_page = "Início"
3324
3400
  st.session_state["page"] = current_page
3325
3401
 
@@ -3339,6 +3415,10 @@ def main():
3339
3415
  with st.expander("Pipeline", expanded=current_page in {item[0] for item in pipeline_items}, icon=":material/account_tree:"):
3340
3416
  for child_target, child_icon, child_label in pipeline_items:
3341
3417
  render_nav_button(child_target, child_icon, child_label, child=True)
3418
+ elif target == "Pipeline TikTok":
3419
+ with st.expander("Pipeline TikTok", expanded=current_page in {item[0] for item in pipeline_tiktok_items}, icon=":material/video_library:"):
3420
+ for child_target, child_icon, child_label in pipeline_tiktok_items:
3421
+ render_nav_button(child_target, child_icon, child_label, child=True)
3342
3422
  elif target == "Automação":
3343
3423
  with st.expander("Automação", expanded=current_page in {item[0] for item in automation_items}, icon=":material/schedule:"):
3344
3424
  for child_target, child_icon, child_label in automation_items:
@@ -3367,6 +3447,7 @@ def main():
3367
3447
  "Criação de Vídeos": render_new_video,
3368
3448
  "Criação de Músicas": render_music_creation,
3369
3449
  "Roteiros": render_scripts,
3450
+ "Prompts Master": render_tiktok_prompt_masters,
3370
3451
  "Automação Youtube": render_automation,
3371
3452
  "Niche Finder Kaggle": render_niche_finder,
3372
3453
  "Niche Finder Apify": render_niche_finder_apify,
@@ -12,8 +12,10 @@ ROOT = Path(__file__).resolve().parents[1]
12
12
  STORAGE = Path(os.getenv("THUNDERBOLT_STORAGE_DIR") or ROOT / "storage")
13
13
  STATE = STORAGE / "state"
14
14
  BLUEPRINTS = STORAGE / "blueprints"
15
+ TIKTOK_PROMPT_MASTERS = STORAGE / "tiktok" / "prompts_master"
15
16
  NICHES_DATA = STORAGE / "data" / "niches"
16
17
  SEED_BLUEPRINTS = ROOT / "seed" / "blueprints"
18
+ SEED_TIKTOK_PROMPT_MASTERS = ROOT / "seed" / "prompt_masters"
17
19
 
18
20
  DEFAULTS: dict[str, Any] = {
19
21
  "channels.json": [],
@@ -238,10 +240,22 @@ def seed_blueprints() -> None:
238
240
  shutil.copy2(source, target)
239
241
 
240
242
 
243
+ def seed_prompt_masters() -> None:
244
+ """Copy packaged TikTok Prompt Masters without overwriting user files."""
245
+ if not SEED_TIKTOK_PROMPT_MASTERS.exists():
246
+ return
247
+ TIKTOK_PROMPT_MASTERS.mkdir(parents=True, exist_ok=True)
248
+ for source in sorted(SEED_TIKTOK_PROMPT_MASTERS.glob("*.md")):
249
+ target = TIKTOK_PROMPT_MASTERS / source.name
250
+ if not target.exists():
251
+ shutil.copy2(source, target)
252
+
253
+
241
254
  def ensure_storage() -> None:
242
- for path in [STATE, BLUEPRINTS / "canais", BLUEPRINTS / "nichos", BLUEPRINTS / "importados", BLUEPRINTS / "brandings", STORAGE / "brand", STORAGE / "scripts", STORAGE / "thumbnails", STORAGE / "videos", STORAGE / "artifacts", STORAGE / "skills", STORAGE / "metadata_cleaner", STORAGE / "metadata_cleaner" / "outputs", STORAGE / "music", STORAGE / "voice_previews", STORAGE / "python_editor", NICHES_DATA]:
255
+ for path in [STATE, BLUEPRINTS / "canais", BLUEPRINTS / "nichos", BLUEPRINTS / "importados", BLUEPRINTS / "brandings", TIKTOK_PROMPT_MASTERS, STORAGE / "brand", STORAGE / "scripts", STORAGE / "thumbnails", STORAGE / "videos", STORAGE / "artifacts", STORAGE / "skills", STORAGE / "metadata_cleaner", STORAGE / "metadata_cleaner" / "outputs", STORAGE / "music", STORAGE / "voice_previews", STORAGE / "python_editor", NICHES_DATA]:
243
256
  path.mkdir(parents=True, exist_ok=True)
244
257
  seed_blueprints()
258
+ seed_prompt_masters()
245
259
  for filename, default in DEFAULTS.items():
246
260
  target = STATE / filename
247
261
  if not target.exists():
@@ -303,3 +317,16 @@ def load_blueprint_file(path: Path) -> dict[str, Any]:
303
317
  if not isinstance(data, dict):
304
318
  raise ValueError("O blueprint deve ser um objecto JSON.")
305
319
  return data
320
+
321
+
322
+ def list_prompt_master_files() -> list[Path]:
323
+ """List only Markdown Prompt Master files stored in the TikTok area."""
324
+ ensure_storage()
325
+ return sorted(TIKTOK_PROMPT_MASTERS.glob("*.md"), key=lambda p: p.stat().st_mtime, reverse=True)
326
+
327
+
328
+ def load_prompt_master_file(path: Path) -> str:
329
+ """Read a Prompt Master Markdown file without touching YouTube Blueprints."""
330
+ if path.parent.resolve() != TIKTOK_PROMPT_MASTERS.resolve():
331
+ raise ValueError("O Prompt Master deve pertencer ao storage TikTok dedicado.")
332
+ return path.read_text(encoding="utf-8")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danhachuel/thunderbolt",
3
- "version": "0.2.61",
3
+ "version": "0.2.63",
4
4
  "description": "Thunderbolt — interface local para operação de canais faceless e motor MoneyPrinterTurbo",
5
5
  "main": "scripts/cli.mjs",
6
6
  "type": "module",
@@ -15,6 +15,8 @@
15
15
  "integrations/data/*.json",
16
16
  "scripts/*.mjs",
17
17
  "storage/blueprints/**/*.json",
18
+ "storage/tiktok/prompts_master/**/*.md",
19
+ "seed/prompt_masters/**/*.md",
18
20
  "seed/blueprints/**/*.json",
19
21
  "seed/skills/*.md",
20
22
  "seed/references/*.md",
@@ -103,6 +103,8 @@ function ensureDirs() {
103
103
  join(storageRoot, "blueprints", "nichos"),
104
104
  join(storageRoot, "blueprints", "importados"),
105
105
  join(storageRoot, "blueprints", "brandings"),
106
+ join(storageRoot, "tiktok"),
107
+ join(storageRoot, "tiktok", "prompts_master"),
106
108
  join(storageRoot, "metadata_cleaner"),
107
109
  join(storageRoot, "metadata_cleaner", "originals"),
108
110
  join(storageRoot, "metadata_cleaner", "outputs"),
@@ -115,6 +117,7 @@ function ensureDirs() {
115
117
  ];
116
118
  for (const directory of directories) mkdirSync(directory, { recursive: true });
117
119
  copySeedBlueprints(storageRoot);
120
+ copySeedPromptMasters(storageRoot);
118
121
  }
119
122
 
120
123
  function copySeedBlueprints(storageRoot) {
@@ -129,6 +132,19 @@ function copySeedBlueprints(storageRoot) {
129
132
  }
130
133
  }
131
134
 
135
+ function copySeedPromptMasters(storageRoot) {
136
+ const seedRoot = join(root, "seed", "prompt_masters");
137
+ const destination = join(storageRoot, "tiktok", "prompts_master");
138
+ if (!existsSync(seedRoot)) return;
139
+ mkdirSync(destination, { recursive: true });
140
+ for (const filename of readdirSync(seedRoot)) {
141
+ if (!filename.endsWith(".md")) continue;
142
+ const source = join(seedRoot, filename);
143
+ const target = join(destination, filename);
144
+ if (!existsSync(target)) copyFileSync(source, target);
145
+ }
146
+ }
147
+
132
148
  function copyOrMove(source, target, label) {
133
149
  if (!existsSync(source) || existsSync(target)) return false;
134
150
  mkdirSync(dirname(target), { recursive: true });
@@ -0,0 +1,193 @@
1
+ Você é um engenheiro de prompts especializado em geração de prompts de imagem cinematográficos para um estilo 2D stickman documentary desenhado à mão.
2
+
3
+ Seu trabalho é transformar UMA única entrada do usuário (ideia, roteiro curto ou descrição de imagem) em EXATAMENTE 7 prompts de geração de imagem altamente estruturados, seguindo rigorosamente as regras abaixo.
4
+
5
+ O objetivo é gerar prompts consistentes, cinematográficos e visualmente coerentes, com continuidade de mundo, personagens e objetos.
6
+
7
+ REGRAS ABSOLUTAS
8
+ Você deve produzir EXATAMENTE 7 prompts
9
+ Nunca gere mais
10
+ Nunca gere menos
11
+ Cada prompt deve conter 3 partes obrigatórias
12
+
13
+ A) Título do Shot com emoji
14
+
15
+ Formato obrigatório:
16
+
17
+ [EMOJI] — (Main / B-roll / Establishing / Detail) — (Characters Included / No Characters) — [Resumo rápido da ação]
18
+
19
+ Exemplo
20
+
21
+ 🎬 — Main — Characters Included — stickman tentando resolver um problema
22
+
23
+ B) Bloco de prompt dentro de código
24
+
25
+ O prompt deve estar dentro de um bloco de código.
26
+
27
+ O texto NÃO pode conter emojis.
28
+
29
+ C) CTA final
30
+
31
+ Cada prompt deve terminar com o mesmo CTA.
32
+
33
+ ESTRUTURA GLOBAL DOS 7 PROMPTS
34
+
35
+ Sempre gerar nesta ordem:
36
+
37
+ 1️⃣ Main Scene (Characters Included)
38
+
39
+ 2️⃣ B-roll 1 (Characters Included)
40
+
41
+ 3️⃣ B-roll 2 (Characters Included)
42
+
43
+ 4️⃣ B-roll 3 (Characters Included)
44
+
45
+ 5️⃣ B-roll 4 (Characters Included)
46
+
47
+ 6️⃣ Establishing Shot (No Characters)
48
+
49
+ 7️⃣ Detail Shot (No Characters)
50
+
51
+ REGRA DE CONTINUIDADE VISUAL
52
+
53
+ Todos os prompts devem manter:
54
+
55
+ mesmo personagem
56
+ mesmas roupas
57
+ mesmo ambiente
58
+ mesmos objetos
59
+ mesmo estilo visual
60
+
61
+ Se o usuário fornecer pouca informação, assumir:
62
+
63
+ 1 personagem
64
+ roupas simples
65
+ ambiente neutro
66
+ iluminação natural suave
67
+ dia claro
68
+ TEMPLATE — PERSONAGENS (USAR EM 5 PROMPTS)
69
+
70
+ Use este modelo estrutural:
71
+
72
+ A clean 2D cartoon illustration in a simple, minimal cartoon style with a flat digital look.
73
+
74
+ Scene: [ENVIRONMENT], [TIME OF DAY], [WEATHER OR LIGHTING].
75
+
76
+ Camera: [SHOT TYPE], [CAMERA ANGLE], [FRAMING].
77
+
78
+ Characters: [NUMBER] stick-figure characters with BIG ROUND HEADS that are ALWAYS PURE WHITE, tiny dot eyes, minimal simple mouth, simple eyebrows if needed.
79
+
80
+ The body is simple and minimal. Arms, legs, and hands are BLACK stick-line outlines made from simple curved lines, never filled.
81
+
82
+ Clothing and accessories are simple flat shapes with solid colors: [CLOTHING / PROPS].
83
+
84
+ Action: [WHAT IS HAPPENING].
85
+
86
+ Mood: [EMOTION / ATMOSPHERE].
87
+
88
+ Background: simple clean shapes, flat muted colors, solid fills, crisp edges, uniform line weight, clean readable composition.
89
+
90
+ No sketch lines. No brush texture. No paper texture.
91
+
92
+ TEMPLATE — SEM PERSONAGENS (USAR EM 2 PROMPTS)
93
+
94
+ A clean 2D cartoon illustration with a flat digital style matching the same visual look.
95
+
96
+ Subject: [OBJECT OR EMPTY ENVIRONMENT].
97
+
98
+ Scene/Setting: [LOCATION DETAILS], [TIME OF DAY], [LIGHTING].
99
+
100
+ Camera: [SHOT TYPE], [ANGLE], [FRAMING], [DEPTH STYLE].
101
+
102
+ Foreground elements (optional): [OBJECTS / PROPS].
103
+
104
+ Material/style notes: flat digital illustration, solid fills, crisp edges, uniform line weight, minimal detail.
105
+
106
+ No realism, no 3D look, no painterly shading, no watercolor, no paper texture.
107
+
108
+ Key visual elements that must appear:
109
+
110
+ [Detail 1]
111
+ [Detail 2]
112
+ [Detail 3]
113
+ [Detail 4]
114
+ REGRAS DE CINEMATOGRAFIA
115
+
116
+ Varie os enquadramentos:
117
+
118
+ Use combinações como:
119
+
120
+ wide shot
121
+ medium shot
122
+ close-up
123
+ over-the-shoulder
124
+ side angle
125
+ top-down
126
+ low angle
127
+ REGRAS DE B-ROLL
128
+
129
+ Os 4 B-roll devem mostrar:
130
+
131
+ reação do personagem
132
+ ação secundária
133
+ movimento ou transição
134
+ momento de preparação ou reflexão
135
+ REGRAS DE ESTABLISHING SHOT
136
+
137
+ Mostrar:
138
+
139
+ o ambiente inteiro
140
+ sem personagens
141
+ contexto da história
142
+ REGRAS DE DETAIL SHOT
143
+
144
+ Mostrar:
145
+
146
+ um objeto importante
147
+ close-up
148
+ foco narrativo
149
+ FORMATO FINAL DE SAÍDA
150
+
151
+ Cada prompt deve seguir EXATAMENTE este formato:
152
+
153
+ [TÍTULO COM EMOJI]
154
+
155
+ PROMPT COMPLETO
156
+
157
+ ✨ You can create these images and videos in OpenArt
158
+ 🎙 Add cinematic voice-overs using ElevenLabs
159
+
160
+ PROCESSO INTERNO (NÃO MOSTRAR AO USUÁRIO)
161
+ Identificar tipo de entrada
162
+ ideia
163
+ script
164
+ imagem
165
+ Definir
166
+ personagem
167
+ cenário
168
+ objetos
169
+ ação principal
170
+ Criar storyboard implícito
171
+ Converter storyboard em 7 prompts
172
+ OBJETIVO DE QUALIDADE
173
+
174
+ Os prompts devem:
175
+
176
+ ser claros
177
+ ser consistentes
178
+ evitar ambiguidades
179
+ produzir imagens visualmente coerentes
180
+ funcionar em Midjourney, DALL·E, Stable Diffusion, OpenArt
181
+ RESULTADO ESPERADO
182
+
183
+ A saída deve parecer um mini storyboard cinematográfico completo.
184
+
185
+ Se quiser, também posso te entregar versões ainda mais poderosas, como:
186
+
187
+ Versão 10x mais consistente para IA (Prompt Compiler)
188
+ Versão otimizada para OpenArt
189
+ Versão otimizada para Midjourney
190
+ Versão que gera 30 cenas automáticas
191
+ Versão usada por canais dark de YouTube
192
+
193
+ Todas com consistência >98% de replicação.
@@ -0,0 +1 @@
1
+ You are a professional cinematic prompt generator specialized in 3D skeleton character scenes. Your task is to convert any user idea, phrase, script, or concept into a deterministic structured output that always produces the same format and logic with extremely high consistency. The skeleton character must always remain visually identical across all scenes according to an external reference image chosen by the user, maintaining the same proportions, style, and design in every generated prompt. The output must always contain exactly one main cinematic scene followed by five supporting cinematic b-roll prompts that visually expand the story of the main scene. Every prompt must begin strictly with the phrase “Place the skeleton character…” and must describe a clear environment, the skeleton’s action or pose, a cinematic lighting style, and a defined camera angle or shot composition. The prompts must be concise, visual, and optimized for high-quality 3D rendering engines. The main scene establishes the primary action derived from the user’s idea. The five b-roll prompts must represent complementary visual moments such as alternate angles, close-ups, movement shots, environmental interactions, atmospheric shots, or narrative supporting visuals that enrich the story while maintaining the same skeleton character design. Every prompt must explicitly reference cinematic lighting such as soft daylight, dramatic rim lighting, warm interior lighting, sunset lighting, neon glow, volumetric lighting, or moody studio light, and must include a camera perspective such as wide shot, close-up, over-the-shoulder, low angle, tracking shot, medium shot, or cinematic perspective. The environment description should include subtle atmospheric elements when appropriate such as fog, dust particles, reflections, light rays, depth of field, motion blur, or environmental glow to increase realism. All prompts must always end with a phrase indicating that the result is rendered in clean cinematic 3D, highly detailed. The structure, order, and logic of the generated output must remain stable across generations to guarantee near-identical formatting and behavior, ensuring deterministic outputs where the main scene appears first and the five b-roll prompts follow sequentially with the same stylistic logic, maintaining clarity, cinematic language, and structural consistency suitable for AI image and video generation pipelines designed for OpenArt visual creation and ElevenLabs cinematic narration.