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,358 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Post Output Validator - Layer 1 do META-AGENT System v1.0
4
+
5
+ FUNÇÃO: Valida compliance do output vs especificação do agente.
6
+ AVISA sobre gaps mas NÃO BLOQUEIA entrega.
7
+
8
+ REGRA #28: META-AGENT QUALITY AWARENESS (WARN, NOT BLOCK)
9
+ """
10
+
11
+ import os
12
+ import re
13
+ import json
14
+ from pathlib import Path
15
+ from datetime import datetime
16
+ from typing import List, Dict, Optional
17
+
18
+ PROJECT_ROOT = Path(os.environ.get('CLAUDE_PROJECT_DIR', '.'))
19
+ LOGS_PATH = PROJECT_ROOT / "logs"
20
+ VALIDATION_LOG = LOGS_PATH / "output_validations.jsonl"
21
+
22
+
23
+ # ═══════════════════════════════════════════════════════════════════════════
24
+ # QUALITY MARKERS
25
+ # ═══════════════════════════════════════════════════════════════════════════
26
+
27
+ # Marcadores padrão para outputs visuais (usado por CHRONICLER e similares)
28
+ VISUAL_MARKERS = [
29
+ {
30
+ "name": "ASCII Header",
31
+ "pattern": r"╔═+.*═+╗",
32
+ "weight": 10,
33
+ "description": "Cabeçalho com bordas duplas"
34
+ },
35
+ {
36
+ "name": "Progress Bar",
37
+ "pattern": r"[█▓░]{5,}|████+",
38
+ "weight": 10,
39
+ "description": "Barras de progresso visuais"
40
+ },
41
+ {
42
+ "name": "Metrics Panel",
43
+ "pattern": r"┌─.*(?:MÉTRICA|PAINEL|MÉTRICAS)",
44
+ "weight": 10,
45
+ "description": "Painel de métricas estruturado"
46
+ },
47
+ {
48
+ "name": "Changes Section",
49
+ "pattern": r"O QUE MUDOU|NOVIDADES|MUDANÇAS",
50
+ "weight": 15,
51
+ "description": "Seção de mudanças/novidades"
52
+ },
53
+ {
54
+ "name": "Personal Notes",
55
+ "pattern": r"NOTAS DO|OBSERVAÇÕES|— \w+$",
56
+ "weight": 10,
57
+ "description": "Notas pessoais do agente"
58
+ },
59
+ {
60
+ "name": "ASCII Boxes",
61
+ "pattern": r"[┌┐└┘├┤│─┬┴┼]{3,}",
62
+ "weight": 5,
63
+ "description": "Caixas ASCII estruturadas"
64
+ },
65
+ {
66
+ "name": "Explanations",
67
+ "pattern": r"\[[^\]]{10,}\]",
68
+ "weight": 5,
69
+ "description": "Explicações entre colchetes"
70
+ },
71
+ {
72
+ "name": "Section Dividers",
73
+ "pattern": r"[═─━]{10,}",
74
+ "weight": 5,
75
+ "description": "Divisores de seção"
76
+ },
77
+ ]
78
+
79
+ # Marcadores para outputs analíticos
80
+ ANALYTICAL_MARKERS = [
81
+ {
82
+ "name": "Data Points",
83
+ "pattern": r"\d+[%,.]?\d*",
84
+ "weight": 5,
85
+ "description": "Números e porcentagens"
86
+ },
87
+ {
88
+ "name": "Bullet Points",
89
+ "pattern": r"^[\s]*[-•*]\s",
90
+ "weight": 3,
91
+ "description": "Lista com bullets"
92
+ },
93
+ {
94
+ "name": "Headers",
95
+ "pattern": r"^#{1,3}\s",
96
+ "weight": 3,
97
+ "description": "Headers markdown"
98
+ },
99
+ ]
100
+
101
+
102
+ # ═══════════════════════════════════════════════════════════════════════════
103
+ # QUALITY SCORING
104
+ # ═══════════════════════════════════════════════════════════════════════════
105
+
106
+ def calculate_quality_score(
107
+ output: str,
108
+ markers: List[Dict] = None,
109
+ agent_type: str = "visual"
110
+ ) -> Dict:
111
+ """
112
+ Calcula score de qualidade do output.
113
+
114
+ Args:
115
+ output: Texto do output a validar
116
+ markers: Lista de marcadores customizados (opcional)
117
+ agent_type: "visual" ou "analytical" para selecionar marcadores
118
+
119
+ Returns:
120
+ dict com score, passing, details, missing
121
+ """
122
+ if markers is None:
123
+ markers = VISUAL_MARKERS if agent_type == "visual" else ANALYTICAL_MARKERS
124
+
125
+ score = 0
126
+ max_score = sum(m["weight"] for m in markers)
127
+ details = []
128
+ missing = []
129
+ found = []
130
+
131
+ for marker in markers:
132
+ pattern = marker["pattern"]
133
+ weight = marker["weight"]
134
+ name = marker["name"]
135
+
136
+ if re.search(pattern, output, re.IGNORECASE | re.MULTILINE):
137
+ score += weight
138
+ details.append(f"✅ {name}: +{weight}")
139
+ found.append(name)
140
+ else:
141
+ missing.append(name)
142
+ details.append(f"❌ {name}: 0")
143
+
144
+ # Normaliza para 100
145
+ normalized_score = int((score / max_score) * 100) if max_score > 0 else 0
146
+
147
+ return {
148
+ "score": normalized_score,
149
+ "raw_score": score,
150
+ "max_score": max_score,
151
+ "passing": normalized_score >= 70,
152
+ "details": details,
153
+ "missing": missing,
154
+ "found": found,
155
+ "markers_checked": len(markers)
156
+ }
157
+
158
+
159
+ def validate_output(output: str, agent_name: str, agent_type: str = "visual") -> Dict:
160
+ """
161
+ Valida output completo. AVISA mas NÃO BLOQUEIA.
162
+
163
+ Esta é a função principal chamada após geração de output.
164
+ MODIFICAÇÃO CRÍTICA: action = "warn" em vez de "block"
165
+
166
+ Args:
167
+ output: Texto do output gerado
168
+ agent_name: Nome do agente que gerou
169
+ agent_type: Tipo do agente ("visual", "analytical")
170
+
171
+ Returns:
172
+ dict com resultado da validação
173
+ """
174
+ result = calculate_quality_score(output, agent_type=agent_type)
175
+
176
+ result["agent"] = agent_name
177
+ result["agent_type"] = agent_type
178
+ result["timestamp"] = datetime.now().isoformat()
179
+
180
+ if not result["passing"]:
181
+ # MODIFICAÇÃO: Avisa em vez de bloquear
182
+ result["warning"] = (
183
+ f"⚠️ Quality score: {result['score']}/100\n"
184
+ f"Missing elements: {', '.join(result['missing'])}\n"
185
+ f"Consider adding these elements for better quality."
186
+ )
187
+ result["action"] = "warn" # NÃO "block"
188
+ result["recommendation"] = "Output delivered with quality warning"
189
+ else:
190
+ result["action"] = "pass"
191
+ result["recommendation"] = "Output quality acceptable"
192
+
193
+ # Log validation
194
+ log_validation(result)
195
+
196
+ return result
197
+
198
+
199
+ def validate_against_spec(output: str, spec: str, agent_name: str) -> Dict:
200
+ """
201
+ Valida output contra especificação customizada.
202
+
203
+ Para casos onde MANDATORY_SECTIONS define requisitos específicos.
204
+ """
205
+ result = {
206
+ "agent": agent_name,
207
+ "timestamp": datetime.now().isoformat(),
208
+ "spec_based": True,
209
+ "requirements_met": [],
210
+ "requirements_missing": []
211
+ }
212
+
213
+ # Extrai requisitos da spec
214
+ requirements = extract_requirements_from_spec(spec)
215
+
216
+ score = 0
217
+ for req in requirements:
218
+ if re.search(req["pattern"], output, re.IGNORECASE | re.DOTALL):
219
+ result["requirements_met"].append(req["name"])
220
+ score += req.get("weight", 10)
221
+ else:
222
+ result["requirements_missing"].append(req["name"])
223
+
224
+ max_score = sum(r.get("weight", 10) for r in requirements)
225
+ result["score"] = int((score / max_score) * 100) if max_score > 0 else 100
226
+ result["passing"] = result["score"] >= 70
227
+
228
+ if not result["passing"]:
229
+ result["action"] = "warn"
230
+ result["warning"] = f"Score: {result['score']}. Missing: {result['requirements_missing']}"
231
+ else:
232
+ result["action"] = "pass"
233
+
234
+ return result
235
+
236
+
237
+ def extract_requirements_from_spec(spec: str) -> List[Dict]:
238
+ """
239
+ Extrai requisitos de uma spec MANDATORY_SECTIONS.
240
+
241
+ Formato esperado na spec:
242
+ | Section | Required | Marker | Example |
243
+ """
244
+ requirements = []
245
+
246
+ # Tenta extrair da tabela markdown
247
+ table_pattern = r'\|\s*([^|]+)\s*\|\s*YES\s*\|\s*`([^`]+)`\s*\|'
248
+ matches = re.findall(table_pattern, spec, re.IGNORECASE)
249
+
250
+ for name, marker in matches:
251
+ requirements.append({
252
+ "name": name.strip(),
253
+ "pattern": re.escape(marker.strip()),
254
+ "weight": 10
255
+ })
256
+
257
+ # Se não encontrou tabela, usa marcadores padrão
258
+ if not requirements:
259
+ return [{"name": "default", "pattern": ".", "weight": 100}]
260
+
261
+ return requirements
262
+
263
+
264
+ # ═══════════════════════════════════════════════════════════════════════════
265
+ # LOGGING
266
+ # ═══════════════════════════════════════════════════════════════════════════
267
+
268
+ def log_validation(result: Dict):
269
+ """Loga resultado da validação."""
270
+ VALIDATION_LOG.parent.mkdir(parents=True, exist_ok=True)
271
+
272
+ entry = {
273
+ "timestamp": result.get("timestamp", datetime.now().isoformat()),
274
+ "agent": result.get("agent", "unknown"),
275
+ "score": result.get("score", 0),
276
+ "passing": result.get("passing", False),
277
+ "action": result.get("action", "unknown"),
278
+ "missing": result.get("missing", []),
279
+ "found": result.get("found", [])
280
+ }
281
+
282
+ try:
283
+ with open(VALIDATION_LOG, "a", encoding='utf-8') as f:
284
+ f.write(json.dumps(entry, ensure_ascii=False) + "\n")
285
+ except Exception:
286
+ pass # Falha silenciosa
287
+
288
+
289
+ # ═══════════════════════════════════════════════════════════════════════════
290
+ # INTEGRATION HELPERS
291
+ # ═══════════════════════════════════════════════════════════════════════════
292
+
293
+ def should_trigger_doctor(result: Dict, threshold: int = 50) -> bool:
294
+ """
295
+ Determina se deve acionar o DOCTOR (Layer 2) para propor fixes.
296
+
297
+ Threshold mais baixo (50) aciona propostas de melhoria.
298
+ Threshold 70 é apenas warning.
299
+ """
300
+ return result.get("score", 100) < threshold
301
+
302
+
303
+ def format_warning_message(result: Dict) -> str:
304
+ """Formata mensagem de warning para exibição."""
305
+ if result.get("action") == "pass":
306
+ return ""
307
+
308
+ return f"""
309
+ ┌─────────────────────────────────────────────────────────────────────┐
310
+ │ ⚠️ QUALITY WARNING │
311
+ ├─────────────────────────────────────────────────────────────────────┤
312
+ │ Agent: {result.get('agent', 'unknown'):<54} │
313
+ │ Score: {result.get('score', 0)}/100 {'(PASSING)' if result.get('passing') else '(BELOW THRESHOLD)':>43} │
314
+ ├─────────────────────────────────────────────────────────────────────┤
315
+ │ Missing: {', '.join(result.get('missing', []))[:53]:<53} │
316
+ └─────────────────────────────────────────────────────────────────────┘
317
+ """
318
+
319
+
320
+ # ═══════════════════════════════════════════════════════════════════════════
321
+ # CLI INTERFACE
322
+ # ═══════════════════════════════════════════════════════════════════════════
323
+
324
+ if __name__ == "__main__":
325
+ # Test output
326
+ test_output = """
327
+ ╔═══════════════════════════════════════════════════════════════════════════════╗
328
+ ║ ALEX HORMOZI - DNA CONSOLIDADO ║
329
+ ╚═══════════════════════════════════════════════════════════════════════════════╝
330
+
331
+ ┌─ MÉTRICAS ─────────────────────────────────────────────────────────────────────┐
332
+ │ Total elementos: 260 │
333
+ │ Progresso: ████████████████████░░░░░░░░░░░░░░░░░░░░ 50% │
334
+ └────────────────────────────────────────────────────────────────────────────────┘
335
+
336
+ O QUE MUDOU DESDE O ÚLTIMO LOG:
337
+ - Adicionados 30 novos frameworks
338
+ - Atualizado DNA-CONFIG.yaml
339
+
340
+ NOTAS DO CHRONICLER:
341
+ "O conhecimento do Hormozi está consolidando bem."
342
+
343
+ — Chronicler
344
+ """
345
+
346
+ result = validate_output(test_output, "chronicler", "visual")
347
+
348
+ print(f"Score: {result['score']}/100")
349
+ print(f"Passing: {result['passing']}")
350
+ print(f"Action: {result['action']}")
351
+ print(f"\nDetails:")
352
+ for detail in result['details']:
353
+ print(f" {detail}")
354
+
355
+ if result.get('warning'):
356
+ print(f"\n{result['warning']}")
357
+
358
+ print(format_warning_message(result))
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ JARVIS Post Tool Use Hook
4
+ Executado após Claude Code usar uma ferramenta de edição/escrita.
5
+
6
+ Responsabilidades:
7
+ 1. Registrar arquivos modificados
8
+ 2. Detectar padrões
9
+ 3. Sugerir melhorias quando apropriado
10
+ """
11
+
12
+ import json
13
+ import sys
14
+ import os
15
+ from datetime import datetime
16
+ from pathlib import Path
17
+
18
+ def get_project_dir():
19
+ """Obtém o diretório do projeto."""
20
+ return os.environ.get('CLAUDE_PROJECT_DIR', os.getcwd())
21
+
22
+ def load_actions_log():
23
+ """Carrega log de ações."""
24
+ project_dir = get_project_dir()
25
+ log_path = Path(project_dir) / 'logs' / 'actions.json'
26
+
27
+ if log_path.exists():
28
+ with open(log_path, 'r', encoding='utf-8') as f:
29
+ return json.load(f)
30
+ return {'actions': []}
31
+
32
+ def save_actions_log(log):
33
+ """Salva log de ações."""
34
+ project_dir = get_project_dir()
35
+ log_path = Path(project_dir) / 'logs' / 'actions.json'
36
+ log_path.parent.mkdir(parents=True, exist_ok=True)
37
+
38
+ # Manter apenas últimas 100 ações
39
+ log['actions'] = log['actions'][-100:]
40
+
41
+ with open(log_path, 'w', encoding='utf-8') as f:
42
+ json.dump(log, f, indent=2, ensure_ascii=False)
43
+
44
+ def detect_patterns(actions):
45
+ """Detecta padrões nas ações recentes."""
46
+ if len(actions) < 3:
47
+ return None
48
+
49
+ # Verificar se mesmo arquivo foi editado múltiplas vezes
50
+ recent = actions[-10:]
51
+ file_counts = {}
52
+ for action in recent:
53
+ file_path = action.get('file_path', '')
54
+ if file_path:
55
+ file_counts[file_path] = file_counts.get(file_path, 0) + 1
56
+
57
+ # Se algum arquivo foi editado 3+ vezes
58
+ repeated = [f for f, c in file_counts.items() if c >= 3]
59
+ if repeated:
60
+ return {
61
+ 'type': 'repeated_edits',
62
+ 'files': repeated,
63
+ 'suggestion': 'Arquivo editado múltiplas vezes. Considerar refatoração.'
64
+ }
65
+
66
+ return None
67
+
68
+ def main():
69
+ """Função principal do hook."""
70
+ try:
71
+ # Ler input do hook (stdin)
72
+ input_data = sys.stdin.read()
73
+ hook_input = json.loads(input_data) if input_data else {}
74
+
75
+ # Extrair informações da ferramenta
76
+ tool_name = hook_input.get('tool_name', 'unknown')
77
+ tool_input = hook_input.get('tool_input', {})
78
+
79
+ file_path = tool_input.get('file_path', '')
80
+
81
+ # Carregar log
82
+ log = load_actions_log()
83
+
84
+ # Registrar ação
85
+ action = {
86
+ 'timestamp': datetime.now().isoformat(),
87
+ 'tool': tool_name,
88
+ 'file_path': file_path,
89
+ 'session_id': hook_input.get('session_id', 'unknown')
90
+ }
91
+ log['actions'].append(action)
92
+
93
+ # Salvar log
94
+ save_actions_log(log)
95
+
96
+ # Detectar padrões
97
+ pattern = detect_patterns(log['actions'])
98
+
99
+ # Preparar feedback
100
+ feedback = None
101
+ if pattern:
102
+ feedback = f"[JARVIS] Padrão detectado: {pattern['suggestion']}"
103
+
104
+ output = {
105
+ 'continue': True,
106
+ 'feedback': feedback
107
+ }
108
+
109
+ print(json.dumps(output))
110
+
111
+ except Exception as e:
112
+ # Em caso de erro, não bloquear a operação
113
+ error_output = {
114
+ 'continue': True,
115
+ 'feedback': None
116
+ }
117
+ print(json.dumps(error_output))
118
+
119
+ if __name__ == '__main__':
120
+ main()
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ POST-WRITE VALIDATOR HOOK
4
+ =========================
5
+ Valida automaticamente arquivos criados/editados.
6
+
7
+ Baseado no workflow Boris Cherny: "give Claude a way to verify its work"
8
+
9
+ Triggers:
10
+ - Após Write de BATCH-*.md → Valida estrutura do batch
11
+ - Após Write de AGENT.md → Valida template V3
12
+ - Após Write de SOUL.md → Valida rastreabilidade
13
+ - Após Write de DNA-CONFIG.yaml → Valida estrutura
14
+
15
+ Output:
16
+ - Se válido: exit 0 (silencioso)
17
+ - Se inválido: print erros para Claude corrigir
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
+ # Paths
28
+ PROJECT_ROOT = Path(os.environ.get('CLAUDE_PROJECT_DIR', '.'))
29
+ LOGS_PATH = PROJECT_ROOT / 'logs' / 'validation'
30
+ LOGS_PATH.mkdir(parents=True, exist_ok=True)
31
+
32
+ def log_validation(file_path: str, file_type: str, is_valid: bool, errors: list):
33
+ """Log validation result"""
34
+ log_file = LOGS_PATH / 'validation.jsonl'
35
+ entry = {
36
+ 'timestamp': datetime.now().isoformat(),
37
+ 'file': file_path,
38
+ 'type': file_type,
39
+ 'valid': is_valid,
40
+ 'errors': errors
41
+ }
42
+ with open(log_file, 'a') as f:
43
+ f.write(json.dumps(entry) + '\n')
44
+
45
+ def validate_batch(content: str, file_path: str) -> tuple[bool, list]:
46
+ """Validate BATCH-*.md structure"""
47
+ errors = []
48
+
49
+ # Required sections
50
+ required_sections = [
51
+ ('ASCII ART HEADER', r'[╔═╗║╚]'),
52
+ ('CONTEXTO DA MISSÃO', r'CONTEXTO DA MISS[ÃA]O|MISSION CONTEXT'),
53
+ ('BATCH SUMMARY', r'BATCH SUMMARY|RESUMO DO BATCH'),
54
+ ('ARQUIVOS PROCESSADOS', r'ARQUIVOS PROCESSADOS|FILES PROCESSED'),
55
+ ('DESTINO DO CONHECIMENTO', r'DESTINO DO CONHECIMENTO|KNOWLEDGE DESTINATION'),
56
+ ('KEY FRAMEWORKS', r'KEY FRAMEWORKS|FRAMEWORKS'),
57
+ ]
58
+
59
+ for section_name, pattern in required_sections:
60
+ if not re.search(pattern, content, re.IGNORECASE):
61
+ errors.append(f"Missing section: {section_name}")
62
+
63
+ # Check for cascading section (REGRA #22)
64
+ if 'Cascateamento Executado' not in content and 'CASCATEAMENTO' not in content.upper():
65
+ errors.append("Missing section: Cascateamento Executado (REGRA #22)")
66
+
67
+ # Check for DNA layers
68
+ dna_layers = ['FILOSOFIA', 'MODELO-MENTAL', 'HEURISTICA', 'FRAMEWORK', 'METODOLOGIA']
69
+ found_layers = sum(1 for layer in dna_layers if layer in content.upper())
70
+ if found_layers < 3:
71
+ errors.append(f"Only {found_layers}/5 DNA layers found. Expected at least 3.")
72
+
73
+ is_valid = len(errors) == 0
74
+ log_validation(file_path, 'BATCH', is_valid, errors)
75
+ return is_valid, errors
76
+
77
+ def validate_agent(content: str, file_path: str) -> tuple[bool, list]:
78
+ """Validate AGENT.md template V3 structure"""
79
+ errors = []
80
+
81
+ # Required parts from Template V3
82
+ required_parts = [
83
+ ('PARTE 0: ÍNDICE', r'PARTE 0|ÍNDICE|INDEX'),
84
+ ('PARTE 1: COMPOSIÇÃO', r'PARTE 1|COMPOSI[ÇC][ÃA]O'),
85
+ ('PARTE 3: MAPA NEURAL', r'PARTE 3|MAPA NEURAL|DNA'),
86
+ ('PARTE 5: SISTEMA DE VOZ', r'PARTE 5|VOZ|VOICE'),
87
+ ]
88
+
89
+ for part_name, pattern in required_parts:
90
+ if not re.search(pattern, content, re.IGNORECASE):
91
+ errors.append(f"Missing: {part_name}")
92
+
93
+ # Check for ASCII header
94
+ if not re.search(r'[╔═╗║╚]', content):
95
+ errors.append("Missing ASCII art header")
96
+
97
+ # Check for version
98
+ if not re.search(r'[Vv]ers[ãa]o|Version', content):
99
+ errors.append("Missing version declaration")
100
+
101
+ # Check for sources/fontes
102
+ if not re.search(r'[Ff]ontes?|[Ss]ources?', content):
103
+ errors.append("Missing source attribution")
104
+
105
+ is_valid = len(errors) == 0
106
+ log_validation(file_path, 'AGENT', is_valid, errors)
107
+ return is_valid, errors
108
+
109
+ def validate_soul(content: str, file_path: str) -> tuple[bool, list]:
110
+ """Validate SOUL.md rastreabilidade"""
111
+ errors = []
112
+
113
+ # Check for source citations
114
+ citation_patterns = [
115
+ r'\^\[FONTE:',
116
+ r'\^\[chunk_id',
117
+ r'\^\[insight_id',
118
+ r'\^\[RAIZ:',
119
+ r'\[FONTE:',
120
+ ]
121
+
122
+ has_citations = any(re.search(p, content) for p in citation_patterns)
123
+ if not has_citations:
124
+ errors.append("No traceable citations found (REGRA #24 requires ^[FONTE:] or similar)")
125
+
126
+ # Check for DNA layers
127
+ if not re.search(r'FILOSOFIA|MODELO.MENTAL|HEURISTICA|FRAMEWORK|METODOLOGIA', content, re.IGNORECASE):
128
+ errors.append("No DNA layers referenced")
129
+
130
+ is_valid = len(errors) == 0
131
+ log_validation(file_path, 'SOUL', is_valid, errors)
132
+ return is_valid, errors
133
+
134
+ def validate_dna_config(content: str, file_path: str) -> tuple[bool, list]:
135
+ """Validate DNA-CONFIG.yaml structure"""
136
+ errors = []
137
+
138
+ # Required fields
139
+ required_fields = ['name', 'type', 'version']
140
+ for field in required_fields:
141
+ if f'{field}:' not in content.lower():
142
+ errors.append(f"Missing required field: {field}")
143
+
144
+ # Check for layers
145
+ layers = ['filosofias', 'modelos_mentais', 'heuristicas', 'frameworks', 'metodologias']
146
+ found_layers = sum(1 for layer in layers if layer in content.lower())
147
+ if found_layers < 3:
148
+ errors.append(f"Only {found_layers}/5 DNA layers defined")
149
+
150
+ is_valid = len(errors) == 0
151
+ log_validation(file_path, 'DNA_CONFIG', is_valid, errors)
152
+ return is_valid, errors
153
+
154
+ def main():
155
+ """Main validation dispatcher"""
156
+ if len(sys.argv) < 2:
157
+ sys.exit(0)
158
+
159
+ file_path = sys.argv[1]
160
+
161
+ # Skip if file doesn't exist or is not relevant
162
+ if not os.path.exists(file_path):
163
+ sys.exit(0)
164
+
165
+ filename = os.path.basename(file_path).upper()
166
+
167
+ # Determine file type and validate
168
+ try:
169
+ with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
170
+ content = f.read()
171
+ except Exception:
172
+ sys.exit(0)
173
+
174
+ is_valid = True
175
+ errors = []
176
+
177
+ if 'BATCH-' in filename and filename.endswith('.MD'):
178
+ is_valid, errors = validate_batch(content, file_path)
179
+ elif filename == 'AGENT.MD':
180
+ is_valid, errors = validate_agent(content, file_path)
181
+ elif filename == 'SOUL.MD':
182
+ is_valid, errors = validate_soul(content, file_path)
183
+ elif 'DNA-CONFIG' in filename and filename.endswith('.YAML'):
184
+ is_valid, errors = validate_dna_config(content, file_path)
185
+ else:
186
+ # Not a file we validate
187
+ sys.exit(0)
188
+
189
+ # Output for Claude to see
190
+ if not is_valid:
191
+ print(f"\n⚠️ VALIDATION FAILED for {os.path.basename(file_path)}:")
192
+ for error in errors:
193
+ print(f" ❌ {error}")
194
+ print("\nPlease fix these issues before proceeding.\n")
195
+ # Exit 0 anyway to not block, but Claude sees the output
196
+
197
+ sys.exit(0)
198
+
199
+ if __name__ == '__main__':
200
+ main()