mega-brain-ai 1.1.0
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.
Potentially problematic release.
This version of mega-brain-ai might be problematic. Click here for more details.
- package/.claude/CLAUDE.md +155 -0
- package/.claude/commands/agents.md +161 -0
- package/.claude/commands/ask.md +117 -0
- package/.claude/commands/benchmark.md +224 -0
- package/.claude/commands/chat.md +343 -0
- package/.claude/commands/compare.md +116 -0
- package/.claude/commands/conclave.md +194 -0
- package/.claude/commands/config.md +133 -0
- package/.claude/commands/council.md +194 -0
- package/.claude/commands/create-agent.md +452 -0
- package/.claude/commands/debate.md +157 -0
- package/.claude/commands/documentation/create-architecture-documentation.md +175 -0
- package/.claude/commands/dossiers.md +180 -0
- package/.claude/commands/evolve.md +223 -0
- package/.claude/commands/extract-dna.md +170 -0
- package/.claude/commands/extract-knowledge.md +507 -0
- package/.claude/commands/inbox.md +296 -0
- package/.claude/commands/ingest-empresa.md +191 -0
- package/.claude/commands/ingest.md +182 -0
- package/.claude/commands/jarvis-briefing.md +67 -0
- package/.claude/commands/jarvis-control.md +169 -0
- package/.claude/commands/jarvis-full.md +181 -0
- package/.claude/commands/jarvis.md +212 -0
- package/.claude/commands/ler-drive.md +212 -0
- package/.claude/commands/log.md +158 -0
- package/.claude/commands/loop.md +133 -0
- package/.claude/commands/loops.md +73 -0
- package/.claude/commands/mission-autopilot.md +538 -0
- package/.claude/commands/mission.md +353 -0
- package/.claude/commands/process-inbox.md +148 -0
- package/.claude/commands/process-jarvis.md +3036 -0
- package/.claude/commands/process-video.md +131 -0
- package/.claude/commands/rag-search.md +78 -0
- package/.claude/commands/resume.md +33 -0
- package/.claude/commands/save.md +38 -0
- package/.claude/commands/scan-inbox.md +125 -0
- package/.claude/commands/setup.md +99 -0
- package/.claude/commands/system-digest.md +243 -0
- package/.claude/commands/verify.md +182 -0
- package/.claude/commands/view-dna.md +169 -0
- package/.claude/hooks/agent_doctor.py +433 -0
- package/.claude/hooks/agent_memory_persister.py +203 -0
- package/.claude/hooks/auto_formatter.py +158 -0
- package/.claude/hooks/checkpoint_writer.py +244 -0
- package/.claude/hooks/claude_md_guard.py +146 -0
- package/.claude/hooks/creation_validator.py +357 -0
- package/.claude/hooks/enforce_dual_location.py +501 -0
- package/.claude/hooks/enforce_plan_mode.py +220 -0
- package/.claude/hooks/inbox_age_alert.py +367 -0
- package/.claude/hooks/jarvis_briefing.py +506 -0
- package/.claude/hooks/ledger_updater.py +301 -0
- package/.claude/hooks/memory_hints_injector.py +251 -0
- package/.claude/hooks/memory_updater.py +202 -0
- package/.claude/hooks/multi_agent_hook.py +464 -0
- package/.claude/hooks/notification_system.py +120 -0
- package/.claude/hooks/pattern_analyzer.py +526 -0
- package/.claude/hooks/pending_tracker.py +188 -0
- package/.claude/hooks/post_batch_cascading.py +1740 -0
- package/.claude/hooks/post_output_validator.py +358 -0
- package/.claude/hooks/post_tool_use.py +120 -0
- package/.claude/hooks/post_write_validator.py +200 -0
- package/.claude/hooks/quality_watchdog.py +394 -0
- package/.claude/hooks/ralph_wiggum.py +277 -0
- package/.claude/hooks/session-source-sync.py +218 -0
- package/.claude/hooks/session_autosave_v2.py +1135 -0
- package/.claude/hooks/session_end.py +203 -0
- package/.claude/hooks/session_start.py +939 -0
- package/.claude/hooks/skill_indexer.py +48 -0
- package/.claude/hooks/skill_router.py +358 -0
- package/.claude/hooks/stop_hook_completeness.py +178 -0
- package/.claude/hooks/subagent_tracker.py +163 -0
- package/.claude/hooks/token_checkpoint.py +584 -0
- package/.claude/hooks/user_prompt_submit.py +125 -0
- package/.claude/rules/ANTHROPIC-STANDARDS.md +384 -0
- package/.claude/rules/CLAUDE-LITE.md +201 -0
- package/.claude/rules/RULE-GROUP-1.md +320 -0
- package/.claude/rules/RULE-GROUP-2.md +307 -0
- package/.claude/rules/RULE-GROUP-3.md +248 -0
- package/.claude/rules/RULE-GROUP-4.md +427 -0
- package/.claude/rules/RULE-GROUP-5.md +388 -0
- package/.claude/rules/RULE-GROUP-6.md +387 -0
- package/.claude/rules/logging.md +53 -0
- package/.claude/rules/mcp-governance.md +128 -0
- package/.claude/rules/pipeline.md +60 -0
- package/.claude/rules/state-management.md +93 -0
- package/.claude/scripts/apply-tags.py +77 -0
- package/.claude/scripts/batch-extract-transcriptions.py +132 -0
- package/.claude/scripts/build-complete-index.py +250 -0
- package/.claude/scripts/build-planilha-index.py +170 -0
- package/.claude/scripts/complete-tag-matching.py +250 -0
- package/.claude/scripts/deduplicate-inbox.py +139 -0
- package/.claude/scripts/docx-xml-extractor.py +141 -0
- package/.claude/scripts/extract-docx-text.py +58 -0
- package/.claude/scripts/extract-single-transcription.py +74 -0
- package/.claude/scripts/extract_docx_from_gdrive.py +77 -0
- package/.claude/scripts/organized-downloader.py +246 -0
- package/.claude/scripts/planilha-tagger.py +187 -0
- package/.claude/scripts/revert-tags.py +70 -0
- package/.claude/scripts/source-sync.py +265 -0
- package/.claude/scripts/tag-inbox-files.py +276 -0
- package/.claude/scripts/tag-inbox-v2.py +253 -0
- package/.claude/scripts/test-extraction.py +35 -0
- package/.claude/scripts/test-full-extraction.py +74 -0
- package/.claude/skills/00-SKILL-CREATOR/SKILL.md +186 -0
- package/.claude/skills/01-SKILL-DOCS-MEGABRAIN/SKILL.md +251 -0
- package/.claude/skills/02-SKILL-PYTHON-MEGABRAIN/SKILL.md +323 -0
- package/.claude/skills/03-SKILL-AGENT-CREATION/SKILL.md +374 -0
- package/.claude/skills/04-SKILL-KNOWLEDGE-EXTRACTION/SKILL.md +318 -0
- package/.claude/skills/05-SKILL-PIPELINE-JARVIS/SKILL.md +430 -0
- package/.claude/skills/06-SKILL-BRAINSTORMING/SKILL.md +72 -0
- package/.claude/skills/07-SKILL-DISPATCHING-PARALLEL-AGENTS/SKILL.md +193 -0
- package/.claude/skills/08-SKILL-EXECUTING-PLANS/SKILL.md +114 -0
- package/.claude/skills/09-SKILL-WRITING-PLANS/SKILL.md +184 -0
- package/.claude/skills/10-SKILL-VERIFICATION-BEFORE-COMPLETION/SKILL.md +130 -0
- package/.claude/skills/11-SKILL-USING-SUPERPOWERS/SKILL.md +105 -0
- package/.claude/skills/DETECTION-PROTOCOL.md +217 -0
- package/.claude/skills/README.md +240 -0
- package/.claude/skills/SKILL-REGISTRY.md +284 -0
- package/.claude/skills/SKILL-SUGGESTIONS.md +114 -0
- package/.claude/skills/_TEMPLATES/SKILL-WRITER-GUIDE.md +385 -0
- package/.claude/skills/chronicler/SKILL.md +146 -0
- package/.claude/skills/chronicler/chronicler_core.py +468 -0
- package/.claude/skills/code-review/SKILL.md +160 -0
- package/.claude/skills/council/SKILL.md +210 -0
- package/.claude/skills/executor/SKILL.md +161 -0
- package/.claude/skills/fase-2-5-tagging/SKILL.md +182 -0
- package/.claude/skills/feature-dev/SKILL.md +154 -0
- package/.claude/skills/finance-agent/SKILL.md +137 -0
- package/.claude/skills/frontend-design/SKILL.md +165 -0
- package/.claude/skills/gdrive-transcription-downloader/SKILL.md +249 -0
- package/.claude/skills/gemini-fallback/SKILL.md +67 -0
- package/.claude/skills/gemini-fallback/gemini_fetch.py +0 -0
- package/.claude/skills/gha/SKILL.md +96 -0
- package/.claude/skills/gha/gha_diagnostic.py +227 -0
- package/.claude/skills/github-workflow/SKILL.md +190 -0
- package/.claude/skills/hookify/SKILL.md +134 -0
- package/.claude/skills/hybrid-source-reading/SKILL.md +265 -0
- package/.claude/skills/jarvis/SKILL.md +546 -0
- package/.claude/skills/jarvis-briefing/SKILL.md +340 -0
- package/.claude/skills/ler-planilha/SKILL.md +281 -0
- package/.claude/skills/plugin-dev/SKILL.md +176 -0
- package/.claude/skills/pr-review-toolkit/SKILL.md +178 -0
- package/.claude/skills/resume/SKILL.md +61 -0
- package/.claude/skills/save/SKILL.md +87 -0
- package/.claude/skills/skill-writer/SKILL.md +153 -0
- package/.claude/skills/skill-writer/examples.md +191 -0
- package/.claude/skills/skill-writer/troubleshooting.md +205 -0
- package/.claude/skills/smart-download-tagger/SKILL.md +148 -0
- package/.claude/skills/source-sync/SKILL.md +240 -0
- package/.claude/skills/sync-docs/SKILL.md +193 -0
- package/.claude/skills/sync-docs/config.json +37 -0
- package/.claude/skills/sync-docs/gdrive_sync.py +358 -0
- package/.claude/skills/sync-docs/reauth.py +71 -0
- package/.claude/skills/talent-agent/SKILL.md +183 -0
- package/.claude/skills/verify/SKILL.md +154 -0
- package/.claude/skills/verify/verify_runner.py +0 -0
- package/.claude/skills/verify-6-levels/SKILL.md +234 -0
- package/.claude/templates/BATCH-LOG-TEMPLATE.md +221 -0
- package/.claudeignore +9 -0
- package/.gitattributes +4 -0
- package/.github/layer1-allowlist.txt +80 -0
- package/.github/layer2-manifest.txt +40 -0
- package/.gitignore +219 -0
- package/README.md +1210 -0
- package/agents/_templates/INDEX.md +741 -0
- package/agents/_templates/TEMPLATE-AGENT-MD-ULTRA-ROBUSTO-V3.md +2399 -0
- package/agents/boardroom/CHECKLIST-MASTER.md +281 -0
- package/agents/boardroom/INTEGRATION-GUIDE.md +406 -0
- package/agents/boardroom/README.md +238 -0
- package/agents/boardroom/config/BOARDROOM-CONFIG.md +186 -0
- package/agents/boardroom/config/TTS-INTEGRATION.md +258 -0
- package/agents/boardroom/config/VOICE-PROFILES.md +624 -0
- package/agents/boardroom/config/voice_mapping.json +128 -0
- package/agents/boardroom/scripts/audio_generator.py +375 -0
- package/agents/boardroom/scripts/audio_generator_edge.py +353 -0
- package/agents/boardroom/scripts/jarvis_boardroom_hook.py +415 -0
- package/agents/boardroom/scripts/notebooklm_generator.py +578 -0
- package/agents/boardroom/templates/EPISODE-TEMPLATE.md +367 -0
- package/agents/boardroom/templates/scene-templates/SCENE-AGENT-DEBATE.md +252 -0
- package/agents/boardroom/templates/scene-templates/SCENE-COUNCIL.md +270 -0
- package/agents/boardroom/templates/scene-templates/SCENE-DNA-CONSULTATION.md +126 -0
- package/agents/boardroom/templates/scene-templates/SCENE-QUESTION.md +174 -0
- package/agents/boardroom/workflows/WORKFLOW-AUDIO-GENERATION.md +421 -0
- package/agents/constitution/BASE-CONSTITUTION.md +254 -0
- package/agents/council/CRITIC.md +197 -0
- package/agents/council/DEVILS-ADVOCATE.md +274 -0
- package/agents/council/SYNTHESIZER.md +293 -0
- package/agents/council/advogado-do-diabo/AGENT.md +489 -0
- package/agents/council/advogado-do-diabo/SOUL.md +100 -0
- package/agents/council/critico-metodologico/AGENT.md +670 -0
- package/agents/council/critico-metodologico/SOUL.md +107 -0
- package/agents/council/sintetizador/AGENT.md +558 -0
- package/agents/council/sintetizador/SOUL.md +94 -0
- package/agents/persons/_example/AGENT-EXAMPLE.md +42 -0
- package/agents/persons/_example/DNA-EXAMPLE.yaml +61 -0
- package/agents/protocols/AGENT-COGNITION-PROTOCOL.md +779 -0
- package/agents/protocols/AGENT-INTEGRITY-PROTOCOL.md +692 -0
- package/agents/protocols/BATCH-VISUAL-PROTOCOL.md +841 -0
- package/agents/protocols/DNA-CONFIG-TEMPLATE.yaml +181 -0
- package/agents/protocols/DNA-EXTRACTION-PROTOCOL.md +370 -0
- package/agents/protocols/EPISTEMIC-PROTOCOL.md +333 -0
- package/agents/protocols/LOG-STRUCTURE-PROTOCOL.md +65 -0
- package/agents/protocols/MEMORY-PROTOCOL.md +567 -0
- package/agents/protocols/NARRATIVE-SYNTHESIS-PROTOCOL.md +278 -0
- package/agents/protocols/PHASE-4-VERIFICATION-CHECKPOINT.md +146 -0
- package/agents/protocols/SOUL-TEMPLATE.md +416 -0
- package/agents/protocols/TEMPLATE-EVOLUTION-PROTOCOL.md +544 -0
- package/agents/protocols/VISUAL-DIFF-PROTOCOL.md +159 -0
- package/agents/sua-empresa/README.md +44 -0
- package/agents/sua-empresa/_example/jds/EXAMPLE-JD.md +42 -0
- package/agents/sua-empresa/_example/org/EXAMPLE-ORG.md +32 -0
- package/agents/sua-empresa/_example/roles/EXAMPLE-ROLE.md +38 -0
- package/bin/cli.js +2 -0
- package/bin/lib/ascii-art.js +234 -0
- package/bin/lib/installer.js +402 -0
- package/bin/lib/setup-wizard.js +95 -0
- package/bin/lib/validate-email.js +109 -0
- package/bin/mega-brain.js +97 -0
- package/bin/push.js +342 -0
- package/bin/templates/env.example +38 -0
- package/inbox/.gitkeep +0 -0
- package/integrations/README.md +46 -0
- package/integrations/mcps/MCP-REGISTRY.md +56 -0
- package/integrations/mcps/excalidraw/CONFIG.md +56 -0
- package/integrations/mcps/gdrive/CONFIG.md +38 -0
- package/knowledge/dna/.gitkeep +0 -0
- package/knowledge/dossiers/persons/.gitkeep +0 -0
- package/knowledge/dossiers/persons/DOSSIER-EXAMPLE.md +49 -0
- package/knowledge/dossiers/system/.gitkeep +0 -0
- package/knowledge/dossiers/themes/.gitkeep +0 -0
- package/knowledge/playbooks/.gitkeep +0 -0
- package/knowledge/playbooks/PLAYBOOK-EXAMPLE.md +50 -0
- package/knowledge/sources/.gitkeep +0 -0
- package/logs/.gitkeep +0 -0
- package/package.json +128 -0
- package/processing/canonical/.gitkeep +0 -0
- package/processing/chunks/.gitkeep +0 -0
- package/processing/insights/.gitkeep +0 -0
- package/processing/narratives/.gitkeep +0 -0
- package/reference/CONSELHO.md +337 -0
- package/reference/CONTEXT7_README.md +28 -0
- package/reference/JARVIS-LOGGING-PROTOCOL.md +380 -0
- package/reference/QUICK-START.md +197 -0
- package/reference/README-RALPH-CASCATEAMENTO.md +207 -0
- package/reference/TEMPLATE-MASTER.md +727 -0
- package/reference/prds/prd-jarvis-mega-brain-v3.md +1305 -0
- package/reference/templates/phase5/IMPLEMENTATION-GUIDE.md +355 -0
- package/reference/templates/phase5/MOGA-BRAIN-PHASE5-TEMPLATES.md +1284 -0
- package/reference/templates/phase5/README.md +165 -0
- package/reference/workflow-claude-code-boris-cherny-continuous-claude.md +2232 -0
- package/system/database/001_moneyclub_buyers.sql +160 -0
- package/system/database/002_premium_token.sql +97 -0
- package/system/database/apply-migration.mjs +129 -0
- package/system/docs/MEGA-BRAIN-DEMO-COMPLETA.md +1226 -0
- package/system/docs/MEGA-BRAIN-MANIFESTO-COMPLETO.md +1054 -0
- package/system/docs/MOGA-BRAIN-EXPLICACAO-COMPLETA.md +791 -0
- package/system/docs/STRATEGIC-INTEGRATION-GUIDE.md +725 -0
- package/system/docs/architecture/01-system-context.md +136 -0
- package/system/docs/architecture/02-components.md +225 -0
- package/system/docs/architecture/03-data-flow.md +235 -0
- package/system/docs/architecture/04-integrations.md +283 -0
- package/system/docs/architecture/README.md +71 -0
- package/system/docs/architecture/diagrams/component-diagram.mmd +50 -0
- package/system/docs/architecture/diagrams/data-flow.mmd +39 -0
- package/system/docs/architecture/diagrams/system-overview.mmd +68 -0
- package/system/protocols/AGENT-AUTHORITY.md +217 -0
- package/system/protocols/CONSTITUICAO-BASE.md +115 -0
- package/system/protocols/CONSTITUTION.md +231 -0
- package/system/protocols/GOVERNANCE-MAP.md +123 -0
- package/system/protocols/HOOK-SECURITY-THREAT-MODEL.md +152 -0
- package/system/protocols/ORQUESTRACAO-PROTOCOL.md +215 -0
- package/system/protocols/_archive/CHUNKING-PROTOCOL.md +207 -0
- package/system/protocols/_archive/ENTITY-RESOLUTION-PROTOCOL.md +269 -0
- package/system/protocols/_archive/INSIGHT-EXTRACTION-PROTOCOL.md +257 -0
- package/system/protocols/_archive/NARRATIVE-SYNTHESIS-PROTOCOL.md +290 -0
- package/system/protocols/agents/AGENT-INTERACTION.md +315 -0
- package/system/protocols/agents/CORTEX-PROTOCOL.md +520 -0
- package/system/protocols/agents/EPISTEMIC-PROTOCOL.md +465 -0
- package/system/protocols/agents/MEMORY-PROTOCOL.md +366 -0
- package/system/protocols/agents/WAR-ROOM.md +355 -0
- package/system/protocols/company/COMPANY-DOCUMENT-PROTOCOL.md +793 -0
- package/system/protocols/company/COMPANY-ENRICHMENT-PROTOCOL.md +679 -0
- package/system/protocols/conclave/CONCLAVE-LOG-TEMPLATE-v2.md +309 -0
- package/system/protocols/conclave/CONCLAVE-PROTOCOL.md +518 -0
- package/system/protocols/conclave/DEBATE-DYNAMICS-CONFIG.yaml +322 -0
- package/system/protocols/conclave/DEBATE-DYNAMICS-PROTOCOL.md +613 -0
- package/system/protocols/conclave/DEBATE-PROTOCOL.md +323 -0
- package/system/protocols/council/COUNCIL-LOG-TEMPLATE-v2.md +309 -0
- package/system/protocols/council/COUNCIL-PROTOCOL.md +518 -0
- package/system/protocols/council/DEBATE-DYNAMICS-CONFIG.yaml +322 -0
- package/system/protocols/council/DEBATE-DYNAMICS-PROTOCOL.md +613 -0
- package/system/protocols/council/DEBATE-PROTOCOL.md +323 -0
- package/system/protocols/dna/DNA-EXTRACTION-PROTOCOL.md +1214 -0
- package/system/protocols/dna/ENRICHMENT-PROTOCOL.md +408 -0
- package/system/protocols/dna/REASONING-MODEL-PROTOCOL.md +331 -0
- package/system/protocols/pipeline/DOSSIER-COMPILATION-PROTOCOL.md +790 -0
- package/system/protocols/pipeline/NARRATIVE-METABOLISM-PROTOCOL.md +292 -0
- package/system/protocols/pipeline/PIPELINE-JARVIS-v2.1.md +606 -0
- package/system/protocols/pipeline/PROMPT-1.1-CHUNKING.md +154 -0
- package/system/protocols/pipeline/PROMPT-1.2-ENTITY-RESOLUTION.md +186 -0
- package/system/protocols/pipeline/PROMPT-2.1-DNA-TAGS-INCREMENT.md +208 -0
- package/system/protocols/pipeline/PROMPT-2.1-INSIGHT-EXTRACTION.md +191 -0
- package/system/protocols/pipeline/PROMPT-3.1-NARRATIVE-SYNTHESIS.md +331 -0
- package/system/protocols/pipeline/SOURCES-COMPILATION-PROTOCOL.md +340 -0
- package/system/protocols/system/AUTO-LOG-PROTOCOL.md +369 -0
- package/system/protocols/system/CHECKPOINT-ENFORCEMENT.md +176 -0
- package/system/protocols/system/ENFORCEMENT.md +435 -0
- package/system/protocols/system/LOG-TEMPLATES.md +1068 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
BOARDROOM WARFARE - Audio Generator (Edge TTS)
|
|
4
|
+
Gera arquivos de audio a partir de scripts .md usando Edge TTS (gratuito)
|
|
5
|
+
|
|
6
|
+
Uso:
|
|
7
|
+
python audio_generator_edge.py <script.md> [--output <output.mp3>]
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import re
|
|
12
|
+
import asyncio
|
|
13
|
+
import argparse
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import List
|
|
16
|
+
from dataclasses import dataclass
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
|
|
19
|
+
# Configurar ffmpeg/ffprobe ANTES de importar pydub (Windows requirement)
|
|
20
|
+
_ffmpeg_bin = Path(r"C:\ffmpeg\bin")
|
|
21
|
+
_ffmpeg_path = _ffmpeg_bin / "ffmpeg.exe"
|
|
22
|
+
_ffprobe_path = _ffmpeg_bin / "ffprobe.exe"
|
|
23
|
+
|
|
24
|
+
if _ffmpeg_path.exists() and _ffprobe_path.exists():
|
|
25
|
+
os.environ["FFMPEG_BINARY"] = str(_ffmpeg_path)
|
|
26
|
+
os.environ["FFPROBE_BINARY"] = str(_ffprobe_path)
|
|
27
|
+
os.environ["PATH"] = str(_ffmpeg_bin) + os.pathsep + os.environ.get("PATH", "")
|
|
28
|
+
print(f"[OK] ffmpeg configurado: {_ffmpeg_path}")
|
|
29
|
+
else:
|
|
30
|
+
print("[!] ffmpeg/ffprobe nao encontrados no caminho esperado")
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
import edge_tts
|
|
34
|
+
EDGE_TTS_AVAILABLE = True
|
|
35
|
+
except ImportError:
|
|
36
|
+
EDGE_TTS_AVAILABLE = False
|
|
37
|
+
print("[!] edge-tts nao instalado. Use: pip install edge-tts")
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
from pydub import AudioSegment
|
|
41
|
+
PYDUB_AVAILABLE = True
|
|
42
|
+
AudioSegment.converter = str(_ffmpeg_path)
|
|
43
|
+
AudioSegment.ffprobe = str(_ffprobe_path)
|
|
44
|
+
except ImportError:
|
|
45
|
+
PYDUB_AVAILABLE = False
|
|
46
|
+
print("[!] pydub nao instalado. Use: pip install pydub")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ═══════════════════════════════════════════════════════════════
|
|
50
|
+
# CONFIGURACAO
|
|
51
|
+
# ═══════════════════════════════════════════════════════════════
|
|
52
|
+
|
|
53
|
+
OUTPUT_PATH = Path(__file__).parent.parent / "outputs" / "AUDIO"
|
|
54
|
+
TEMP_PATH = Path(__file__).parent.parent / "outputs" / "temp"
|
|
55
|
+
|
|
56
|
+
OUTPUT_PATH.mkdir(parents=True, exist_ok=True)
|
|
57
|
+
TEMP_PATH.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
|
|
59
|
+
# Mapeamento de vozes Edge TTS para speakers
|
|
60
|
+
# Vozes disponiveis pt-BR:
|
|
61
|
+
# - pt-BR-AntonioNeural (Male) - voz grave, autoritaria
|
|
62
|
+
# - pt-BR-FranciscaNeural (Female) - voz feminina padrao
|
|
63
|
+
# - pt-BR-ThalitaMultilingualNeural (Female) - voz feminina multilingual
|
|
64
|
+
|
|
65
|
+
VOICE_MAPPING = {
|
|
66
|
+
# Narracao principal - voz masculina grave
|
|
67
|
+
"NARRATOR": "pt-BR-AntonioNeural",
|
|
68
|
+
|
|
69
|
+
# Citador - voz neutra, feminina para contrastar
|
|
70
|
+
"CITADOR": "pt-BR-FranciscaNeural",
|
|
71
|
+
|
|
72
|
+
# C-Level executivos - alternar para diferenciar
|
|
73
|
+
"CRO": "pt-BR-AntonioNeural", # Revenue - assertivo
|
|
74
|
+
"CFO": "pt-BR-FranciscaNeural", # Finance - analitico
|
|
75
|
+
|
|
76
|
+
# Council - vozes distintas
|
|
77
|
+
"METHODOLOGICAL-CRITIC": "pt-BR-ThalitaMultilingualNeural", # Critico
|
|
78
|
+
"DEVILS-ADVOCATE": "pt-BR-AntonioNeural", # Provocador
|
|
79
|
+
"SYNTHESIZER": "pt-BR-FranciscaNeural", # Sintetizador
|
|
80
|
+
|
|
81
|
+
# Fallback
|
|
82
|
+
"DEFAULT": "pt-BR-AntonioNeural"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Ajustes de rate/pitch por speaker para diferenciar vozes iguais
|
|
86
|
+
VOICE_ADJUSTMENTS = {
|
|
87
|
+
"NARRATOR": {"rate": "-5%", "pitch": "-5Hz"}, # Mais lento, mais grave
|
|
88
|
+
"CITADOR": {"rate": "+0%", "pitch": "+0Hz"}, # Neutro
|
|
89
|
+
"CRO": {"rate": "+10%", "pitch": "+0Hz"}, # Mais rapido, energico
|
|
90
|
+
"CFO": {"rate": "-5%", "pitch": "+5Hz"}, # Mais lento, analitico
|
|
91
|
+
"METHODOLOGICAL-CRITIC": {"rate": "+0%", "pitch": "-3Hz"},
|
|
92
|
+
"DEVILS-ADVOCATE": {"rate": "+15%", "pitch": "+3Hz"}, # Agressivo
|
|
93
|
+
"SYNTHESIZER": {"rate": "-10%", "pitch": "+0Hz"}, # Calmo, ponderado
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass
|
|
98
|
+
class Segment:
|
|
99
|
+
"""Representa um segmento de audio a ser gerado."""
|
|
100
|
+
index: int
|
|
101
|
+
speaker: str
|
|
102
|
+
text: str
|
|
103
|
+
instruction: str = ""
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# ═══════════════════════════════════════════════════════════════
|
|
107
|
+
# PARSING DO SCRIPT
|
|
108
|
+
# ═══════════════════════════════════════════════════════════════
|
|
109
|
+
|
|
110
|
+
def parse_script(script_path: Path) -> List[Segment]:
|
|
111
|
+
"""
|
|
112
|
+
Parse um script .md e extrai os segmentos de fala.
|
|
113
|
+
|
|
114
|
+
Formato esperado:
|
|
115
|
+
[PERSONAGEM]
|
|
116
|
+
(instrucao opcional)
|
|
117
|
+
"Texto da fala"
|
|
118
|
+
"""
|
|
119
|
+
segments = []
|
|
120
|
+
|
|
121
|
+
with open(script_path, 'r', encoding='utf-8') as f:
|
|
122
|
+
content = f.read()
|
|
123
|
+
|
|
124
|
+
# Regex para capturar falas
|
|
125
|
+
pattern = r'\[([A-Z_-]+)\]\s*(?:\(([^)]+)\))?\s*\n([^\[\n]+(?:\n(?!\[)[^\[\n]+)*)'
|
|
126
|
+
|
|
127
|
+
matches = re.findall(pattern, content)
|
|
128
|
+
|
|
129
|
+
for i, (speaker, instruction, text) in enumerate(matches):
|
|
130
|
+
# Limpar texto
|
|
131
|
+
text = text.strip()
|
|
132
|
+
text = re.sub(r'^["\']|["\']$', '', text) # Remove aspas
|
|
133
|
+
text = re.sub(r'\[PAUSA.*?\]', '', text) # Remove marcacoes de pausa
|
|
134
|
+
text = re.sub(r'\[SOM:.*?\]', '', text) # Remove marcacoes de som
|
|
135
|
+
text = text.strip()
|
|
136
|
+
|
|
137
|
+
if text:
|
|
138
|
+
segments.append(Segment(
|
|
139
|
+
index=i,
|
|
140
|
+
speaker=speaker.strip(),
|
|
141
|
+
text=text,
|
|
142
|
+
instruction=instruction.strip() if instruction else ""
|
|
143
|
+
))
|
|
144
|
+
|
|
145
|
+
return segments
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# ═══════════════════════════════════════════════════════════════
|
|
149
|
+
# GERACAO DE AUDIO
|
|
150
|
+
# ═══════════════════════════════════════════════════════════════
|
|
151
|
+
|
|
152
|
+
async def generate_audio_segment(segment: Segment, output_file: Path) -> bool:
|
|
153
|
+
"""
|
|
154
|
+
Gera audio para um segmento usando Edge TTS.
|
|
155
|
+
"""
|
|
156
|
+
if not EDGE_TTS_AVAILABLE:
|
|
157
|
+
raise RuntimeError("edge-tts nao esta instalado")
|
|
158
|
+
|
|
159
|
+
# Buscar voz para o speaker
|
|
160
|
+
speaker_key = segment.speaker.upper().replace(" ", "-")
|
|
161
|
+
voice = VOICE_MAPPING.get(speaker_key, VOICE_MAPPING["DEFAULT"])
|
|
162
|
+
|
|
163
|
+
# Buscar ajustes de voz
|
|
164
|
+
adjustments = VOICE_ADJUSTMENTS.get(speaker_key, {"rate": "+0%", "pitch": "+0Hz"})
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
communicate = edge_tts.Communicate(
|
|
168
|
+
text=segment.text,
|
|
169
|
+
voice=voice,
|
|
170
|
+
rate=adjustments["rate"],
|
|
171
|
+
pitch=adjustments["pitch"]
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
await communicate.save(str(output_file))
|
|
175
|
+
return True
|
|
176
|
+
|
|
177
|
+
except Exception as e:
|
|
178
|
+
print(f" [X] Erro Edge TTS: {e}")
|
|
179
|
+
return False
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def generate_silence(duration_seconds: float) -> AudioSegment:
|
|
183
|
+
"""Gera segmento de silencio."""
|
|
184
|
+
return AudioSegment.silent(duration=int(duration_seconds * 1000))
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
# ═══════════════════════════════════════════════════════════════
|
|
188
|
+
# PIPELINE PRINCIPAL
|
|
189
|
+
# ═══════════════════════════════════════════════════════════════
|
|
190
|
+
|
|
191
|
+
async def generate_episode_audio(script_path: Path, output_path: Path = None) -> Path:
|
|
192
|
+
"""
|
|
193
|
+
Pipeline completo de geracao de audio.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
script_path: Caminho para o script .md
|
|
197
|
+
output_path: Caminho para o arquivo de saida (opcional)
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
Path do arquivo de audio gerado
|
|
201
|
+
"""
|
|
202
|
+
if not PYDUB_AVAILABLE:
|
|
203
|
+
raise RuntimeError("pydub nao esta instalado")
|
|
204
|
+
|
|
205
|
+
print(f"\n{'='*60}")
|
|
206
|
+
print("[MOVIE] BOARDROOM WARFARE - GERACAO DE AUDIO (Edge TTS)")
|
|
207
|
+
print(f"{'='*60}\n")
|
|
208
|
+
|
|
209
|
+
# 1. Parse do script
|
|
210
|
+
print("[DOC] Parsing do script...")
|
|
211
|
+
segments = parse_script(script_path)
|
|
212
|
+
print(f" {len(segments)} segmentos encontrados")
|
|
213
|
+
|
|
214
|
+
# Mostrar speakers unicos
|
|
215
|
+
unique_speakers = set(s.speaker for s in segments)
|
|
216
|
+
print(f" Speakers: {', '.join(sorted(unique_speakers))}")
|
|
217
|
+
|
|
218
|
+
# 2. Gerar segmentos de audio
|
|
219
|
+
print("\n[AUDIO] Gerando segmentos de audio...")
|
|
220
|
+
audio_segments = []
|
|
221
|
+
|
|
222
|
+
for i, segment in enumerate(segments):
|
|
223
|
+
speaker_display = segment.speaker[:15].ljust(15)
|
|
224
|
+
text_preview = segment.text[:40] + "..." if len(segment.text) > 40 else segment.text
|
|
225
|
+
print(f" [{i+1:02d}/{len(segments):02d}] {speaker_display} {text_preview}")
|
|
226
|
+
|
|
227
|
+
temp_file = TEMP_PATH / f"segment_{i:04d}.mp3"
|
|
228
|
+
|
|
229
|
+
try:
|
|
230
|
+
success = await generate_audio_segment(segment, temp_file)
|
|
231
|
+
|
|
232
|
+
if success and temp_file.exists():
|
|
233
|
+
audio_segment = AudioSegment.from_mp3(temp_file)
|
|
234
|
+
audio_segments.append(audio_segment)
|
|
235
|
+
duration_sec = len(audio_segment) / 1000
|
|
236
|
+
print(f" [OK] {duration_sec:.1f}s")
|
|
237
|
+
else:
|
|
238
|
+
print(f" [!] Usando silencio como placeholder")
|
|
239
|
+
audio_segments.append(generate_silence(2))
|
|
240
|
+
|
|
241
|
+
except Exception as e:
|
|
242
|
+
print(f" [X] Erro: {e}")
|
|
243
|
+
audio_segments.append(generate_silence(2))
|
|
244
|
+
|
|
245
|
+
# 3. Concatenar
|
|
246
|
+
print("\n[LINK] Concatenando segmentos...")
|
|
247
|
+
final_audio = AudioSegment.empty()
|
|
248
|
+
|
|
249
|
+
for i, segment_audio in enumerate(audio_segments):
|
|
250
|
+
final_audio += segment_audio
|
|
251
|
+
# Pausa entre falas baseada no tipo de transicao
|
|
252
|
+
if i < len(segments) - 1:
|
|
253
|
+
current_speaker = segments[i].speaker
|
|
254
|
+
next_speaker = segments[i + 1].speaker
|
|
255
|
+
|
|
256
|
+
# Pausa maior entre speakers diferentes
|
|
257
|
+
if current_speaker != next_speaker:
|
|
258
|
+
final_audio += generate_silence(0.8)
|
|
259
|
+
else:
|
|
260
|
+
final_audio += generate_silence(0.4)
|
|
261
|
+
|
|
262
|
+
# 4. Exportar
|
|
263
|
+
if output_path is None:
|
|
264
|
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
265
|
+
script_name = script_path.stem
|
|
266
|
+
output_path = OUTPUT_PATH / f"{script_name}_{timestamp}.mp3"
|
|
267
|
+
|
|
268
|
+
print(f"\n[SAVE] Exportando para: {output_path}")
|
|
269
|
+
final_audio.export(output_path, format="mp3", bitrate="192k")
|
|
270
|
+
|
|
271
|
+
# 5. Limpar arquivos temporarios
|
|
272
|
+
print("\n[CLEAN] Limpando arquivos temporarios...")
|
|
273
|
+
for temp_file in TEMP_PATH.glob("segment_*.mp3"):
|
|
274
|
+
temp_file.unlink()
|
|
275
|
+
|
|
276
|
+
# 6. Resumo
|
|
277
|
+
duration_minutes = len(final_audio) / 1000 / 60
|
|
278
|
+
print(f"\n{'='*60}")
|
|
279
|
+
print("[OK] AUDIO GERADO COM SUCESSO")
|
|
280
|
+
print(f"{'='*60}")
|
|
281
|
+
print(f" [FILE] Arquivo: {output_path}")
|
|
282
|
+
print(f" [TIME] Duracao: {duration_minutes:.1f} minutos")
|
|
283
|
+
print(f" [MASK] Vozes: {len(unique_speakers)}")
|
|
284
|
+
print(f" [COST] Custo: GRATUITO (Edge TTS)")
|
|
285
|
+
print(f"{'='*60}\n")
|
|
286
|
+
|
|
287
|
+
return output_path
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
# ═══════════════════════════════════════════════════════════════
|
|
291
|
+
# CLI
|
|
292
|
+
# ═══════════════════════════════════════════════════════════════
|
|
293
|
+
|
|
294
|
+
def main():
|
|
295
|
+
parser = argparse.ArgumentParser(
|
|
296
|
+
description="Gera audio a partir de scripts Boardroom Warfare (Edge TTS - gratuito)"
|
|
297
|
+
)
|
|
298
|
+
parser.add_argument(
|
|
299
|
+
"script",
|
|
300
|
+
type=Path,
|
|
301
|
+
help="Caminho para o script .md"
|
|
302
|
+
)
|
|
303
|
+
parser.add_argument(
|
|
304
|
+
"--output", "-o",
|
|
305
|
+
type=Path,
|
|
306
|
+
default=None,
|
|
307
|
+
help="Caminho para o arquivo de saida"
|
|
308
|
+
)
|
|
309
|
+
parser.add_argument(
|
|
310
|
+
"--dry-run",
|
|
311
|
+
action="store_true",
|
|
312
|
+
help="Apenas parse o script, nao gera audio"
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
args = parser.parse_args()
|
|
316
|
+
|
|
317
|
+
if not args.script.exists():
|
|
318
|
+
print(f"[X] Script nao encontrado: {args.script}")
|
|
319
|
+
return 1
|
|
320
|
+
|
|
321
|
+
if args.dry_run:
|
|
322
|
+
print("[SEARCH] Modo dry-run: apenas parsing")
|
|
323
|
+
segments = parse_script(args.script)
|
|
324
|
+
print(f"\n{len(segments)} segmentos encontrados:\n")
|
|
325
|
+
|
|
326
|
+
# Agrupar por speaker
|
|
327
|
+
speaker_counts = {}
|
|
328
|
+
for s in segments:
|
|
329
|
+
speaker_counts[s.speaker] = speaker_counts.get(s.speaker, 0) + 1
|
|
330
|
+
|
|
331
|
+
print("Contagem por speaker:")
|
|
332
|
+
for speaker, count in sorted(speaker_counts.items()):
|
|
333
|
+
voice = VOICE_MAPPING.get(speaker, VOICE_MAPPING["DEFAULT"])
|
|
334
|
+
print(f" {speaker}: {count} falas -> {voice}")
|
|
335
|
+
|
|
336
|
+
print("\nPrimeiros 5 segmentos:")
|
|
337
|
+
for s in segments[:5]:
|
|
338
|
+
print(f" [{s.speaker}] {s.text[:60]}...")
|
|
339
|
+
return 0
|
|
340
|
+
|
|
341
|
+
try:
|
|
342
|
+
output_path = asyncio.run(generate_episode_audio(args.script, args.output))
|
|
343
|
+
print(f"\n[HEADPHONE] Para ouvir: {output_path}")
|
|
344
|
+
return 0
|
|
345
|
+
except Exception as e:
|
|
346
|
+
print(f"\n[X] Erro: {e}")
|
|
347
|
+
import traceback
|
|
348
|
+
traceback.print_exc()
|
|
349
|
+
return 1
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
if __name__ == "__main__":
|
|
353
|
+
exit(main())
|