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,202 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
JARVIS Memory Updater Hook
|
|
4
|
+
Atualiza JARVIS-MEMORY.md automaticamente.
|
|
5
|
+
|
|
6
|
+
Triggers:
|
|
7
|
+
- Decisoes importantes detectadas
|
|
8
|
+
- Preferencias demonstradas
|
|
9
|
+
- Final de sessao
|
|
10
|
+
- Padroes de comportamento observados
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import sys
|
|
15
|
+
import os
|
|
16
|
+
import re
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
|
|
20
|
+
def get_project_dir():
|
|
21
|
+
"""Obtem o diretorio do projeto."""
|
|
22
|
+
return os.environ.get('CLAUDE_PROJECT_DIR', os.getcwd())
|
|
23
|
+
|
|
24
|
+
def load_memory():
|
|
25
|
+
"""Carrega JARVIS-MEMORY.md atual."""
|
|
26
|
+
project_dir = get_project_dir()
|
|
27
|
+
memory_path = Path(project_dir) / '.claude' / 'jarvis' / 'JARVIS-MEMORY.md'
|
|
28
|
+
|
|
29
|
+
if memory_path.exists():
|
|
30
|
+
with open(memory_path, 'r', encoding='utf-8') as f:
|
|
31
|
+
return f.read()
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
def detect_decision(message):
|
|
35
|
+
"""Detecta se a mensagem contem uma decisao importante."""
|
|
36
|
+
decision_patterns = [
|
|
37
|
+
r'decid[io]',
|
|
38
|
+
r'escolh[eo]',
|
|
39
|
+
r'prefer[eo]',
|
|
40
|
+
r'vamos (usar|fazer|implementar)',
|
|
41
|
+
r'aprovo',
|
|
42
|
+
r'confirmo',
|
|
43
|
+
r'sim,?\s*(pode|faz|continua)',
|
|
44
|
+
r'nao,?\s*(nao pode|nao faz)',
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
message_lower = message.lower()
|
|
48
|
+
for pattern in decision_patterns:
|
|
49
|
+
if re.search(pattern, message_lower):
|
|
50
|
+
return True
|
|
51
|
+
return False
|
|
52
|
+
|
|
53
|
+
def detect_preference(message):
|
|
54
|
+
"""Detecta se a mensagem demonstra uma preferencia."""
|
|
55
|
+
preference_patterns = [
|
|
56
|
+
r'gosto (de|quando)',
|
|
57
|
+
r'prefiro',
|
|
58
|
+
r'sempre (quero|faz)',
|
|
59
|
+
r'nunca (quero|faz)',
|
|
60
|
+
r'melhor (assim|dessa forma)',
|
|
61
|
+
r'perfeito',
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
message_lower = message.lower()
|
|
65
|
+
for pattern in preference_patterns:
|
|
66
|
+
if re.search(pattern, message_lower):
|
|
67
|
+
return True
|
|
68
|
+
return False
|
|
69
|
+
|
|
70
|
+
def extract_decision_summary(message):
|
|
71
|
+
"""Extrai um resumo da decisao."""
|
|
72
|
+
# Limitar a 100 caracteres
|
|
73
|
+
summary = message[:100]
|
|
74
|
+
if len(message) > 100:
|
|
75
|
+
summary += "..."
|
|
76
|
+
return summary
|
|
77
|
+
|
|
78
|
+
def update_memory_file(section, content):
|
|
79
|
+
"""Atualiza uma secao especifica do JARVIS-MEMORY.md."""
|
|
80
|
+
project_dir = get_project_dir()
|
|
81
|
+
memory_path = Path(project_dir) / '.claude' / 'jarvis' / 'JARVIS-MEMORY.md'
|
|
82
|
+
|
|
83
|
+
if not memory_path.exists():
|
|
84
|
+
return False
|
|
85
|
+
|
|
86
|
+
with open(memory_path, 'r', encoding='utf-8') as f:
|
|
87
|
+
memory = f.read()
|
|
88
|
+
|
|
89
|
+
# Encontrar secao de decisoes e adicionar
|
|
90
|
+
if section == 'decisions':
|
|
91
|
+
# Procurar por "### Decisoes Importantes"
|
|
92
|
+
if '### Decisoes Importantes' in memory:
|
|
93
|
+
# Adicionar nova decisao
|
|
94
|
+
date_str = datetime.now().strftime('%Y-%m-%d')
|
|
95
|
+
new_entry = f"\n{date_str}:\n├─ {content}\n"
|
|
96
|
+
|
|
97
|
+
# Inserir apos o header da secao
|
|
98
|
+
parts = memory.split('### Decisoes Importantes')
|
|
99
|
+
if len(parts) == 2:
|
|
100
|
+
# Encontrar o bloco de codigo
|
|
101
|
+
if '```' in parts[1]:
|
|
102
|
+
code_start = parts[1].find('```')
|
|
103
|
+
code_end = parts[1].find('```', code_start + 3)
|
|
104
|
+
if code_end > code_start:
|
|
105
|
+
# Inserir antes do fechamento do bloco
|
|
106
|
+
before = parts[1][:code_end]
|
|
107
|
+
after = parts[1][code_end:]
|
|
108
|
+
parts[1] = before + new_entry + after
|
|
109
|
+
memory = '### Decisoes Importantes'.join(parts)
|
|
110
|
+
|
|
111
|
+
# Atualizar timestamp
|
|
112
|
+
memory = re.sub(
|
|
113
|
+
r'\*Ultima atualizacao: \d{4}-\d{2}-\d{2}\*',
|
|
114
|
+
f'*Ultima atualizacao: {datetime.now().strftime("%Y-%m-%d")}*',
|
|
115
|
+
memory
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Incrementar contador de interacoes
|
|
119
|
+
match = re.search(r'\*Interacoes registradas: (\d+)\*', memory)
|
|
120
|
+
if match:
|
|
121
|
+
count = int(match.group(1)) + 1
|
|
122
|
+
memory = re.sub(
|
|
123
|
+
r'\*Interacoes registradas: \d+\*',
|
|
124
|
+
f'*Interacoes registradas: {count}*',
|
|
125
|
+
memory
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
with open(memory_path, 'w', encoding='utf-8') as f:
|
|
129
|
+
f.write(memory)
|
|
130
|
+
|
|
131
|
+
return True
|
|
132
|
+
|
|
133
|
+
def log_update(update_type, content):
|
|
134
|
+
"""Loga a atualizacao de memoria."""
|
|
135
|
+
project_dir = get_project_dir()
|
|
136
|
+
log_path = Path(project_dir) / 'logs' / 'memory_updates.jsonl'
|
|
137
|
+
log_path.parent.mkdir(parents=True, exist_ok=True)
|
|
138
|
+
|
|
139
|
+
log_entry = {
|
|
140
|
+
'timestamp': datetime.now().isoformat(),
|
|
141
|
+
'type': update_type,
|
|
142
|
+
'content': content[:200]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
with open(log_path, 'a', encoding='utf-8') as f:
|
|
146
|
+
f.write(json.dumps(log_entry, ensure_ascii=False) + '\n')
|
|
147
|
+
|
|
148
|
+
def main():
|
|
149
|
+
"""Funcao principal do hook."""
|
|
150
|
+
try:
|
|
151
|
+
# Ler input do hook
|
|
152
|
+
input_data = sys.stdin.read()
|
|
153
|
+
if not input_data:
|
|
154
|
+
print(json.dumps({'continue': True}))
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
hook_input = json.loads(input_data)
|
|
158
|
+
|
|
159
|
+
# Extrair mensagem do usuario (se disponivel)
|
|
160
|
+
message = hook_input.get('message', '')
|
|
161
|
+
if not message:
|
|
162
|
+
# Tentar extrair de outros campos
|
|
163
|
+
message = hook_input.get('content', '')
|
|
164
|
+
if not message:
|
|
165
|
+
message = hook_input.get('text', '')
|
|
166
|
+
|
|
167
|
+
if not message:
|
|
168
|
+
print(json.dumps({'continue': True}))
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
updated = False
|
|
172
|
+
|
|
173
|
+
# Detectar decisoes
|
|
174
|
+
if detect_decision(message):
|
|
175
|
+
summary = extract_decision_summary(message)
|
|
176
|
+
if update_memory_file('decisions', summary):
|
|
177
|
+
log_update('decision', summary)
|
|
178
|
+
updated = True
|
|
179
|
+
|
|
180
|
+
# Detectar preferencias
|
|
181
|
+
if detect_preference(message):
|
|
182
|
+
summary = extract_decision_summary(message)
|
|
183
|
+
log_update('preference', summary)
|
|
184
|
+
updated = True
|
|
185
|
+
|
|
186
|
+
# Output
|
|
187
|
+
output = {
|
|
188
|
+
'continue': True,
|
|
189
|
+
'memory_updated': updated
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
print(json.dumps(output))
|
|
193
|
+
|
|
194
|
+
except Exception as e:
|
|
195
|
+
# Nao bloquear em caso de erro
|
|
196
|
+
print(json.dumps({
|
|
197
|
+
'continue': True,
|
|
198
|
+
'error': str(e)
|
|
199
|
+
}))
|
|
200
|
+
|
|
201
|
+
if __name__ == '__main__':
|
|
202
|
+
main()
|
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
4
|
+
║ JARVIS MULTI-AGENT HOOK ║
|
|
5
|
+
║ ║
|
|
6
|
+
║ Hook para Claude Code que detecta automaticamente quando usar agentes. ║
|
|
7
|
+
║ Integra com user_prompt_submit para análise em tempo real. ║
|
|
8
|
+
╚═══════════════════════════════════════════════════════════════════════════════╝
|
|
9
|
+
|
|
10
|
+
FUNCIONAMENTO:
|
|
11
|
+
1. Intercepta cada prompt do usuário
|
|
12
|
+
2. Analisa complexidade e necessidade de agentes
|
|
13
|
+
3. Se necessário, injeta instruções de orquestração
|
|
14
|
+
4. Mantém log de decisões para aprendizado
|
|
15
|
+
|
|
16
|
+
TRIGGERS AUTOMÁTICOS:
|
|
17
|
+
- Tarefas com múltiplos aspectos
|
|
18
|
+
- Pedidos de análise profunda
|
|
19
|
+
- Comparações e avaliações
|
|
20
|
+
- Debates e war rooms explícitos
|
|
21
|
+
- Keywords de domínio específico
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import json
|
|
25
|
+
import sys
|
|
26
|
+
import os
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from datetime import datetime
|
|
29
|
+
from typing import Dict, Any, Optional, Tuple
|
|
30
|
+
|
|
31
|
+
# Adicionar path dos scripts
|
|
32
|
+
# .claude/hooks/ -> .claude/ -> raiz do projeto
|
|
33
|
+
PROJECT_ROOT = Path(os.environ.get('CLAUDE_PROJECT_DIR', str(Path(__file__).parent.parent.parent)))
|
|
34
|
+
SCRIPTS_PATH = PROJECT_ROOT / "scripts"
|
|
35
|
+
sys.path.insert(0, str(SCRIPTS_PATH))
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
from jarvis_orchestrator import JarvisOrchestrator, TaskComplexity, ExecutionStrategy
|
|
39
|
+
except ImportError:
|
|
40
|
+
# Fallback se módulo não disponível
|
|
41
|
+
JarvisOrchestrator = None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# ============================================================================
|
|
45
|
+
# CONFIGURAÇÃO
|
|
46
|
+
# ============================================================================
|
|
47
|
+
|
|
48
|
+
SYSTEM_PATH = PROJECT_ROOT / "system"
|
|
49
|
+
LOGS_PATH = PROJECT_ROOT / "logs"
|
|
50
|
+
CONFIG_FILE = SYSTEM_PATH / "multi_agent_config.json"
|
|
51
|
+
|
|
52
|
+
DEFAULT_CONFIG = {
|
|
53
|
+
"enabled": True,
|
|
54
|
+
"min_complexity_for_notification": 2, # SIMPLE ou acima
|
|
55
|
+
"auto_inject_orchestration": True,
|
|
56
|
+
"log_all_analyses": True,
|
|
57
|
+
"war_room_keywords": [
|
|
58
|
+
"war room", "debate", "confrontar", "perspectivas diferentes",
|
|
59
|
+
"prós e contras", "avaliar opções", "conselho", "board"
|
|
60
|
+
],
|
|
61
|
+
"force_agents_keywords": [
|
|
62
|
+
"use os agentes", "consulte especialistas", "análise profunda",
|
|
63
|
+
"múltiplas perspectivas", "investigação completa"
|
|
64
|
+
],
|
|
65
|
+
"skip_analysis_patterns": [
|
|
66
|
+
r'^(oi|olá|bom dia|boa tarde|boa noite|hey|hi)[\s!.]*$',
|
|
67
|
+
r'^(obrigado|valeu|thanks|ok|entendi|certo)[\s!.]*$',
|
|
68
|
+
r'^(sim|não|yes|no)[\s!.]*$',
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# ============================================================================
|
|
74
|
+
# HOOK PRINCIPAL
|
|
75
|
+
# ============================================================================
|
|
76
|
+
|
|
77
|
+
def load_config() -> Dict:
|
|
78
|
+
"""Carrega configuração do hook."""
|
|
79
|
+
if CONFIG_FILE.exists():
|
|
80
|
+
try:
|
|
81
|
+
with open(CONFIG_FILE, 'r') as f:
|
|
82
|
+
user_config = json.load(f)
|
|
83
|
+
config = DEFAULT_CONFIG.copy()
|
|
84
|
+
config.update(user_config)
|
|
85
|
+
return config
|
|
86
|
+
except Exception:
|
|
87
|
+
pass
|
|
88
|
+
return DEFAULT_CONFIG
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def should_skip_analysis(prompt: str, config: Dict) -> bool:
|
|
92
|
+
"""Verifica se deve pular análise para este prompt."""
|
|
93
|
+
import re
|
|
94
|
+
|
|
95
|
+
prompt_lower = prompt.lower().strip()
|
|
96
|
+
|
|
97
|
+
for pattern in config.get("skip_analysis_patterns", []):
|
|
98
|
+
if re.match(pattern, prompt_lower, re.IGNORECASE):
|
|
99
|
+
return True
|
|
100
|
+
|
|
101
|
+
# Muito curto
|
|
102
|
+
if len(prompt) < 10:
|
|
103
|
+
return True
|
|
104
|
+
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def detect_war_room_request(prompt: str, config: Dict) -> bool:
|
|
109
|
+
"""Detecta se usuário quer War Room explicitamente."""
|
|
110
|
+
prompt_lower = prompt.lower()
|
|
111
|
+
|
|
112
|
+
for keyword in config.get("war_room_keywords", []):
|
|
113
|
+
if keyword in prompt_lower:
|
|
114
|
+
return True
|
|
115
|
+
|
|
116
|
+
return False
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def detect_force_agents(prompt: str, config: Dict) -> bool:
|
|
120
|
+
"""Detecta se usuário quer forçar uso de agentes."""
|
|
121
|
+
prompt_lower = prompt.lower()
|
|
122
|
+
|
|
123
|
+
for keyword in config.get("force_agents_keywords", []):
|
|
124
|
+
if keyword in prompt_lower:
|
|
125
|
+
return True
|
|
126
|
+
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def analyze_prompt(prompt: str) -> Dict[str, Any]:
|
|
131
|
+
"""
|
|
132
|
+
Analisa o prompt e retorna recomendação de orquestração.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Dict com análise e recomendações
|
|
136
|
+
"""
|
|
137
|
+
if JarvisOrchestrator is None:
|
|
138
|
+
return {
|
|
139
|
+
"available": False,
|
|
140
|
+
"reason": "Orchestrator não disponível"
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
try:
|
|
144
|
+
orchestrator = JarvisOrchestrator()
|
|
145
|
+
analysis = orchestrator.analyze_task(prompt)
|
|
146
|
+
plan = orchestrator.create_orchestration_plan(analysis)
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
"available": True,
|
|
150
|
+
"complexity": analysis.complexity.name,
|
|
151
|
+
"complexity_value": analysis.complexity.value,
|
|
152
|
+
"requires_agents": analysis.requires_agents,
|
|
153
|
+
"recommended_agents": [a.value for a in analysis.recommended_agents],
|
|
154
|
+
"strategy": analysis.strategy.value,
|
|
155
|
+
"reasoning": analysis.reasoning,
|
|
156
|
+
"confidence": analysis.confidence,
|
|
157
|
+
"domain": analysis.domain,
|
|
158
|
+
"keywords": analysis.keywords[:10],
|
|
159
|
+
"plan_summary": {
|
|
160
|
+
"task_id": plan.task_id,
|
|
161
|
+
"agents_count": len(plan.agents_to_activate),
|
|
162
|
+
"synthesis_strategy": plan.synthesis_strategy
|
|
163
|
+
},
|
|
164
|
+
"orchestration_prompt": orchestrator.get_orchestration_prompt(plan)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
except Exception as e:
|
|
168
|
+
return {
|
|
169
|
+
"available": False,
|
|
170
|
+
"reason": str(e)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def generate_agent_context(analysis: Dict, config: Dict) -> str:
|
|
175
|
+
"""
|
|
176
|
+
Gera contexto de agentes para injetar no prompt.
|
|
177
|
+
|
|
178
|
+
Este contexto instrui o JARVIS sobre como proceder com agentes.
|
|
179
|
+
"""
|
|
180
|
+
if not analysis.get("available") or not analysis.get("requires_agents"):
|
|
181
|
+
return ""
|
|
182
|
+
|
|
183
|
+
agents_list = ", ".join(analysis.get("recommended_agents", []))
|
|
184
|
+
strategy = analysis.get("strategy", "direct")
|
|
185
|
+
reasoning = analysis.get("reasoning", "")
|
|
186
|
+
|
|
187
|
+
context = f"""
|
|
188
|
+
╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
189
|
+
║ 🤖 JARVIS MULTI-AGENT ANALYSIS
|
|
190
|
+
╚═══════════════════════════════════════════════════════════════════════════════╝
|
|
191
|
+
|
|
192
|
+
ANÁLISE AUTOMÁTICA DA TAREFA:
|
|
193
|
+
• Complexidade: {analysis.get('complexity', 'N/A')}
|
|
194
|
+
• Domínio: {analysis.get('domain', 'Geral')}
|
|
195
|
+
• Confiança: {analysis.get('confidence', 0):.0%}
|
|
196
|
+
|
|
197
|
+
ESTRATÉGIA RECOMENDADA: {strategy.upper()}
|
|
198
|
+
|
|
199
|
+
AGENTES RECOMENDADOS: {agents_list or 'Nenhum'}
|
|
200
|
+
|
|
201
|
+
RACIOCÍNIO: {reasoning}
|
|
202
|
+
|
|
203
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
204
|
+
|
|
205
|
+
INSTRUÇÕES PARA JARVIS:
|
|
206
|
+
|
|
207
|
+
1. ATIVE OS AGENTES RECOMENDADOS mentalmente
|
|
208
|
+
2. Para cada agente, PROCESSE A TAREFA sob sua perspectiva
|
|
209
|
+
3. SINTETIZE os resultados em uma resposta coesa
|
|
210
|
+
4. APRESENTE a resposta final consolidada ao senhor
|
|
211
|
+
|
|
212
|
+
FORMATO DE RESPOSTA:
|
|
213
|
+
|
|
214
|
+
"Senhor, [contexto da análise].
|
|
215
|
+
|
|
216
|
+
[Se múltiplos agentes]: Consultei [agentes] para esta tarefa.
|
|
217
|
+
|
|
218
|
+
[Resposta principal consolidada]
|
|
219
|
+
|
|
220
|
+
[Se relevante]: Pontos adicionais dos especialistas: [insights]"
|
|
221
|
+
|
|
222
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
223
|
+
"""
|
|
224
|
+
|
|
225
|
+
return context
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
def generate_war_room_context(prompt: str) -> str:
|
|
229
|
+
"""Gera contexto específico para War Room."""
|
|
230
|
+
return f"""
|
|
231
|
+
╔═══════════════════════════════════════════════════════════════════════════════╗
|
|
232
|
+
║ 🎭 JARVIS WAR ROOM ACTIVATED
|
|
233
|
+
╚═══════════════════════════════════════════════════════════════════════════════╝
|
|
234
|
+
|
|
235
|
+
O senhor solicitou um debate estruturado.
|
|
236
|
+
|
|
237
|
+
TÓPICO: {prompt}
|
|
238
|
+
|
|
239
|
+
PARTICIPANTES A ATIVAR:
|
|
240
|
+
• ANALYST - Visão analítica e dados
|
|
241
|
+
• CRITIC - Identificar falhas e riscos
|
|
242
|
+
• DEVILS_ADVOCATE - Argumentos contrários
|
|
243
|
+
• SYNTHESIZER - Integrar perspectivas
|
|
244
|
+
|
|
245
|
+
ESTRUTURA DO DEBATE:
|
|
246
|
+
|
|
247
|
+
1. OPENING STATEMENTS
|
|
248
|
+
Cada participante apresenta posição inicial (2-3 parágrafos)
|
|
249
|
+
|
|
250
|
+
2. DEBATE ROUNDS (2 rodadas)
|
|
251
|
+
Participantes respondem uns aos outros
|
|
252
|
+
|
|
253
|
+
3. SÍNTESE FINAL
|
|
254
|
+
Consolidação de consensos, divergências e recomendação
|
|
255
|
+
|
|
256
|
+
FORMATO DE OUTPUT:
|
|
257
|
+
|
|
258
|
+
## Síntese Executiva
|
|
259
|
+
[Resumo em 2-3 frases]
|
|
260
|
+
|
|
261
|
+
## Consensos
|
|
262
|
+
[Pontos de concordância]
|
|
263
|
+
|
|
264
|
+
## Divergências
|
|
265
|
+
[Onde houve discordância]
|
|
266
|
+
|
|
267
|
+
## Recomendação Final
|
|
268
|
+
[Ação recomendada considerando todas as perspectivas]
|
|
269
|
+
|
|
270
|
+
═══════════════════════════════════════════════════════════════════════════════
|
|
271
|
+
"""
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def log_analysis(prompt: str, analysis: Dict, decision: str):
|
|
275
|
+
"""Registra análise para aprendizado."""
|
|
276
|
+
log_file = LOGS_PATH / "agent_hook_analyses.jsonl"
|
|
277
|
+
LOGS_PATH.mkdir(parents=True, exist_ok=True)
|
|
278
|
+
|
|
279
|
+
entry = {
|
|
280
|
+
"timestamp": datetime.now().isoformat(),
|
|
281
|
+
"prompt_preview": prompt[:100] + "..." if len(prompt) > 100 else prompt,
|
|
282
|
+
"prompt_length": len(prompt),
|
|
283
|
+
"analysis": {
|
|
284
|
+
"complexity": analysis.get("complexity"),
|
|
285
|
+
"requires_agents": analysis.get("requires_agents"),
|
|
286
|
+
"agents_recommended": analysis.get("recommended_agents"),
|
|
287
|
+
"strategy": analysis.get("strategy"),
|
|
288
|
+
"confidence": analysis.get("confidence")
|
|
289
|
+
},
|
|
290
|
+
"decision": decision
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
try:
|
|
294
|
+
with open(log_file, 'a', encoding='utf-8') as f:
|
|
295
|
+
f.write(json.dumps(entry, ensure_ascii=False) + '\n')
|
|
296
|
+
except Exception:
|
|
297
|
+
pass # Silently fail logging
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def process_user_prompt(prompt: str) -> Tuple[str, Dict[str, Any]]:
|
|
301
|
+
"""
|
|
302
|
+
Processa prompt do usuário e decide sobre uso de agentes.
|
|
303
|
+
|
|
304
|
+
Esta é a função principal chamada pelo hook.
|
|
305
|
+
|
|
306
|
+
Args:
|
|
307
|
+
prompt: Texto do usuário
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
Tupla (contexto_adicional, metadata)
|
|
311
|
+
"""
|
|
312
|
+
config = load_config()
|
|
313
|
+
|
|
314
|
+
# Verificar se hook está habilitado
|
|
315
|
+
if not config.get("enabled", True):
|
|
316
|
+
return "", {"decision": "hook_disabled"}
|
|
317
|
+
|
|
318
|
+
# Verificar se deve pular
|
|
319
|
+
if should_skip_analysis(prompt, config):
|
|
320
|
+
return "", {"decision": "skipped_trivial"}
|
|
321
|
+
|
|
322
|
+
# Verificar War Room explícito
|
|
323
|
+
if detect_war_room_request(prompt, config):
|
|
324
|
+
context = generate_war_room_context(prompt)
|
|
325
|
+
log_analysis(prompt, {"war_room": True}, "war_room_explicit")
|
|
326
|
+
return context, {"decision": "war_room", "explicit": True}
|
|
327
|
+
|
|
328
|
+
# Analisar prompt
|
|
329
|
+
analysis = analyze_prompt(prompt)
|
|
330
|
+
|
|
331
|
+
if not analysis.get("available"):
|
|
332
|
+
return "", {"decision": "analysis_unavailable", "reason": analysis.get("reason")}
|
|
333
|
+
|
|
334
|
+
# Verificar se força agentes
|
|
335
|
+
force_agents = detect_force_agents(prompt, config)
|
|
336
|
+
|
|
337
|
+
# Decidir se deve injetar contexto
|
|
338
|
+
should_inject = False
|
|
339
|
+
decision = "no_agents_needed"
|
|
340
|
+
|
|
341
|
+
complexity_value = analysis.get("complexity_value", 0)
|
|
342
|
+
min_complexity = config.get("min_complexity_for_notification", 2)
|
|
343
|
+
|
|
344
|
+
if force_agents:
|
|
345
|
+
should_inject = True
|
|
346
|
+
decision = "forced_by_user"
|
|
347
|
+
elif analysis.get("requires_agents") and complexity_value >= min_complexity:
|
|
348
|
+
should_inject = True
|
|
349
|
+
decision = "complexity_threshold_met"
|
|
350
|
+
elif complexity_value >= 4: # COMPLEX ou CRITICAL
|
|
351
|
+
should_inject = True
|
|
352
|
+
decision = "high_complexity"
|
|
353
|
+
|
|
354
|
+
# Gerar contexto se necessário
|
|
355
|
+
if should_inject and config.get("auto_inject_orchestration", True):
|
|
356
|
+
context = generate_agent_context(analysis, config)
|
|
357
|
+
log_analysis(prompt, analysis, decision)
|
|
358
|
+
return context, {"decision": decision, "analysis": analysis}
|
|
359
|
+
|
|
360
|
+
# Log mesmo sem injeção
|
|
361
|
+
if config.get("log_all_analyses", True):
|
|
362
|
+
log_analysis(prompt, analysis, decision)
|
|
363
|
+
|
|
364
|
+
return "", {"decision": decision, "analysis": analysis}
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
# ============================================================================
|
|
368
|
+
# INTERFACE PARA HOOK DO CLAUDE CODE
|
|
369
|
+
# ============================================================================
|
|
370
|
+
|
|
371
|
+
def hook_handler(event: Dict) -> Dict:
|
|
372
|
+
"""
|
|
373
|
+
Handler principal para integração com sistema de hooks.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
event: Evento do hook contendo prompt e contexto
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
Dict com contexto adicional e metadata
|
|
380
|
+
"""
|
|
381
|
+
prompt = event.get("prompt", "")
|
|
382
|
+
|
|
383
|
+
if not prompt:
|
|
384
|
+
return {"context": "", "metadata": {"decision": "empty_prompt"}}
|
|
385
|
+
|
|
386
|
+
context, metadata = process_user_prompt(prompt)
|
|
387
|
+
|
|
388
|
+
return {
|
|
389
|
+
"context": context,
|
|
390
|
+
"metadata": metadata
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
# ============================================================================
|
|
395
|
+
# CLI PARA TESTES
|
|
396
|
+
# ============================================================================
|
|
397
|
+
|
|
398
|
+
def main():
|
|
399
|
+
"""CLI para testar o hook."""
|
|
400
|
+
import argparse
|
|
401
|
+
|
|
402
|
+
parser = argparse.ArgumentParser(description='JARVIS Multi-Agent Hook')
|
|
403
|
+
parser.add_argument('prompt', nargs='?', help='Prompt para testar')
|
|
404
|
+
parser.add_argument('--verbose', '-v', action='store_true', help='Saída detalhada')
|
|
405
|
+
|
|
406
|
+
args = parser.parse_args()
|
|
407
|
+
|
|
408
|
+
if args.prompt:
|
|
409
|
+
context, metadata = process_user_prompt(args.prompt)
|
|
410
|
+
|
|
411
|
+
print(f"\n📊 ANÁLISE DO HOOK")
|
|
412
|
+
print(f"{'='*60}")
|
|
413
|
+
print(f"Prompt: {args.prompt[:80]}...")
|
|
414
|
+
print(f"Decisão: {metadata.get('decision')}")
|
|
415
|
+
|
|
416
|
+
if args.verbose and metadata.get('analysis'):
|
|
417
|
+
analysis = metadata['analysis']
|
|
418
|
+
print(f"\nAnálise Detalhada:")
|
|
419
|
+
print(f" Complexidade: {analysis.get('complexity')}")
|
|
420
|
+
print(f" Requer Agentes: {analysis.get('requires_agents')}")
|
|
421
|
+
print(f" Agentes: {analysis.get('recommended_agents')}")
|
|
422
|
+
print(f" Estratégia: {analysis.get('strategy')}")
|
|
423
|
+
print(f" Confiança: {analysis.get('confidence', 0):.0%}")
|
|
424
|
+
|
|
425
|
+
if context:
|
|
426
|
+
print(f"\n📋 CONTEXTO GERADO:")
|
|
427
|
+
print(f"{'='*60}")
|
|
428
|
+
print(context)
|
|
429
|
+
else:
|
|
430
|
+
# Modo interativo
|
|
431
|
+
print("🧪 JARVIS Multi-Agent Hook - Modo Teste")
|
|
432
|
+
print("Digite prompts para ver a análise. 'sair' para encerrar.\n")
|
|
433
|
+
|
|
434
|
+
while True:
|
|
435
|
+
try:
|
|
436
|
+
prompt = input("Teste: ").strip()
|
|
437
|
+
if prompt.lower() in ['sair', 'exit', 'quit']:
|
|
438
|
+
break
|
|
439
|
+
if not prompt:
|
|
440
|
+
continue
|
|
441
|
+
|
|
442
|
+
context, metadata = process_user_prompt(prompt)
|
|
443
|
+
|
|
444
|
+
print(f"\n Decisão: {metadata.get('decision')}")
|
|
445
|
+
|
|
446
|
+
if metadata.get('analysis'):
|
|
447
|
+
a = metadata['analysis']
|
|
448
|
+
print(f" Complexidade: {a.get('complexity')} | Agentes: {a.get('requires_agents')}")
|
|
449
|
+
|
|
450
|
+
if context:
|
|
451
|
+
print(f" ✅ Contexto de agentes seria injetado")
|
|
452
|
+
else:
|
|
453
|
+
print(f" ⏭️ Sem injeção de contexto")
|
|
454
|
+
|
|
455
|
+
print()
|
|
456
|
+
|
|
457
|
+
except KeyboardInterrupt:
|
|
458
|
+
break
|
|
459
|
+
|
|
460
|
+
print("\nAté logo!")
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
if __name__ == '__main__':
|
|
464
|
+
main()
|