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.

Files changed (308) hide show
  1. package/.claude/CLAUDE.md +155 -0
  2. package/.claude/commands/agents.md +161 -0
  3. package/.claude/commands/ask.md +117 -0
  4. package/.claude/commands/benchmark.md +224 -0
  5. package/.claude/commands/chat.md +343 -0
  6. package/.claude/commands/compare.md +116 -0
  7. package/.claude/commands/conclave.md +194 -0
  8. package/.claude/commands/config.md +133 -0
  9. package/.claude/commands/council.md +194 -0
  10. package/.claude/commands/create-agent.md +452 -0
  11. package/.claude/commands/debate.md +157 -0
  12. package/.claude/commands/documentation/create-architecture-documentation.md +175 -0
  13. package/.claude/commands/dossiers.md +180 -0
  14. package/.claude/commands/evolve.md +223 -0
  15. package/.claude/commands/extract-dna.md +170 -0
  16. package/.claude/commands/extract-knowledge.md +507 -0
  17. package/.claude/commands/inbox.md +296 -0
  18. package/.claude/commands/ingest-empresa.md +191 -0
  19. package/.claude/commands/ingest.md +182 -0
  20. package/.claude/commands/jarvis-briefing.md +67 -0
  21. package/.claude/commands/jarvis-control.md +169 -0
  22. package/.claude/commands/jarvis-full.md +181 -0
  23. package/.claude/commands/jarvis.md +212 -0
  24. package/.claude/commands/ler-drive.md +212 -0
  25. package/.claude/commands/log.md +158 -0
  26. package/.claude/commands/loop.md +133 -0
  27. package/.claude/commands/loops.md +73 -0
  28. package/.claude/commands/mission-autopilot.md +538 -0
  29. package/.claude/commands/mission.md +353 -0
  30. package/.claude/commands/process-inbox.md +148 -0
  31. package/.claude/commands/process-jarvis.md +3036 -0
  32. package/.claude/commands/process-video.md +131 -0
  33. package/.claude/commands/rag-search.md +78 -0
  34. package/.claude/commands/resume.md +33 -0
  35. package/.claude/commands/save.md +38 -0
  36. package/.claude/commands/scan-inbox.md +125 -0
  37. package/.claude/commands/setup.md +99 -0
  38. package/.claude/commands/system-digest.md +243 -0
  39. package/.claude/commands/verify.md +182 -0
  40. package/.claude/commands/view-dna.md +169 -0
  41. package/.claude/hooks/agent_doctor.py +433 -0
  42. package/.claude/hooks/agent_memory_persister.py +203 -0
  43. package/.claude/hooks/auto_formatter.py +158 -0
  44. package/.claude/hooks/checkpoint_writer.py +244 -0
  45. package/.claude/hooks/claude_md_guard.py +146 -0
  46. package/.claude/hooks/creation_validator.py +357 -0
  47. package/.claude/hooks/enforce_dual_location.py +501 -0
  48. package/.claude/hooks/enforce_plan_mode.py +220 -0
  49. package/.claude/hooks/inbox_age_alert.py +367 -0
  50. package/.claude/hooks/jarvis_briefing.py +506 -0
  51. package/.claude/hooks/ledger_updater.py +301 -0
  52. package/.claude/hooks/memory_hints_injector.py +251 -0
  53. package/.claude/hooks/memory_updater.py +202 -0
  54. package/.claude/hooks/multi_agent_hook.py +464 -0
  55. package/.claude/hooks/notification_system.py +120 -0
  56. package/.claude/hooks/pattern_analyzer.py +526 -0
  57. package/.claude/hooks/pending_tracker.py +188 -0
  58. package/.claude/hooks/post_batch_cascading.py +1740 -0
  59. package/.claude/hooks/post_output_validator.py +358 -0
  60. package/.claude/hooks/post_tool_use.py +120 -0
  61. package/.claude/hooks/post_write_validator.py +200 -0
  62. package/.claude/hooks/quality_watchdog.py +394 -0
  63. package/.claude/hooks/ralph_wiggum.py +277 -0
  64. package/.claude/hooks/session-source-sync.py +218 -0
  65. package/.claude/hooks/session_autosave_v2.py +1135 -0
  66. package/.claude/hooks/session_end.py +203 -0
  67. package/.claude/hooks/session_start.py +939 -0
  68. package/.claude/hooks/skill_indexer.py +48 -0
  69. package/.claude/hooks/skill_router.py +358 -0
  70. package/.claude/hooks/stop_hook_completeness.py +178 -0
  71. package/.claude/hooks/subagent_tracker.py +163 -0
  72. package/.claude/hooks/token_checkpoint.py +584 -0
  73. package/.claude/hooks/user_prompt_submit.py +125 -0
  74. package/.claude/rules/ANTHROPIC-STANDARDS.md +384 -0
  75. package/.claude/rules/CLAUDE-LITE.md +201 -0
  76. package/.claude/rules/RULE-GROUP-1.md +320 -0
  77. package/.claude/rules/RULE-GROUP-2.md +307 -0
  78. package/.claude/rules/RULE-GROUP-3.md +248 -0
  79. package/.claude/rules/RULE-GROUP-4.md +427 -0
  80. package/.claude/rules/RULE-GROUP-5.md +388 -0
  81. package/.claude/rules/RULE-GROUP-6.md +387 -0
  82. package/.claude/rules/logging.md +53 -0
  83. package/.claude/rules/mcp-governance.md +128 -0
  84. package/.claude/rules/pipeline.md +60 -0
  85. package/.claude/rules/state-management.md +93 -0
  86. package/.claude/scripts/apply-tags.py +77 -0
  87. package/.claude/scripts/batch-extract-transcriptions.py +132 -0
  88. package/.claude/scripts/build-complete-index.py +250 -0
  89. package/.claude/scripts/build-planilha-index.py +170 -0
  90. package/.claude/scripts/complete-tag-matching.py +250 -0
  91. package/.claude/scripts/deduplicate-inbox.py +139 -0
  92. package/.claude/scripts/docx-xml-extractor.py +141 -0
  93. package/.claude/scripts/extract-docx-text.py +58 -0
  94. package/.claude/scripts/extract-single-transcription.py +74 -0
  95. package/.claude/scripts/extract_docx_from_gdrive.py +77 -0
  96. package/.claude/scripts/organized-downloader.py +246 -0
  97. package/.claude/scripts/planilha-tagger.py +187 -0
  98. package/.claude/scripts/revert-tags.py +70 -0
  99. package/.claude/scripts/source-sync.py +265 -0
  100. package/.claude/scripts/tag-inbox-files.py +276 -0
  101. package/.claude/scripts/tag-inbox-v2.py +253 -0
  102. package/.claude/scripts/test-extraction.py +35 -0
  103. package/.claude/scripts/test-full-extraction.py +74 -0
  104. package/.claude/skills/00-SKILL-CREATOR/SKILL.md +186 -0
  105. package/.claude/skills/01-SKILL-DOCS-MEGABRAIN/SKILL.md +251 -0
  106. package/.claude/skills/02-SKILL-PYTHON-MEGABRAIN/SKILL.md +323 -0
  107. package/.claude/skills/03-SKILL-AGENT-CREATION/SKILL.md +374 -0
  108. package/.claude/skills/04-SKILL-KNOWLEDGE-EXTRACTION/SKILL.md +318 -0
  109. package/.claude/skills/05-SKILL-PIPELINE-JARVIS/SKILL.md +430 -0
  110. package/.claude/skills/06-SKILL-BRAINSTORMING/SKILL.md +72 -0
  111. package/.claude/skills/07-SKILL-DISPATCHING-PARALLEL-AGENTS/SKILL.md +193 -0
  112. package/.claude/skills/08-SKILL-EXECUTING-PLANS/SKILL.md +114 -0
  113. package/.claude/skills/09-SKILL-WRITING-PLANS/SKILL.md +184 -0
  114. package/.claude/skills/10-SKILL-VERIFICATION-BEFORE-COMPLETION/SKILL.md +130 -0
  115. package/.claude/skills/11-SKILL-USING-SUPERPOWERS/SKILL.md +105 -0
  116. package/.claude/skills/DETECTION-PROTOCOL.md +217 -0
  117. package/.claude/skills/README.md +240 -0
  118. package/.claude/skills/SKILL-REGISTRY.md +284 -0
  119. package/.claude/skills/SKILL-SUGGESTIONS.md +114 -0
  120. package/.claude/skills/_TEMPLATES/SKILL-WRITER-GUIDE.md +385 -0
  121. package/.claude/skills/chronicler/SKILL.md +146 -0
  122. package/.claude/skills/chronicler/chronicler_core.py +468 -0
  123. package/.claude/skills/code-review/SKILL.md +160 -0
  124. package/.claude/skills/council/SKILL.md +210 -0
  125. package/.claude/skills/executor/SKILL.md +161 -0
  126. package/.claude/skills/fase-2-5-tagging/SKILL.md +182 -0
  127. package/.claude/skills/feature-dev/SKILL.md +154 -0
  128. package/.claude/skills/finance-agent/SKILL.md +137 -0
  129. package/.claude/skills/frontend-design/SKILL.md +165 -0
  130. package/.claude/skills/gdrive-transcription-downloader/SKILL.md +249 -0
  131. package/.claude/skills/gemini-fallback/SKILL.md +67 -0
  132. package/.claude/skills/gemini-fallback/gemini_fetch.py +0 -0
  133. package/.claude/skills/gha/SKILL.md +96 -0
  134. package/.claude/skills/gha/gha_diagnostic.py +227 -0
  135. package/.claude/skills/github-workflow/SKILL.md +190 -0
  136. package/.claude/skills/hookify/SKILL.md +134 -0
  137. package/.claude/skills/hybrid-source-reading/SKILL.md +265 -0
  138. package/.claude/skills/jarvis/SKILL.md +546 -0
  139. package/.claude/skills/jarvis-briefing/SKILL.md +340 -0
  140. package/.claude/skills/ler-planilha/SKILL.md +281 -0
  141. package/.claude/skills/plugin-dev/SKILL.md +176 -0
  142. package/.claude/skills/pr-review-toolkit/SKILL.md +178 -0
  143. package/.claude/skills/resume/SKILL.md +61 -0
  144. package/.claude/skills/save/SKILL.md +87 -0
  145. package/.claude/skills/skill-writer/SKILL.md +153 -0
  146. package/.claude/skills/skill-writer/examples.md +191 -0
  147. package/.claude/skills/skill-writer/troubleshooting.md +205 -0
  148. package/.claude/skills/smart-download-tagger/SKILL.md +148 -0
  149. package/.claude/skills/source-sync/SKILL.md +240 -0
  150. package/.claude/skills/sync-docs/SKILL.md +193 -0
  151. package/.claude/skills/sync-docs/config.json +37 -0
  152. package/.claude/skills/sync-docs/gdrive_sync.py +358 -0
  153. package/.claude/skills/sync-docs/reauth.py +71 -0
  154. package/.claude/skills/talent-agent/SKILL.md +183 -0
  155. package/.claude/skills/verify/SKILL.md +154 -0
  156. package/.claude/skills/verify/verify_runner.py +0 -0
  157. package/.claude/skills/verify-6-levels/SKILL.md +234 -0
  158. package/.claude/templates/BATCH-LOG-TEMPLATE.md +221 -0
  159. package/.claudeignore +9 -0
  160. package/.gitattributes +4 -0
  161. package/.github/layer1-allowlist.txt +80 -0
  162. package/.github/layer2-manifest.txt +40 -0
  163. package/.gitignore +219 -0
  164. package/README.md +1210 -0
  165. package/agents/_templates/INDEX.md +741 -0
  166. package/agents/_templates/TEMPLATE-AGENT-MD-ULTRA-ROBUSTO-V3.md +2399 -0
  167. package/agents/boardroom/CHECKLIST-MASTER.md +281 -0
  168. package/agents/boardroom/INTEGRATION-GUIDE.md +406 -0
  169. package/agents/boardroom/README.md +238 -0
  170. package/agents/boardroom/config/BOARDROOM-CONFIG.md +186 -0
  171. package/agents/boardroom/config/TTS-INTEGRATION.md +258 -0
  172. package/agents/boardroom/config/VOICE-PROFILES.md +624 -0
  173. package/agents/boardroom/config/voice_mapping.json +128 -0
  174. package/agents/boardroom/scripts/audio_generator.py +375 -0
  175. package/agents/boardroom/scripts/audio_generator_edge.py +353 -0
  176. package/agents/boardroom/scripts/jarvis_boardroom_hook.py +415 -0
  177. package/agents/boardroom/scripts/notebooklm_generator.py +578 -0
  178. package/agents/boardroom/templates/EPISODE-TEMPLATE.md +367 -0
  179. package/agents/boardroom/templates/scene-templates/SCENE-AGENT-DEBATE.md +252 -0
  180. package/agents/boardroom/templates/scene-templates/SCENE-COUNCIL.md +270 -0
  181. package/agents/boardroom/templates/scene-templates/SCENE-DNA-CONSULTATION.md +126 -0
  182. package/agents/boardroom/templates/scene-templates/SCENE-QUESTION.md +174 -0
  183. package/agents/boardroom/workflows/WORKFLOW-AUDIO-GENERATION.md +421 -0
  184. package/agents/constitution/BASE-CONSTITUTION.md +254 -0
  185. package/agents/council/CRITIC.md +197 -0
  186. package/agents/council/DEVILS-ADVOCATE.md +274 -0
  187. package/agents/council/SYNTHESIZER.md +293 -0
  188. package/agents/council/advogado-do-diabo/AGENT.md +489 -0
  189. package/agents/council/advogado-do-diabo/SOUL.md +100 -0
  190. package/agents/council/critico-metodologico/AGENT.md +670 -0
  191. package/agents/council/critico-metodologico/SOUL.md +107 -0
  192. package/agents/council/sintetizador/AGENT.md +558 -0
  193. package/agents/council/sintetizador/SOUL.md +94 -0
  194. package/agents/persons/_example/AGENT-EXAMPLE.md +42 -0
  195. package/agents/persons/_example/DNA-EXAMPLE.yaml +61 -0
  196. package/agents/protocols/AGENT-COGNITION-PROTOCOL.md +779 -0
  197. package/agents/protocols/AGENT-INTEGRITY-PROTOCOL.md +692 -0
  198. package/agents/protocols/BATCH-VISUAL-PROTOCOL.md +841 -0
  199. package/agents/protocols/DNA-CONFIG-TEMPLATE.yaml +181 -0
  200. package/agents/protocols/DNA-EXTRACTION-PROTOCOL.md +370 -0
  201. package/agents/protocols/EPISTEMIC-PROTOCOL.md +333 -0
  202. package/agents/protocols/LOG-STRUCTURE-PROTOCOL.md +65 -0
  203. package/agents/protocols/MEMORY-PROTOCOL.md +567 -0
  204. package/agents/protocols/NARRATIVE-SYNTHESIS-PROTOCOL.md +278 -0
  205. package/agents/protocols/PHASE-4-VERIFICATION-CHECKPOINT.md +146 -0
  206. package/agents/protocols/SOUL-TEMPLATE.md +416 -0
  207. package/agents/protocols/TEMPLATE-EVOLUTION-PROTOCOL.md +544 -0
  208. package/agents/protocols/VISUAL-DIFF-PROTOCOL.md +159 -0
  209. package/agents/sua-empresa/README.md +44 -0
  210. package/agents/sua-empresa/_example/jds/EXAMPLE-JD.md +42 -0
  211. package/agents/sua-empresa/_example/org/EXAMPLE-ORG.md +32 -0
  212. package/agents/sua-empresa/_example/roles/EXAMPLE-ROLE.md +38 -0
  213. package/bin/cli.js +2 -0
  214. package/bin/lib/ascii-art.js +234 -0
  215. package/bin/lib/installer.js +402 -0
  216. package/bin/lib/setup-wizard.js +95 -0
  217. package/bin/lib/validate-email.js +109 -0
  218. package/bin/mega-brain.js +97 -0
  219. package/bin/push.js +342 -0
  220. package/bin/templates/env.example +38 -0
  221. package/inbox/.gitkeep +0 -0
  222. package/integrations/README.md +46 -0
  223. package/integrations/mcps/MCP-REGISTRY.md +56 -0
  224. package/integrations/mcps/excalidraw/CONFIG.md +56 -0
  225. package/integrations/mcps/gdrive/CONFIG.md +38 -0
  226. package/knowledge/dna/.gitkeep +0 -0
  227. package/knowledge/dossiers/persons/.gitkeep +0 -0
  228. package/knowledge/dossiers/persons/DOSSIER-EXAMPLE.md +49 -0
  229. package/knowledge/dossiers/system/.gitkeep +0 -0
  230. package/knowledge/dossiers/themes/.gitkeep +0 -0
  231. package/knowledge/playbooks/.gitkeep +0 -0
  232. package/knowledge/playbooks/PLAYBOOK-EXAMPLE.md +50 -0
  233. package/knowledge/sources/.gitkeep +0 -0
  234. package/logs/.gitkeep +0 -0
  235. package/package.json +128 -0
  236. package/processing/canonical/.gitkeep +0 -0
  237. package/processing/chunks/.gitkeep +0 -0
  238. package/processing/insights/.gitkeep +0 -0
  239. package/processing/narratives/.gitkeep +0 -0
  240. package/reference/CONSELHO.md +337 -0
  241. package/reference/CONTEXT7_README.md +28 -0
  242. package/reference/JARVIS-LOGGING-PROTOCOL.md +380 -0
  243. package/reference/QUICK-START.md +197 -0
  244. package/reference/README-RALPH-CASCATEAMENTO.md +207 -0
  245. package/reference/TEMPLATE-MASTER.md +727 -0
  246. package/reference/prds/prd-jarvis-mega-brain-v3.md +1305 -0
  247. package/reference/templates/phase5/IMPLEMENTATION-GUIDE.md +355 -0
  248. package/reference/templates/phase5/MOGA-BRAIN-PHASE5-TEMPLATES.md +1284 -0
  249. package/reference/templates/phase5/README.md +165 -0
  250. package/reference/workflow-claude-code-boris-cherny-continuous-claude.md +2232 -0
  251. package/system/database/001_moneyclub_buyers.sql +160 -0
  252. package/system/database/002_premium_token.sql +97 -0
  253. package/system/database/apply-migration.mjs +129 -0
  254. package/system/docs/MEGA-BRAIN-DEMO-COMPLETA.md +1226 -0
  255. package/system/docs/MEGA-BRAIN-MANIFESTO-COMPLETO.md +1054 -0
  256. package/system/docs/MOGA-BRAIN-EXPLICACAO-COMPLETA.md +791 -0
  257. package/system/docs/STRATEGIC-INTEGRATION-GUIDE.md +725 -0
  258. package/system/docs/architecture/01-system-context.md +136 -0
  259. package/system/docs/architecture/02-components.md +225 -0
  260. package/system/docs/architecture/03-data-flow.md +235 -0
  261. package/system/docs/architecture/04-integrations.md +283 -0
  262. package/system/docs/architecture/README.md +71 -0
  263. package/system/docs/architecture/diagrams/component-diagram.mmd +50 -0
  264. package/system/docs/architecture/diagrams/data-flow.mmd +39 -0
  265. package/system/docs/architecture/diagrams/system-overview.mmd +68 -0
  266. package/system/protocols/AGENT-AUTHORITY.md +217 -0
  267. package/system/protocols/CONSTITUICAO-BASE.md +115 -0
  268. package/system/protocols/CONSTITUTION.md +231 -0
  269. package/system/protocols/GOVERNANCE-MAP.md +123 -0
  270. package/system/protocols/HOOK-SECURITY-THREAT-MODEL.md +152 -0
  271. package/system/protocols/ORQUESTRACAO-PROTOCOL.md +215 -0
  272. package/system/protocols/_archive/CHUNKING-PROTOCOL.md +207 -0
  273. package/system/protocols/_archive/ENTITY-RESOLUTION-PROTOCOL.md +269 -0
  274. package/system/protocols/_archive/INSIGHT-EXTRACTION-PROTOCOL.md +257 -0
  275. package/system/protocols/_archive/NARRATIVE-SYNTHESIS-PROTOCOL.md +290 -0
  276. package/system/protocols/agents/AGENT-INTERACTION.md +315 -0
  277. package/system/protocols/agents/CORTEX-PROTOCOL.md +520 -0
  278. package/system/protocols/agents/EPISTEMIC-PROTOCOL.md +465 -0
  279. package/system/protocols/agents/MEMORY-PROTOCOL.md +366 -0
  280. package/system/protocols/agents/WAR-ROOM.md +355 -0
  281. package/system/protocols/company/COMPANY-DOCUMENT-PROTOCOL.md +793 -0
  282. package/system/protocols/company/COMPANY-ENRICHMENT-PROTOCOL.md +679 -0
  283. package/system/protocols/conclave/CONCLAVE-LOG-TEMPLATE-v2.md +309 -0
  284. package/system/protocols/conclave/CONCLAVE-PROTOCOL.md +518 -0
  285. package/system/protocols/conclave/DEBATE-DYNAMICS-CONFIG.yaml +322 -0
  286. package/system/protocols/conclave/DEBATE-DYNAMICS-PROTOCOL.md +613 -0
  287. package/system/protocols/conclave/DEBATE-PROTOCOL.md +323 -0
  288. package/system/protocols/council/COUNCIL-LOG-TEMPLATE-v2.md +309 -0
  289. package/system/protocols/council/COUNCIL-PROTOCOL.md +518 -0
  290. package/system/protocols/council/DEBATE-DYNAMICS-CONFIG.yaml +322 -0
  291. package/system/protocols/council/DEBATE-DYNAMICS-PROTOCOL.md +613 -0
  292. package/system/protocols/council/DEBATE-PROTOCOL.md +323 -0
  293. package/system/protocols/dna/DNA-EXTRACTION-PROTOCOL.md +1214 -0
  294. package/system/protocols/dna/ENRICHMENT-PROTOCOL.md +408 -0
  295. package/system/protocols/dna/REASONING-MODEL-PROTOCOL.md +331 -0
  296. package/system/protocols/pipeline/DOSSIER-COMPILATION-PROTOCOL.md +790 -0
  297. package/system/protocols/pipeline/NARRATIVE-METABOLISM-PROTOCOL.md +292 -0
  298. package/system/protocols/pipeline/PIPELINE-JARVIS-v2.1.md +606 -0
  299. package/system/protocols/pipeline/PROMPT-1.1-CHUNKING.md +154 -0
  300. package/system/protocols/pipeline/PROMPT-1.2-ENTITY-RESOLUTION.md +186 -0
  301. package/system/protocols/pipeline/PROMPT-2.1-DNA-TAGS-INCREMENT.md +208 -0
  302. package/system/protocols/pipeline/PROMPT-2.1-INSIGHT-EXTRACTION.md +191 -0
  303. package/system/protocols/pipeline/PROMPT-3.1-NARRATIVE-SYNTHESIS.md +331 -0
  304. package/system/protocols/pipeline/SOURCES-COMPILATION-PROTOCOL.md +340 -0
  305. package/system/protocols/system/AUTO-LOG-PROTOCOL.md +369 -0
  306. package/system/protocols/system/CHECKPOINT-ENFORCEMENT.md +176 -0
  307. package/system/protocols/system/ENFORCEMENT.md +435 -0
  308. package/system/protocols/system/LOG-TEMPLATES.md +1068 -0
