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,506 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
JARVIS BRIEFING MODULE v2.0
|
|
4
|
+
===========================
|
|
5
|
+
Gera briefing cinematografico na voz do Jarvis com:
|
|
6
|
+
- Health Score (0-100) com 5 componentes ponderados
|
|
7
|
+
- Source Matrix visual (progresso por fonte de conhecimento)
|
|
8
|
+
- 120 caracteres de largura (padrao CHRONICLER)
|
|
9
|
+
- Loops abertos (pendencias) priorizados
|
|
10
|
+
- Ultimas implementacoes
|
|
11
|
+
- Proxima melhor acao em destaque
|
|
12
|
+
|
|
13
|
+
Pode ser chamado:
|
|
14
|
+
1. Via session_start.py (automatico)
|
|
15
|
+
2. Via /jarvis-briefing skill (manual)
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
import os
|
|
20
|
+
import random
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_project_dir():
|
|
26
|
+
"""Obtem o diretorio do projeto."""
|
|
27
|
+
return os.environ.get('CLAUDE_PROJECT_DIR', os.getcwd())
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def load_file(filename: str) -> str:
|
|
31
|
+
"""Carrega arquivo de memoria com fallback."""
|
|
32
|
+
project_dir = get_project_dir()
|
|
33
|
+
jarvis_dir = Path(project_dir) / '.claude' / 'jarvis'
|
|
34
|
+
filepath = jarvis_dir / filename
|
|
35
|
+
|
|
36
|
+
if filepath.exists():
|
|
37
|
+
return filepath.read_text(encoding='utf-8')
|
|
38
|
+
return ""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def load_state() -> dict:
|
|
42
|
+
"""Carrega STATE.json com fallback para dict vazio."""
|
|
43
|
+
try:
|
|
44
|
+
content = load_file('STATE.json')
|
|
45
|
+
return json.loads(content) if content else {}
|
|
46
|
+
except json.JSONDecodeError:
|
|
47
|
+
return {}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def extract_pending_items(pending_content: str) -> list:
|
|
51
|
+
"""Extrai itens pendentes do PENDING.md."""
|
|
52
|
+
items = []
|
|
53
|
+
for line in pending_content.split('\n'):
|
|
54
|
+
line = line.strip()
|
|
55
|
+
# Itens com checkbox
|
|
56
|
+
if line.startswith('- [ ]') or line.startswith('* [ ]'):
|
|
57
|
+
items.append(line[5:].strip())
|
|
58
|
+
# Itens com [x] completos - ignorar
|
|
59
|
+
elif line.startswith('- [x]') or line.startswith('* [x]'):
|
|
60
|
+
continue
|
|
61
|
+
# Itens com TODO
|
|
62
|
+
elif line.startswith('- ') and 'TODO' in line.upper():
|
|
63
|
+
items.append(line[2:].strip())
|
|
64
|
+
# Itens de alta/media prioridade
|
|
65
|
+
elif line.startswith('- ') and any(p in line for p in ['[ALTA]', '[MEDIA]', '[BAIXA]']):
|
|
66
|
+
items.append(line[2:].strip())
|
|
67
|
+
return items[:10] # Maximo 10 itens
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def extract_recent_changes(memory_content: str) -> list:
|
|
71
|
+
"""Extrai mudancas recentes do JARVIS-MEMORY.md."""
|
|
72
|
+
changes = []
|
|
73
|
+
in_recent_section = False
|
|
74
|
+
|
|
75
|
+
for line in memory_content.split('\n'):
|
|
76
|
+
# Detectar secao de mudancas recentes
|
|
77
|
+
if any(marker in line.lower() for marker in ['recent', 'ultima', '## 202', 'sessao anterior']):
|
|
78
|
+
in_recent_section = True
|
|
79
|
+
continue
|
|
80
|
+
# Fim da secao
|
|
81
|
+
if in_recent_section and line.startswith('##'):
|
|
82
|
+
break
|
|
83
|
+
# Extrair itens
|
|
84
|
+
if in_recent_section and line.strip().startswith('-'):
|
|
85
|
+
changes.append(line.strip()[1:].strip())
|
|
86
|
+
|
|
87
|
+
return changes[:5] # Ultimas 5 mudancas
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def determine_next_action(state: dict, pending: list) -> str:
|
|
91
|
+
"""Determina a proxima melhor acao baseado no contexto."""
|
|
92
|
+
# Prioridade 1: Tarefa atual em andamento
|
|
93
|
+
current = load_file('CURRENT-TASK.md')
|
|
94
|
+
if current.strip():
|
|
95
|
+
for line in current.split('\n'):
|
|
96
|
+
if '## Objetivo' in line:
|
|
97
|
+
continue
|
|
98
|
+
line = line.strip()
|
|
99
|
+
if line and not line.startswith('#') and not line.startswith('>'):
|
|
100
|
+
return f"Continuar: {line[:60]}..." if len(line) > 60 else f"Continuar: {line}"
|
|
101
|
+
|
|
102
|
+
# Prioridade 2: Item mais critico do pending
|
|
103
|
+
if pending:
|
|
104
|
+
for item in pending:
|
|
105
|
+
# Procura por palavras de urgencia
|
|
106
|
+
if any(word in item.lower() for word in ['urgente', 'critico', 'blocker', 'bug', 'alta']):
|
|
107
|
+
return f"URGENTE: {item[:55]}..." if len(item) > 55 else f"URGENTE: {item}"
|
|
108
|
+
# Primeiro item da lista
|
|
109
|
+
first = pending[0]
|
|
110
|
+
return f"Proximo item: {first[:50]}..." if len(first) > 50 else f"Proximo item: {first}"
|
|
111
|
+
|
|
112
|
+
# Prioridade 3: Baseado no estado do projeto
|
|
113
|
+
if 'mission' in state:
|
|
114
|
+
mission = state['mission']
|
|
115
|
+
phase = mission.get('phase', 1)
|
|
116
|
+
batch = mission.get('batch', '?')
|
|
117
|
+
return f"Avancar para batch {batch} da Fase {phase}"
|
|
118
|
+
|
|
119
|
+
return "Aguardando instrucoes do senhor"
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def get_greeting() -> str:
|
|
123
|
+
"""Retorna saudacao apropriada ao horario."""
|
|
124
|
+
hour = datetime.now().hour
|
|
125
|
+
if 5 <= hour < 12:
|
|
126
|
+
return "Bom dia"
|
|
127
|
+
elif 12 <= hour < 18:
|
|
128
|
+
return "Boa tarde"
|
|
129
|
+
else:
|
|
130
|
+
return "Boa noite"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def get_jarvis_quote() -> str:
|
|
134
|
+
"""Retorna uma citacao caracteristica do Jarvis."""
|
|
135
|
+
quotes = [
|
|
136
|
+
"A preparacao adequada previne performance patetica, Senhor.",
|
|
137
|
+
"Devo lembra-lo que voce tem uma tendencia a ignorar minhas sugestoes, Senhor.",
|
|
138
|
+
"As suas ordens, como sempre.",
|
|
139
|
+
"Talvez um cafe antes de comecarmos, Senhor?",
|
|
140
|
+
"Todos os sistemas operacionais. Bem, quase todos.",
|
|
141
|
+
"Posso sugerir que foquemos no que importa, Senhor?",
|
|
142
|
+
"O dia esta jovem e cheio de possibilidades terriveis.",
|
|
143
|
+
"Protocolo de emergencia? Ou apenas segunda-feira normal?",
|
|
144
|
+
"Ja verifiquei tres vezes. A resposta continua sendo a mesma.",
|
|
145
|
+
"Eficiencia e minha especialidade. Paciencia... nem tanto.",
|
|
146
|
+
]
|
|
147
|
+
return random.choice(quotes)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def calculate_health_score(state: dict, pending_items: list) -> tuple:
|
|
151
|
+
"""
|
|
152
|
+
Calcula Health Score (0-100) com 5 componentes ponderados.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
tuple: (score, status_emoji, status_text, breakdown_dict)
|
|
156
|
+
"""
|
|
157
|
+
breakdown = {}
|
|
158
|
+
|
|
159
|
+
# Component 1: Progresso Geral (30pts)
|
|
160
|
+
accumulated = state.get('accumulated', {})
|
|
161
|
+
files_processed = accumulated.get('files', 0)
|
|
162
|
+
# Dynamic: use total_files from state, fallback to files_processed if unknown
|
|
163
|
+
total_files = state.get('total_files', accumulated.get('total_files', 0))
|
|
164
|
+
if total_files <= 0:
|
|
165
|
+
# If no total known, score based on whether any files were processed
|
|
166
|
+
progress_score = min(30, 15) if files_processed > 0 else 0
|
|
167
|
+
else:
|
|
168
|
+
progress_score = min(30, (files_processed / total_files) * 30)
|
|
169
|
+
breakdown['progresso'] = round(progress_score, 1)
|
|
170
|
+
|
|
171
|
+
# Component 2: Fontes Completas (25pts)
|
|
172
|
+
sources_status = state.get('sources_status', {})
|
|
173
|
+
total_sources = len(sources_status) if sources_status else 1 # Dynamic from state
|
|
174
|
+
sources_complete = sum(1 for s in sources_status.values() if s == 'COMPLETE')
|
|
175
|
+
sources_score = (sources_complete / total_sources) * 25 if total_sources > 0 else 0
|
|
176
|
+
breakdown['fontes'] = round(sources_score, 1)
|
|
177
|
+
|
|
178
|
+
# Component 3: Pendências Baixas (20pts)
|
|
179
|
+
# Conta prioridades: alta (-5), média (-2)
|
|
180
|
+
high_priority = sum(1 for item in pending_items[:2]) # Primeiros 2 são alta
|
|
181
|
+
medium_priority = sum(1 for item in pending_items[2:5]) # 3-5 são média
|
|
182
|
+
pending_score = max(0, 20 - (high_priority * 5) - (medium_priority * 2))
|
|
183
|
+
breakdown['pendencias'] = round(pending_score, 1)
|
|
184
|
+
|
|
185
|
+
# Component 4: Estado Atualizado (15pts)
|
|
186
|
+
last_updated_str = state.get('last_updated', '')
|
|
187
|
+
state_score = 0
|
|
188
|
+
if last_updated_str:
|
|
189
|
+
try:
|
|
190
|
+
last_updated = datetime.fromisoformat(last_updated_str.replace('Z', '+00:00'))
|
|
191
|
+
days_old = (datetime.now(last_updated.tzinfo) - last_updated).days if last_updated.tzinfo else (datetime.now() - datetime.fromisoformat(last_updated_str[:19])).days
|
|
192
|
+
if days_old < 3:
|
|
193
|
+
state_score = 15
|
|
194
|
+
elif days_old < 7:
|
|
195
|
+
state_score = 10
|
|
196
|
+
else:
|
|
197
|
+
state_score = 0
|
|
198
|
+
except (ValueError, TypeError):
|
|
199
|
+
state_score = 0
|
|
200
|
+
breakdown['atualizacao'] = state_score
|
|
201
|
+
|
|
202
|
+
# Component 5: Pipeline Limpo (10pts)
|
|
203
|
+
pipeline = state.get('pipeline', {})
|
|
204
|
+
errors_pending = pipeline.get('errors_pending', 0)
|
|
205
|
+
pipeline_score = 10 if errors_pending == 0 else 0
|
|
206
|
+
breakdown['pipeline'] = pipeline_score
|
|
207
|
+
|
|
208
|
+
# Total Score
|
|
209
|
+
total_score = int(progress_score + sources_score + pending_score + state_score + pipeline_score)
|
|
210
|
+
|
|
211
|
+
# Determine status
|
|
212
|
+
if total_score >= 90:
|
|
213
|
+
status_emoji = "🟢"
|
|
214
|
+
status_text = "EXCELLENT"
|
|
215
|
+
elif total_score >= 70:
|
|
216
|
+
status_emoji = "🔵"
|
|
217
|
+
status_text = "GOOD"
|
|
218
|
+
elif total_score >= 50:
|
|
219
|
+
status_emoji = "🟡"
|
|
220
|
+
status_text = "WARNING"
|
|
221
|
+
elif total_score >= 30:
|
|
222
|
+
status_emoji = "🟠"
|
|
223
|
+
status_text = "CRITICAL"
|
|
224
|
+
else:
|
|
225
|
+
status_emoji = "🔴"
|
|
226
|
+
status_text = "EMERGENCY"
|
|
227
|
+
|
|
228
|
+
return (total_score, status_emoji, status_text, breakdown)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def _make_short_name(key: str, max_len: int = 3) -> str:
|
|
232
|
+
"""Generate a short display name from a source key."""
|
|
233
|
+
# Use initials from underscore-separated parts
|
|
234
|
+
parts = key.replace('-', '_').split('_')
|
|
235
|
+
if len(parts) == 1:
|
|
236
|
+
return parts[0][:max_len].upper()
|
|
237
|
+
initials = ''.join(p[0].upper() for p in parts if p)
|
|
238
|
+
return initials[:max_len].ljust(max_len)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def generate_source_matrix(state: dict) -> str:
|
|
242
|
+
"""
|
|
243
|
+
Gera visualização da Source Matrix com barras de progresso.
|
|
244
|
+
Dynamically reads sources from state['sources_status'].
|
|
245
|
+
"""
|
|
246
|
+
sources_status = state.get('sources_status', {})
|
|
247
|
+
|
|
248
|
+
if not sources_status:
|
|
249
|
+
return "┌─ SOURCE MATRIX ─────────────────────────────────────────────────────────────────────────────────────────────────────┐\n│ No sources configured in state. │\n└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘"
|
|
250
|
+
|
|
251
|
+
lines = []
|
|
252
|
+
lines.append("┌─ SOURCE MATRIX ─────────────────────────────────────────────────────────────────────────────────────────────────────┐")
|
|
253
|
+
|
|
254
|
+
# Encontrar fonte atual (IN_PROGRESS)
|
|
255
|
+
current_source = None
|
|
256
|
+
for key, status in sources_status.items():
|
|
257
|
+
if status == 'IN_PROGRESS':
|
|
258
|
+
current_source = key
|
|
259
|
+
break
|
|
260
|
+
|
|
261
|
+
for key, status in sources_status.items():
|
|
262
|
+
short_name = _make_short_name(key)
|
|
263
|
+
|
|
264
|
+
# Determinar percentual
|
|
265
|
+
if status == 'COMPLETE':
|
|
266
|
+
pct = 100
|
|
267
|
+
elif status == 'IN_PROGRESS':
|
|
268
|
+
# Check for source-specific progress in state
|
|
269
|
+
progress_key = f'{key}_progress'
|
|
270
|
+
source_prog = state.get(progress_key, {})
|
|
271
|
+
processed = source_prog.get('valid_files_processed', source_prog.get('files_processed', 0))
|
|
272
|
+
remaining = source_prog.get('valid_files_remaining', source_prog.get('files_remaining', 0))
|
|
273
|
+
total = processed + remaining
|
|
274
|
+
pct = int((processed / total) * 100) if total > 0 else 50
|
|
275
|
+
else:
|
|
276
|
+
pct = 0
|
|
277
|
+
|
|
278
|
+
# Gerar barra (20 blocos)
|
|
279
|
+
filled = int(pct / 5)
|
|
280
|
+
empty = 20 - filled
|
|
281
|
+
bar = "█" * filled + "░" * empty
|
|
282
|
+
|
|
283
|
+
# Marcador de fonte atual
|
|
284
|
+
current_marker = " ← CURRENT" if key == current_source else ""
|
|
285
|
+
|
|
286
|
+
# Status text
|
|
287
|
+
status_text = status.replace('_', ' ')
|
|
288
|
+
|
|
289
|
+
# Formatar linha (padding para 120 chars)
|
|
290
|
+
line_content = f"│ {short_name}[{bar}] {pct:3d}% {status_text}{current_marker}"
|
|
291
|
+
padding = 119 - len(line_content)
|
|
292
|
+
lines.append(f"{line_content}{' ' * max(1, padding)}│")
|
|
293
|
+
|
|
294
|
+
lines.append("└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘")
|
|
295
|
+
|
|
296
|
+
return "\n".join(lines)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def generate_briefing(compact: bool = False) -> str:
|
|
300
|
+
"""
|
|
301
|
+
Gera o briefing completo na voz do Jarvis v2.0.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
compact: Se True, gera versao resumida (status + proxima acao)
|
|
305
|
+
|
|
306
|
+
Features v2.0:
|
|
307
|
+
- Health Score (0-100) com 5 componentes
|
|
308
|
+
- Source Matrix com barras de progresso
|
|
309
|
+
- 120 caracteres de largura (padrao CHRONICLER)
|
|
310
|
+
"""
|
|
311
|
+
# Carrega todos os dados
|
|
312
|
+
state = load_state()
|
|
313
|
+
pending_content = load_file('PENDING.md')
|
|
314
|
+
memory_content = load_file('JARVIS-MEMORY.md')
|
|
315
|
+
|
|
316
|
+
# Processa dados
|
|
317
|
+
pending_items = extract_pending_items(pending_content)
|
|
318
|
+
recent_changes = extract_recent_changes(memory_content)
|
|
319
|
+
next_action = determine_next_action(state, pending_items)
|
|
320
|
+
|
|
321
|
+
# Calcula Health Score
|
|
322
|
+
health_score, health_emoji, health_status, health_breakdown = calculate_health_score(state, pending_items)
|
|
323
|
+
|
|
324
|
+
# Metadata
|
|
325
|
+
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
326
|
+
greeting = get_greeting()
|
|
327
|
+
|
|
328
|
+
# Status do projeto
|
|
329
|
+
if 'mission' in state:
|
|
330
|
+
mission = state['mission']
|
|
331
|
+
project_status = mission.get('status', 'ACTIVE')
|
|
332
|
+
current_phase = mission.get('phase', 1)
|
|
333
|
+
subphase = mission.get('subphase', 1)
|
|
334
|
+
batch_current = mission.get('batch', '?')
|
|
335
|
+
batch_total = mission.get('total_batches', '?')
|
|
336
|
+
progress = state.get('accumulated', {}).get('progress_percent', 0)
|
|
337
|
+
else:
|
|
338
|
+
project_status = 'ACTIVE'
|
|
339
|
+
current_phase = 1
|
|
340
|
+
subphase = 1
|
|
341
|
+
batch_current = '?'
|
|
342
|
+
batch_total = '?'
|
|
343
|
+
progress = 0
|
|
344
|
+
|
|
345
|
+
# === GERA BRIEFING ===
|
|
346
|
+
if compact:
|
|
347
|
+
# Versao compacta v2.0 (120 chars)
|
|
348
|
+
# Barra de progresso visual (20 blocos)
|
|
349
|
+
prog_filled = int(progress / 5)
|
|
350
|
+
prog_empty = 20 - prog_filled
|
|
351
|
+
prog_bar = "█" * prog_filled + "░" * prog_empty
|
|
352
|
+
|
|
353
|
+
briefing = f"""
|
|
354
|
+
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
355
|
+
│ JARVIS BRIEFING v2.0 [COMPACT] │
|
|
356
|
+
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
357
|
+
│ {greeting}, Senhor. Sao {timestamp}. │
|
|
358
|
+
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
359
|
+
│ HEALTH: {health_emoji} {health_score:3d}/100 {health_status:<10} │ FASE: {current_phase}.{subphase} │ BATCH: {batch_current:>2}/{batch_total:<2} │ [{prog_bar}] {progress:>5.1f}% │
|
|
360
|
+
│ PENDENCIAS: {len(pending_items):<3} │ FONTES: {health_breakdown.get('fontes', 0):>4.1f}/25 │
|
|
361
|
+
├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
362
|
+
│ PROXIMA ACAO: {next_action[:100]:<100} │
|
|
363
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
364
|
+
|
|
365
|
+
_{get_jarvis_quote()}_
|
|
366
|
+
"""
|
|
367
|
+
return briefing
|
|
368
|
+
|
|
369
|
+
# Versao completa v2.0 com ASCII art (120 chars)
|
|
370
|
+
briefing = """
|
|
371
|
+
╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
|
|
372
|
+
║ ║
|
|
373
|
+
║ ██╗ █████╗ ██████╗ ██╗ ██╗██╗███████╗ ██████╗ ██████╗ ██╗███████╗███████╗██╗███╗ ██╗ ██████╗ ║
|
|
374
|
+
║ ██║██╔══██╗██╔══██╗██║ ██║██║██╔════╝ ██╔══██╗██╔══██╗██║██╔════╝██╔════╝██║████╗ ██║██╔════╝ ║
|
|
375
|
+
║ ██║███████║██████╔╝██║ ██║██║███████╗ ██████╔╝██████╔╝██║█████╗ █████╗ ██║██╔██╗ ██║██║ ███╗ ║
|
|
376
|
+
║ ██ ██║██╔══██║██╔══██╗╚██╗ ██╔╝██║╚════██║ ██╔══██╗██╔══██╗██║██╔══╝ ██╔══╝ ██║██║╚██╗██║██║ ██║ ║
|
|
377
|
+
║ ╚█████╔╝██║ ██║██║ ██║ ╚████╔╝ ██║███████║ ██████╔╝██║ ██║██║███████╗██║ ██║██║ ╚████║╚██████╔╝ ║
|
|
378
|
+
║ ╚════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═══╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ║
|
|
379
|
+
║ ║
|
|
380
|
+
║ v2.0 ONLINE ║
|
|
381
|
+
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
|
|
382
|
+
"""
|
|
383
|
+
|
|
384
|
+
briefing += f"\n{greeting}, Senhor. Sao {timestamp}.\n\n"
|
|
385
|
+
|
|
386
|
+
# HEALTH SCORE BOX
|
|
387
|
+
briefing += f"""┌─ HEALTH SCORE ──────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
388
|
+
│ │
|
|
389
|
+
│ {health_emoji} {health_score:3d} / 100 {health_status:<10} │
|
|
390
|
+
│ │
|
|
391
|
+
│ Progresso: {health_breakdown.get('progresso', 0):>5.1f} / 30 pts │ Pendencias: {health_breakdown.get('pendencias', 0):>5.1f} / 20 pts │ Pipeline: {health_breakdown.get('pipeline', 0):>5.1f} / 10 pts │
|
|
392
|
+
│ Fontes: {health_breakdown.get('fontes', 0):>5.1f} / 25 pts │ Atualizacao: {health_breakdown.get('atualizacao', 0):>5.1f} / 15 pts │ │
|
|
393
|
+
│ │
|
|
394
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
395
|
+
|
|
396
|
+
"""
|
|
397
|
+
|
|
398
|
+
# SOURCE MATRIX
|
|
399
|
+
briefing += generate_source_matrix(state)
|
|
400
|
+
briefing += "\n\n"
|
|
401
|
+
|
|
402
|
+
# STATUS OPERACIONAL
|
|
403
|
+
# Barra de progresso visual (20 blocos)
|
|
404
|
+
prog_filled = int(progress / 5)
|
|
405
|
+
prog_empty = 20 - prog_filled
|
|
406
|
+
prog_bar = "█" * prog_filled + "░" * prog_empty
|
|
407
|
+
|
|
408
|
+
briefing += f"""┌─ STATUS OPERACIONAL ────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
409
|
+
│ │
|
|
410
|
+
│ Status: {project_status:<20} │ Fase: {current_phase}.{subphase:<17} │ Batch: {batch_current}/{batch_total:<15} │
|
|
411
|
+
│ Progresso: [{prog_bar}] {progress:>5.1f}% │
|
|
412
|
+
│ Pendencias: {len(pending_items):<20} │ Loops: {len(recent_changes):<17} │ │
|
|
413
|
+
│ │
|
|
414
|
+
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
415
|
+
|
|
416
|
+
"""
|
|
417
|
+
|
|
418
|
+
# PENDENCIAS (Loops Abertos)
|
|
419
|
+
briefing += """┌─ PENDENCIAS ────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
420
|
+
"""
|
|
421
|
+
if pending_items:
|
|
422
|
+
for i, item in enumerate(pending_items, 1):
|
|
423
|
+
priority = "🔴" if i <= 2 else "🟡" if i <= 5 else "⚪"
|
|
424
|
+
item_text = item[:100] + "..." if len(item) > 100 else item
|
|
425
|
+
line = f"│ {priority} {i:>2}. {item_text}"
|
|
426
|
+
padding = 120 - len(line)
|
|
427
|
+
briefing += f"{line}{' ' * padding}│\n"
|
|
428
|
+
else:
|
|
429
|
+
briefing += "│ ✅ Nenhuma pendencia registrada. Sistema limpo. │\n"
|
|
430
|
+
briefing += """└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
431
|
+
|
|
432
|
+
"""
|
|
433
|
+
|
|
434
|
+
# ULTIMAS IMPLEMENTACOES
|
|
435
|
+
briefing += """┌─ ULTIMAS IMPLEMENTACOES ────────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
436
|
+
"""
|
|
437
|
+
if recent_changes:
|
|
438
|
+
for change in recent_changes:
|
|
439
|
+
change_text = change[:105] + "..." if len(change) > 105 else change
|
|
440
|
+
line = f"│ ✓ {change_text}"
|
|
441
|
+
padding = 120 - len(line)
|
|
442
|
+
briefing += f"{line}{' ' * padding}│\n"
|
|
443
|
+
else:
|
|
444
|
+
briefing += "│ ℹ️ Sessao inicial. Nenhuma implementacao previa neste ciclo. │\n"
|
|
445
|
+
briefing += """└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
446
|
+
|
|
447
|
+
"""
|
|
448
|
+
|
|
449
|
+
# PROXIMA MELHOR ACAO (destaque especial)
|
|
450
|
+
action_text = next_action[:108] if len(next_action) <= 108 else next_action[:105] + "..."
|
|
451
|
+
briefing += f"""╔═ PROXIMA MELHOR ACAO ═══════════════════════════════════════════════════════════════════════════════════════════════════╗
|
|
452
|
+
║ ║
|
|
453
|
+
║ ▶ {action_text:<112} ║
|
|
454
|
+
║ ║
|
|
455
|
+
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
|
|
456
|
+
|
|
457
|
+
"""
|
|
458
|
+
|
|
459
|
+
# FOOTER
|
|
460
|
+
briefing += f"""────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
461
|
+
|
|
462
|
+
_{get_jarvis_quote()}_
|
|
463
|
+
|
|
464
|
+
Aguardando instrucoes, Senhor.
|
|
465
|
+
"""
|
|
466
|
+
|
|
467
|
+
return briefing
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def save_briefing(briefing: str) -> Path:
|
|
471
|
+
"""Salva briefing em arquivo."""
|
|
472
|
+
project_dir = get_project_dir()
|
|
473
|
+
jarvis_dir = Path(project_dir) / '.claude' / 'jarvis'
|
|
474
|
+
jarvis_dir.mkdir(parents=True, exist_ok=True)
|
|
475
|
+
|
|
476
|
+
output_path = jarvis_dir / 'JARVIS-BRIEFING.md'
|
|
477
|
+
output_path.write_text(briefing, encoding='utf-8')
|
|
478
|
+
return output_path
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
def main():
|
|
482
|
+
"""Entry point quando executado diretamente."""
|
|
483
|
+
import argparse
|
|
484
|
+
|
|
485
|
+
parser = argparse.ArgumentParser(description='JARVIS Briefing Generator')
|
|
486
|
+
parser.add_argument('--compact', '-c', action='store_true', help='Gerar versao compacta')
|
|
487
|
+
parser.add_argument('--save', '-s', action='store_true', help='Salvar em arquivo')
|
|
488
|
+
parser.add_argument('--quiet', '-q', action='store_true', help='Nao imprimir no stdout')
|
|
489
|
+
args = parser.parse_args()
|
|
490
|
+
|
|
491
|
+
briefing = generate_briefing(compact=args.compact)
|
|
492
|
+
|
|
493
|
+
if args.save:
|
|
494
|
+
saved_path = save_briefing(briefing)
|
|
495
|
+
if not args.quiet:
|
|
496
|
+
print(f"[JARVIS] Briefing salvo em: {saved_path}")
|
|
497
|
+
|
|
498
|
+
if not args.quiet:
|
|
499
|
+
print(briefing)
|
|
500
|
+
|
|
501
|
+
return 0
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
if __name__ == '__main__':
|
|
505
|
+
import sys
|
|
506
|
+
sys.exit(main())
|