@@ -0,0 +1,394 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Quality Watchdog - Layer 1 do META-AGENT System v1.0
4
+
5
+ FUNÇÃO: Detecta agentes em prompts e injeta MANDATORY_SECTIONS no contexto.
6
+ Faz parte do sistema de enforcement de qualidade (warn, não block).
7
+
8
+ REGRA #28: META-AGENT QUALITY AWARENESS
9
+ """
10
+
11
+ import json
12
+ import os
13
+ import re
14
+ from pathlib import Path
15
+ from datetime import datetime
16
+ from typing import Dict, Optional
17
+
18
+ PROJECT_ROOT = Path(os.environ.get('CLAUDE_PROJECT_DIR', '.'))
19
+ AGENTS_PATH = PROJECT_ROOT / "agents"
20
+ JARVIS_SUBAGENTS = PROJECT_ROOT / ".claude" / "jarvis" / "sub-agents"
21
+ LOGS_PATH = PROJECT_ROOT / "logs"
22
+ QUALITY_GAPS_LOG = LOGS_PATH / "quality_gaps.jsonl"
23
+
24
+
25
+ # ═══════════════════════════════════════════════════════════════════════════
26
+ # AGENT DETECTION
27
+ # ═══════════════════════════════════════════════════════════════════════════
28
+
29
+ # Keywords para sub-agents JARVIS
30
+ SUBAGENT_KEYWORDS = {
31
+ "chronicler": ["log bonito", "log visual", "chronicler", "formatar log", "status formatado", "resumo visual"],
32
+ }
33
+
34
+ # Dynamic caches (populated on first use)
35
+ _PERSON_KEYWORDS_CACHE = None
36
+ _CARGO_KEYWORDS_CACHE = None
37
+
38
+
39
+ def _scan_agents_directory(subdir: str) -> Dict:
40
+ """
41
+ Dynamically scan agents/{subdir}/ to build keyword map.
42
+ Each subdirectory name becomes an agent key, and keywords are
43
+ generated from the directory name parts.
44
+ """
45
+ keywords = {}
46
+ scan_path = AGENTS_PATH / subdir
47
+ if not scan_path.exists():
48
+ return keywords
49
+
50
+ for entry in scan_path.iterdir():
51
+ if entry.is_dir():
52
+ agent_name = entry.name.lower()
53
+ # Generate keywords from directory name
54
+ parts = agent_name.replace('-', ' ').replace('_', ' ').split()
55
+ kws = [agent_name.replace('-', ' ')] # full name as keyword
56
+ # Add individual meaningful parts (skip very short ones)
57
+ for part in parts:
58
+ if len(part) >= 3:
59
+ kws.append(part)
60
+ # Also add the hyphenated form
61
+ if '-' in agent_name or '_' in agent_name:
62
+ kws.append(agent_name)
63
+ keywords[agent_name] = list(set(kws))
64
+
65
+ return keywords
66
+
67
+
68
+ def _get_person_keywords() -> Dict:
69
+ """Lazily load person keywords from agents/persons/ directory."""
70
+ global _PERSON_KEYWORDS_CACHE
71
+ if _PERSON_KEYWORDS_CACHE is None:
72
+ _PERSON_KEYWORDS_CACHE = _scan_agents_directory("persons")
73
+ return _PERSON_KEYWORDS_CACHE
74
+
75
+
76
+ def _get_cargo_keywords() -> Dict:
77
+ """Lazily load cargo keywords from agents/cargo/ directory (recursive)."""
78
+ global _CARGO_KEYWORDS_CACHE
79
+ if _CARGO_KEYWORDS_CACHE is None:
80
+ _CARGO_KEYWORDS_CACHE = {}
81
+ cargo_path = AGENTS_PATH / "cargo"
82
+ if cargo_path.exists():
83
+ # Scan all subdirectories recursively for agent folders containing AGENT.md
84
+ for agent_md in cargo_path.rglob("AGENT.md"):
85
+ agent_dir = agent_md.parent
86
+ agent_name = agent_dir.name.lower()
87
+ parts = agent_name.replace('-', ' ').replace('_', ' ').split()
88
+ kws = [agent_name.replace('-', ' ')]
89
+ for part in parts:
90
+ if len(part) >= 3:
91
+ kws.append(part)
92
+ _CARGO_KEYWORDS_CACHE[agent_name] = list(set(kws))
93
+ return _CARGO_KEYWORDS_CACHE
94
+
95
+
96
+ def detect_agent_in_prompt(prompt: str) -> Dict:
97
+ """
98
+ Detecta qual agente está sendo requisitado no prompt.
99
+
100
+ Returns:
101
+ dict: {type: "subagent"|"person"|"cargo"|None, name: str|None}
102
+ """
103
+ prompt_lower = prompt.lower()
104
+
105
+ # Detecta sub-agent JARVIS (prioridade mais alta)
106
+ for agent, keywords in SUBAGENT_KEYWORDS.items():
107
+ if any(kw in prompt_lower for kw in keywords):
108
+ return {"type": "subagent", "name": agent}
109
+
110
+ # Detecta PERSON agent (dynamically from agents/persons/ directory)
111
+ for agent, keywords in _get_person_keywords().items():
112
+ if any(kw in prompt_lower for kw in keywords):
113
+ return {"type": "person", "name": agent}
114
+
115
+ # Detecta CARGO agent (dynamically from agents/cargo/ directory)
116
+ for agent, keywords in _get_cargo_keywords().items():
117
+ if any(kw in prompt_lower for kw in keywords):
118
+ return {"type": "cargo", "name": agent}
119
+
120
+ return {"type": None, "name": None}
121
+
122
+
123
+ # ═══════════════════════════════════════════════════════════════════════════
124
+ # MANDATORY SECTIONS EXTRACTION
125
+ # ═══════════════════════════════════════════════════════════════════════════
126
+
127
+ def extract_mandatory_sections(agent_path: Path) -> Dict:
128
+ """
129
+ Extrai MANDATORY_SECTIONS do header do AGENT.md.
130
+
131
+ Prioridade:
132
+ 1. Bloco formal <!-- MANDATORY --> ... <!-- End MANDATORY -->
133
+ 2. Seção ## ⚠️ MANDATORY OUTPUT SECTIONS
134
+ 3. Fallback: primeiras 50 linhas
135
+ """
136
+ agent_md = agent_path / "AGENT.md"
137
+ if not agent_md.exists():
138
+ return {"found": False, "content": "", "lines": 0}
139
+
140
+ try:
141
+ content = agent_md.read_text(encoding='utf-8')
142
+ except Exception as e:
143
+ return {"found": False, "content": "", "lines": 0, "error": str(e)}
144
+
145
+ # Método 1: Bloco formal com comentários HTML
146
+ match = re.search(
147
+ r'<!-- MANDATORY -->(.+?)<!-- End MANDATORY -->',
148
+ content,
149
+ re.DOTALL | re.IGNORECASE
150
+ )
151
+ if match:
152
+ return {
153
+ "found": True,
154
+ "method": "html_comments",
155
+ "content": match.group(1).strip(),
156
+ "lines": len(match.group(1).split('\n'))
157
+ }
158
+
159
+ # Método 2: Seção com header markdown
160
+ match = re.search(
161
+ r'## ⚠️ MANDATORY OUTPUT SECTIONS.*?(?=## [^⚠️]|$)',
162
+ content,
163
+ re.DOTALL | re.IGNORECASE
164
+ )
165
+ if match:
166
+ return {
167
+ "found": True,
168
+ "method": "markdown_header",
169
+ "content": match.group(0).strip(),
170
+ "lines": len(match.group(0).split('\n'))
171
+ }
172
+
173
+ # Método 3: Fallback - primeiras 50 linhas (para agents sem MANDATORY formal)
174
+ lines = content.split('\n')[:50]
175
+ return {
176
+ "found": False,
177
+ "method": "fallback_header",
178
+ "content": '\n'.join(lines),
179
+ "lines": 50
180
+ }
181
+
182
+
183
+ def resolve_agent_path(agent_info: Dict) -> Optional[Path]:
184
+ """Resolve o caminho do agente baseado no tipo."""
185
+ if not agent_info.get("name"):
186
+ return None
187
+
188
+ agent_name = agent_info["name"].upper()
189
+
190
+ if agent_info["type"] == "subagent":
191
+ return JARVIS_SUBAGENTS / agent_name
192
+ elif agent_info["type"] == "person":
193
+ return AGENTS_PATH / "persons" / agent_name
194
+ elif agent_info["type"] == "cargo":
195
+ # Cargo agents têm estrutura diferente
196
+ cargo_paths = {
197
+ "CRO": AGENTS_PATH / "cargo" / "C-LEVEL" / "CRO",
198
+ "CFO": AGENTS_PATH / "cargo" / "C-LEVEL" / "CFO",
199
+ "SALES-MANAGER": AGENTS_PATH / "cargo" / "SALES" / "SALES-MANAGER",
200
+ "closer": AGENTS_PATH / "cargo" / "SALES" / "closer",
201
+ "SDR": AGENTS_PATH / "cargo" / "SALES" / "SDR",
202
+ }
203
+ return cargo_paths.get(agent_name)
204
+
205
+ return None
206
+
207
+
208
+ # ═══════════════════════════════════════════════════════════════════════════
209
+ # CONTEXT INJECTION
210
+ # ═══════════════════════════════════════════════════════════════════════════
211
+
212
+ def inject_quality_context(prompt: str) -> str:
213
+ """
214
+ Injeta contexto de qualidade se agente detectado.
215
+
216
+ Retorna string vazia se nenhum agente detectado.
217
+ """
218
+ agent_info = detect_agent_in_prompt(prompt)
219
+
220
+ if not agent_info.get("name"):
221
+ return ""
222
+
223
+ agent_path = resolve_agent_path(agent_info)
224
+ if not agent_path or not agent_path.exists():
225
+ return ""
226
+
227
+ mandatory = extract_mandatory_sections(agent_path)
228
+
229
+ # Sempre injeta contexto se agente detectado
230
+ context = f"""
231
+ [QUALITY WATCHDOG ACTIVATED]
232
+ Agent detected: {agent_info['name']}
233
+ Type: {agent_info['type']}
234
+ Path: {agent_path}
235
+
236
+ """
237
+
238
+ if mandatory.get("found"):
239
+ context += f"""--- MANDATORY SECTIONS (MUST INCLUDE IN OUTPUT) ---
240
+ {mandatory['content']}
241
+ --- END MANDATORY SECTIONS ---
242
+
243
+ ⚠️ OUTPUT WILL BE VALIDATED AGAINST THESE REQUIREMENTS
244
+ ⚠️ Quality scoring active - minimum recommended: 70/100
245
+ """
246
+ else:
247
+ context += f"""--- AGENT HEADER (First 50 lines) ---
248
+ {mandatory['content']}
249
+ --- END HEADER ---
250
+
251
+ ℹ️ No formal MANDATORY_SECTIONS found. Using header as reference.
252
+ """
253
+
254
+ return context
255
+
256
+
257
+ # ═══════════════════════════════════════════════════════════════════════════
258
+ # LOGGING
259
+ # ═══════════════════════════════════════════════════════════════════════════
260
+
261
+ def log_quality_gap(agent: str, score: int, missing: list, agent_type: str = "unknown"):
262
+ """
263
+ Loga gap de qualidade para análise do DOCTOR (Layer 2).
264
+
265
+ Não bloqueia - apenas registra para análise posterior.
266
+ """
267
+ # Garantir que diretório existe
268
+ QUALITY_GAPS_LOG.parent.mkdir(parents=True, exist_ok=True)
269
+
270
+ entry = {
271
+ "timestamp": datetime.now().isoformat(),
272
+ "agent": agent,
273
+ "agent_type": agent_type,
274
+ "score": score,
275
+ "missing_sections": missing,
276
+ "status": "gap_detected",
277
+ "action_taken": "logged_for_review"
278
+ }
279
+
280
+ try:
281
+ with open(QUALITY_GAPS_LOG, "a", encoding='utf-8') as f:
282
+ f.write(json.dumps(entry, ensure_ascii=False) + "\n")
283
+ except Exception as e:
284
+ # Falha silenciosa - não deve interromper fluxo
285
+ pass
286
+
287
+
288
+ def log_watchdog_activation(agent_info: Dict, mandatory_found: bool):
289
+ """Loga ativação do watchdog para auditoria."""
290
+ log_file = LOGS_PATH / "watchdog_activations.jsonl"
291
+ log_file.parent.mkdir(parents=True, exist_ok=True)
292
+
293
+ entry = {
294
+ "timestamp": datetime.now().isoformat(),
295
+ "agent": agent_info.get("name"),
296
+ "type": agent_info.get("type"),
297
+ "mandatory_found": mandatory_found
298
+ }
299
+
300
+ try:
301
+ with open(log_file, "a", encoding='utf-8') as f:
302
+ f.write(json.dumps(entry, ensure_ascii=False) + "\n")
303
+ except Exception:
304
+ pass
305
+
306
+
307
+ # ═══════════════════════════════════════════════════════════════════════════
308
+ # MAIN INTERFACE
309
+ # ═══════════════════════════════════════════════════════════════════════════
310
+
311
+ def process_prompt(prompt: str) -> Dict:
312
+ """
313
+ Processa prompt e retorna contexto de qualidade se aplicável.
314
+
315
+ Interface principal para integração com user_prompt_submit.py
316
+ """
317
+ agent_info = detect_agent_in_prompt(prompt)
318
+
319
+ result = {
320
+ "agent_detected": agent_info.get("name") is not None,
321
+ "agent_info": agent_info,
322
+ "context": "",
323
+ "mandatory_found": False
324
+ }
325
+
326
+ if agent_info.get("name"):
327
+ context = inject_quality_context(prompt)
328
+ result["context"] = context
329
+ result["mandatory_found"] = "MANDATORY SECTIONS" in context
330
+
331
+ # Log activation
332
+ log_watchdog_activation(agent_info, result["mandatory_found"])
333
+
334
+ return result
335
+
336
+
337
+ # ═══════════════════════════════════════════════════════════════════════════
338
+ # CLI INTERFACE
339
+ # ═══════════════════════════════════════════════════════════════════════════
340
+
341
+ def main():
342
+ """
343
+ Hook entry point for Claude Code UserPromptSubmit event.
344
+ Reads JSON from stdin, outputs JSON to stdout.
345
+ """
346
+ import sys
347
+
348
+ try:
349
+ input_data = sys.stdin.read()
350
+ hook_input = json.loads(input_data) if input_data else {}
351
+
352
+ prompt = hook_input.get('prompt', '')
353
+ if not prompt:
354
+ print(json.dumps({'continue': True}))
355
+ return
356
+
357
+ result = process_prompt(prompt)
358
+
359
+ feedback = result.get('context') if result.get('agent_detected') else None
360
+
361
+ print(json.dumps({
362
+ 'continue': True,
363
+ 'feedback': feedback if feedback else None
364
+ }))
365
+
366
+ except Exception:
367
+ print(json.dumps({'continue': True}))
368
+
369
+
370
+ def cli_test():
371
+ """CLI test mode - run directly for debugging."""
372
+ import sys
373
+
374
+ if len(sys.argv) > 1:
375
+ test_prompt = " ".join(sys.argv[1:])
376
+ else:
377
+ test_prompt = "me dá um log bonito do conteúdo do Alex Hormozi"
378
+
379
+ print(f"Testing prompt: {test_prompt}\n")
380
+
381
+ result = process_prompt(test_prompt)
382
+
383
+ print(f"Agent detected: {result['agent_detected']}")
384
+ print(f"Agent info: {result['agent_info']}")
385
+ print(f"Mandatory found: {result['mandatory_found']}")
386
+ print(f"\nContext to inject:\n{result['context'][:500]}...")
387
+
388
+
389
+ if __name__ == "__main__":
390
+ import sys
391
+ if len(sys.argv) > 1 and sys.argv[1] == '--test':
392
+ cli_test()
393
+ else:
394
+ main()
@@ -0,0 +1,277 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ RALPH WIGGUM - COMPLETION PROMISE HOOK
4
+ ======================================
5
+ Baseado no plugin original de Boris Cherny.
6
+
7
+ O "completion promise" é um pattern onde Claude deve outputtar uma string
8
+ específica para sinalizar que a tarefa está REALMENTE completa.
9
+
10
+ Funcionamento:
11
+ 1. Claude recebe instrução para usar <promise>DONE</promise> quando terminar
12
+ 2. Este hook verifica se o completion promise foi dado
13
+ 3. Se não foi, re-prompta Claude para continuar ou confirmar
14
+
15
+ Token: <promise>DONE</promise>
16
+
17
+ Referência: https://github.com/chernyshov/ralph-wiggum
18
+ """
19
+
20
+ import sys
21
+ import os
22
+ import json
23
+ import re
24
+ from pathlib import Path
25
+ from datetime import datetime
26
+
27
+ PROJECT_ROOT = Path(os.environ.get('CLAUDE_PROJECT_DIR', '.'))
28
+ STATE_FILE = PROJECT_ROOT / '.claude' / 'ralph_wiggum_state.json'
29
+ LOG_FILE = PROJECT_ROOT / 'logs' / 'ralph_wiggum.jsonl'
30
+
31
+ # Completion promise token
32
+ PROMISE_TOKEN = '<promise>DONE</promise>'
33
+ PROMISE_PATTERN = re.compile(r'<promise>DONE</promise>', re.IGNORECASE)
34
+
35
+ # Tasks that require completion promise
36
+ COMPLEX_TASK_KEYWORDS = [
37
+ 'processar', 'pipeline', 'batch', 'criar agente',
38
+ 'implementar', 'refatorar', 'migrar', 'varredura',
39
+ 'fase 4', 'fase 5', 'dossier', 'playbook'
40
+ ]
41
+
42
+
43
+ def ensure_dirs():
44
+ """Ensure log directory exists"""
45
+ LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
46
+ STATE_FILE.parent.mkdir(parents=True, exist_ok=True)
47
+
48
+
49
+ def load_state() -> dict:
50
+ """Load Ralph Wiggum state"""
51
+ if STATE_FILE.exists():
52
+ try:
53
+ return json.loads(STATE_FILE.read_text())
54
+ except:
55
+ pass
56
+ return {
57
+ 'active_task': None,
58
+ 'promise_required': False,
59
+ 'promise_received': False,
60
+ 'reprompt_count': 0,
61
+ 'max_reprompts': 3
62
+ }
63
+
64
+
65
+ def save_state(state: dict):
66
+ """Save Ralph Wiggum state"""
67
+ ensure_dirs()
68
+ STATE_FILE.write_text(json.dumps(state, indent=2))
69
+
70
+
71
+ def log_event(event_type: str, details: dict):
72
+ """Log Ralph Wiggum events"""
73
+ ensure_dirs()
74
+ entry = {
75
+ 'timestamp': datetime.now().isoformat(),
76
+ 'event': event_type,
77
+ **details
78
+ }
79
+ with open(LOG_FILE, 'a') as f:
80
+ f.write(json.dumps(entry) + '\n')
81
+
82
+
83
+ def is_complex_task(task_description: str) -> bool:
84
+ """Determine if task requires completion promise"""
85
+ if not task_description:
86
+ return False
87
+ task_lower = task_description.lower()
88
+ return any(keyword in task_lower for keyword in COMPLEX_TASK_KEYWORDS)
89
+
90
+
91
+ def check_promise_in_output() -> bool:
92
+ """Check if completion promise was given in recent output"""
93
+ # Check LEDGER for promise
94
+ ledger_path = PROJECT_ROOT / '.claude' / 'LEDGER.md'
95
+ if ledger_path.exists():
96
+ content = ledger_path.read_text()
97
+ if PROMISE_PATTERN.search(content):
98
+ return True
99
+
100
+ # Check recent session log
101
+ sessions_dir = PROJECT_ROOT / '.claude' / 'sessions'
102
+ if sessions_dir.exists():
103
+ session_files = sorted(sessions_dir.glob('SESSION-*.md'), reverse=True)
104
+ if session_files:
105
+ recent = session_files[0].read_text()
106
+ if PROMISE_PATTERN.search(recent):
107
+ return True
108
+
109
+ return False
110
+
111
+
112
+ def start_task(task_description: str):
113
+ """Call when a complex task starts"""
114
+ state = load_state()
115
+
116
+ if is_complex_task(task_description):
117
+ state['active_task'] = task_description
118
+ state['promise_required'] = True
119
+ state['promise_received'] = False
120
+ state['reprompt_count'] = 0
121
+ save_state(state)
122
+ log_event('task_started', {'task': task_description, 'promise_required': True})
123
+
124
+ # Inject instruction about completion promise
125
+ print(f"""
126
+ ╔══════════════════════════════════════════════════════════════════════════════╗
127
+ ║ 🎯 RALPH WIGGUM ACTIVE ║
128
+ ╠══════════════════════════════════════════════════════════════════════════════╣
129
+ ║ ║
130
+ ║ Tarefa complexa detectada: {task_description[:50]:<50} ║
131
+ ║ ║
132
+ ║ Quando COMPLETAR a tarefa, inclua na sua resposta: ║
133
+ ║ ║
134
+ ║ <promise>DONE</promise> ║
135
+ ║ ║
136
+ ║ Isso confirma que a tarefa está REALMENTE completa. ║
137
+ ║ ║
138
+ ╚══════════════════════════════════════════════════════════════════════════════╝
139
+ """)
140
+
141
+
142
+ def check_completion() -> bool:
143
+ """Check if task is complete (has promise)"""
144
+ state = load_state()
145
+
146
+ if not state.get('promise_required'):
147
+ return True
148
+
149
+ if state.get('promise_received'):
150
+ return True
151
+
152
+ # Check if promise was given
153
+ if check_promise_in_output():
154
+ state['promise_received'] = True
155
+ save_state(state)
156
+ log_event('promise_received', {'task': state.get('active_task')})
157
+ return True
158
+
159
+ return False
160
+
161
+
162
+ def reprompt():
163
+ """Generate reprompt message if task incomplete"""
164
+ state = load_state()
165
+
166
+ if state.get('reprompt_count', 0) >= state.get('max_reprompts', 3):
167
+ # Max reprompts reached, allow exit
168
+ log_event('max_reprompts_reached', {'task': state.get('active_task')})
169
+ clear_task()
170
+ return None
171
+
172
+ state['reprompt_count'] = state.get('reprompt_count', 0) + 1
173
+ save_state(state)
174
+
175
+ task = state.get('active_task', 'current task')
176
+ count = state['reprompt_count']
177
+ max_count = state.get('max_reprompts', 3)
178
+
179
+ log_event('reprompt_generated', {'task': task, 'count': count})
180
+
181
+ return f"""
182
+ ╔══════════════════════════════════════════════════════════════════════════════╗
183
+ ║ ⚠️ RALPH WIGGUM: Completion promise not detected ({count}/{max_count}) ║
184
+ ╠══════════════════════════════════════════════════════════════════════════════╣
185
+ ║ ║
186
+ ║ Task: {task[:66]:<66} ║
187
+ ║ ║
188
+ ║ Você ainda não confirmou que a tarefa está completa. ║
189
+ ║ ║
190
+ ║ Se a tarefa está COMPLETA, responda com: ║
191
+ ║ <promise>DONE</promise> ║
192
+ ║ ║
193
+ ║ Se há mais trabalho, continue de onde parou. ║
194
+ ║ ║
195
+ ╚══════════════════════════════════════════════════════════════════════════════╝
196
+ """
197
+
198
+
199
+ def clear_task():
200
+ """Clear the current task"""
201
+ state = load_state()
202
+ if state.get('active_task'):
203
+ log_event('task_cleared', {'task': state.get('active_task')})
204
+ state['active_task'] = None
205
+ state['promise_required'] = False
206
+ state['promise_received'] = False
207
+ state['reprompt_count'] = 0
208
+ save_state(state)
209
+
210
+
211
+ def main():
212
+ """Main Ralph Wiggum logic for Stop hook"""
213
+ ensure_dirs()
214
+ state = load_state()
215
+
216
+ # If no task active, allow exit
217
+ if not state.get('active_task'):
218
+ sys.exit(0)
219
+
220
+ # If promise not required, allow exit
221
+ if not state.get('promise_required'):
222
+ sys.exit(0)
223
+
224
+ # Check if promise was given
225
+ if check_completion():
226
+ print("\n✅ Ralph Wiggum: Completion promise received. Task complete.\n")
227
+ clear_task()
228
+ sys.exit(0)
229
+
230
+ # Generate reprompt
231
+ reprompt_msg = reprompt()
232
+
233
+ if reprompt_msg:
234
+ print(reprompt_msg)
235
+ else:
236
+ # Max reprompts reached
237
+ print("\n⚠️ Ralph Wiggum: Max reprompts reached. Allowing exit.\n")
238
+
239
+ sys.exit(0)
240
+
241
+
242
+ # CLI interface for manual control
243
+ if __name__ == '__main__':
244
+ if len(sys.argv) > 1:
245
+ cmd = sys.argv[1]
246
+
247
+ if cmd == 'start' and len(sys.argv) > 2:
248
+ task = ' '.join(sys.argv[2:])
249
+ start_task(task)
250
+
251
+ elif cmd == 'check':
252
+ if check_completion():
253
+ print("✅ Task complete (promise received)")
254
+ else:
255
+ print("⏳ Task incomplete (no promise)")
256
+
257
+ elif cmd == 'clear':
258
+ clear_task()
259
+ print("🗑️ Task cleared")
260
+
261
+ elif cmd == 'status':
262
+ state = load_state()
263
+ print(json.dumps(state, indent=2))
264
+
265
+ else:
266
+ print("""
267
+ Ralph Wiggum - Completion Promise Hook
268
+
269
+ Usage:
270
+ ralph_wiggum.py # Stop hook mode
271
+ ralph_wiggum.py start TASK # Start tracking complex task
272
+ ralph_wiggum.py check # Check if promise received
273
+ ralph_wiggum.py clear # Clear current task
274
+ ralph_wiggum.py status # Show current state
275
+ """)
276
+ else:
277
+ main()