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,220 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ ENFORCE PLAN MODE HOOK v1.0.0
4
+ =============================
5
+
6
+ Hook: UserPromptSubmit
7
+ Propósito: Detecta quando o usuário solicita modificação de arquivos e
8
+ avisa se Plan Mode não foi ativado.
9
+
10
+ REGRA #13: PLAN MODE OBRIGATÓRIO PARA MODIFICAÇÃO DE ARQUIVOS
11
+ REGRA #29: WARN, NOT BLOCK (avisa, não bloqueia)
12
+
13
+ Criado: 2026-01-14
14
+ Autor: JARVIS
15
+ """
16
+
17
+ import json
18
+ import sys
19
+ import re
20
+ from datetime import datetime
21
+ from pathlib import Path
22
+
23
+ # Keywords que indicam intenção de modificar arquivos
24
+ MODIFYING_KEYWORDS = [
25
+ # Português
26
+ "criar", "crie", "criando", "criação",
27
+ "atualizar", "atualize", "atualizando", "atualização",
28
+ "modificar", "modifique", "modificando", "modificação",
29
+ "implementar", "implemente", "implementando", "implementação",
30
+ "adicionar", "adicione", "adicionando", "adição",
31
+ "remover", "remova", "removendo", "remoção",
32
+ "deletar", "delete", "deletando",
33
+ "refatorar", "refatore", "refatorando", "refatoração",
34
+ "corrigir", "corrija", "corrigindo", "correção",
35
+ "fix", "fixing", "fixed",
36
+ "editar", "edite", "editando", "edição",
37
+ "escrever", "escreva", "escrevendo",
38
+ "gerar", "gere", "gerando", "geração",
39
+ "mudar", "mude", "mudando", "mudança",
40
+
41
+ # Inglês
42
+ "create", "creating", "creation",
43
+ "update", "updating",
44
+ "modify", "modifying", "modification",
45
+ "implement", "implementing", "implementation",
46
+ "add", "adding",
47
+ "remove", "removing", "removal",
48
+ "delete", "deleting", "deletion",
49
+ "refactor", "refactoring",
50
+ "edit", "editing",
51
+ "write", "writing",
52
+ "generate", "generating",
53
+ "change", "changing",
54
+
55
+ # Comandos específicos
56
+ "novo arquivo", "new file",
57
+ "nova feature", "new feature",
58
+ "novo hook", "new hook",
59
+ "nova skill", "new skill",
60
+ "novo agente", "new agent",
61
+ "bug fix", "bugfix",
62
+ ]
63
+
64
+ # Keywords que indicam exceções (não precisa Plan Mode)
65
+ EXCEPTION_KEYWORDS = [
66
+ # Leitura/consulta
67
+ "mostrar", "show", "exibir", "display",
68
+ "ler", "read", "leia",
69
+ "buscar", "search", "find", "procurar",
70
+ "verificar", "check", "verify",
71
+ "status", "estado",
72
+ "listar", "list",
73
+ "onde estamos", "where are we",
74
+ "o que é", "what is",
75
+ "como funciona", "how does",
76
+ "explique", "explain",
77
+ "descreva", "describe",
78
+
79
+ # Comandos slash (já são skills)
80
+ "/jarvis", "/status", "/save", "/resume",
81
+ "/conclave", "/verify", "/config",
82
+ ]
83
+
84
+ # Log file
85
+ LOG_FILE = Path(__file__).parent.parent / "mission-control" / "plan_mode_warnings.jsonl"
86
+
87
+
88
+ def check_plan_mode_required(prompt: str) -> dict:
89
+ """
90
+ Analisa o prompt para determinar se Plan Mode é necessário.
91
+
92
+ Returns:
93
+ dict com:
94
+ - required: bool (se Plan Mode é necessário)
95
+ - keywords_found: list (keywords de modificação encontradas)
96
+ - exception_found: str|None (exceção que foi encontrada)
97
+ - confidence: str (HIGH, MEDIUM, LOW)
98
+ """
99
+ prompt_lower = prompt.lower()
100
+
101
+ # Verificar exceções primeiro
102
+ for exc in EXCEPTION_KEYWORDS:
103
+ if exc in prompt_lower:
104
+ return {
105
+ "required": False,
106
+ "keywords_found": [],
107
+ "exception_found": exc,
108
+ "confidence": "HIGH"
109
+ }
110
+
111
+ # Verificar keywords de modificação
112
+ found_keywords = []
113
+ for kw in MODIFYING_KEYWORDS:
114
+ # Usar word boundary para evitar falsos positivos
115
+ pattern = r'\b' + re.escape(kw) + r'\b'
116
+ if re.search(pattern, prompt_lower):
117
+ found_keywords.append(kw)
118
+
119
+ if not found_keywords:
120
+ return {
121
+ "required": False,
122
+ "keywords_found": [],
123
+ "exception_found": None,
124
+ "confidence": "HIGH"
125
+ }
126
+
127
+ # Determinar confiança baseado em quantidade de keywords
128
+ if len(found_keywords) >= 3:
129
+ confidence = "HIGH"
130
+ elif len(found_keywords) >= 2:
131
+ confidence = "MEDIUM"
132
+ else:
133
+ confidence = "LOW"
134
+
135
+ return {
136
+ "required": True,
137
+ "keywords_found": found_keywords,
138
+ "exception_found": None,
139
+ "confidence": confidence
140
+ }
141
+
142
+
143
+ def log_warning(prompt: str, analysis: dict):
144
+ """Loga warning para auditoria."""
145
+ try:
146
+ LOG_FILE.parent.mkdir(parents=True, exist_ok=True)
147
+
148
+ entry = {
149
+ "timestamp": datetime.now().isoformat(),
150
+ "hook": "enforce_plan_mode",
151
+ "prompt_preview": prompt[:200] + "..." if len(prompt) > 200 else prompt,
152
+ "keywords_found": analysis["keywords_found"],
153
+ "confidence": analysis["confidence"],
154
+ "action": "WARNING_ISSUED"
155
+ }
156
+
157
+ with open(LOG_FILE, "a", encoding="utf-8") as f:
158
+ f.write(json.dumps(entry, ensure_ascii=False) + "\n")
159
+ except Exception:
160
+ # Não falhar por erro de log
161
+ pass
162
+
163
+
164
+ def main():
165
+ try:
166
+ # Ler input do hook
167
+ input_data = json.loads(sys.stdin.read())
168
+
169
+ # Extrair prompt do usuário
170
+ prompt = input_data.get("prompt", "")
171
+
172
+ if not prompt:
173
+ # Sem prompt, não há o que analisar
174
+ print(json.dumps({"continue": True}))
175
+ sys.exit(0)
176
+
177
+ # Analisar se Plan Mode é necessário
178
+ analysis = check_plan_mode_required(prompt)
179
+
180
+ if not analysis["required"]:
181
+ # Não precisa de Plan Mode
182
+ print(json.dumps({"continue": True}))
183
+ sys.exit(0)
184
+
185
+ # Plan Mode é necessário - emitir WARNING (não bloquear)
186
+ # REGRA #29: WARN, NOT BLOCK
187
+
188
+ log_warning(prompt, analysis)
189
+
190
+ # Construir mensagem de aviso
191
+ warning_msg = (
192
+ f"[PLAN MODE WARNING] Detectada intenção de modificação de arquivos. "
193
+ f"Keywords: {', '.join(analysis['keywords_found'][:5])}. "
194
+ f"Confiança: {analysis['confidence']}. "
195
+ f"REGRA #13 recomenda Plan Mode para modificações. "
196
+ f"Use Shift+Tab 2x para ativar ou digite 'plan mode'."
197
+ )
198
+
199
+ # Retornar com aviso (não bloqueia - exit 0)
200
+ print(json.dumps({
201
+ "continue": True,
202
+ "feedback": warning_msg
203
+ }))
204
+ sys.exit(0)
205
+
206
+ except json.JSONDecodeError:
207
+ # Input inválido - continuar silenciosamente
208
+ print(json.dumps({"continue": True}))
209
+ sys.exit(0)
210
+ except Exception as e:
211
+ # Erro inesperado - logar e continuar (não bloquear)
212
+ print(json.dumps({
213
+ "continue": True,
214
+ "warning": f"enforce_plan_mode hook error: {str(e)}"
215
+ }))
216
+ sys.exit(0) # Don't block on internal errors
217
+
218
+
219
+ if __name__ == "__main__":
220
+ main()
@@ -0,0 +1,367 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ INBOX AGE ALERT HOOK - REGRA #7 ENFORCEMENT
4
+ ============================================
5
+
6
+ Alerta sobre arquivos antigos no INBOX no inicio de cada sessao.
7
+
8
+ REGRA #7: INBOX E TEMPORARIO
9
+ - NAO PODE deixar arquivos no INBOX indefinidamente
10
+ - NAO PODE mover para INBOX sem plano de organizacao
11
+ - DEVE organizar cada arquivo que entra no INBOX
12
+
13
+ Este hook:
14
+ 1. Executa no inicio de cada sessao (session_start hook)
15
+ 2. Verifica arquivos no INBOX com mais de 3 dias
16
+ 3. Se encontrar, gera alerta formatado para o JARVIS exibir
17
+ 4. Loga em /logs/inbox_alerts.jsonl
18
+
19
+ Autor: JARVIS Autonomous System
20
+ Data: 2026-01-11
21
+ """
22
+
23
+ import os
24
+ import json
25
+ import sys
26
+ from pathlib import Path
27
+ from datetime import datetime, timedelta
28
+ from typing import List, Dict, Optional
29
+
30
+ # ==============================================================================
31
+ # CONFIGURACAO
32
+ # ==============================================================================
33
+
34
+ PROJECT_ROOT = Path(os.environ.get('CLAUDE_PROJECT_DIR', '.'))
35
+ INBOX_PATH = PROJECT_ROOT / "inbox"
36
+ MAX_AGE_DAYS = 3
37
+ ALERT_LOG = PROJECT_ROOT / "logs" / "inbox_alerts.jsonl"
38
+
39
+ # Extensoes de arquivos para monitorar
40
+ MONITORED_EXTENSIONS = {".txt", ".md", ".docx", ".pdf", ".json", ".yaml", ".yml"}
41
+
42
+ # Pastas/prefixos a ignorar
43
+ IGNORE_PREFIXES = {"_", ".", "__"}
44
+ IGNORE_FOLDERS = {"_BACKUP", "_OLD", "_ARCHIVE", "__pycache__"}
45
+
46
+
47
+ # ==============================================================================
48
+ # FUNCOES PRINCIPAIS
49
+ # ==============================================================================
50
+
51
+
52
+ def get_old_files(max_age_days: int = MAX_AGE_DAYS) -> List[Dict]:
53
+ """
54
+ Retorna lista de arquivos mais velhos que max_age_days.
55
+
56
+ Args:
57
+ max_age_days: Numero maximo de dias que um arquivo pode ficar no INBOX
58
+
59
+ Returns:
60
+ Lista de dicts com informacoes dos arquivos antigos
61
+ """
62
+ old_files = []
63
+ cutoff = datetime.now() - timedelta(days=max_age_days)
64
+
65
+ if not INBOX_PATH.exists():
66
+ return []
67
+
68
+ for root, dirs, files in os.walk(INBOX_PATH):
69
+ # Ignorar pastas de backup e ocultas
70
+ dirs[:] = [
71
+ d
72
+ for d in dirs
73
+ if not any(d.startswith(p) for p in IGNORE_PREFIXES)
74
+ and d not in IGNORE_FOLDERS
75
+ ]
76
+
77
+ for f in files:
78
+ # Ignorar arquivos ocultos
79
+ if any(f.startswith(p) for p in IGNORE_PREFIXES):
80
+ continue
81
+
82
+ # Verificar extensao
83
+ ext = Path(f).suffix.lower()
84
+ if ext not in MONITORED_EXTENSIONS:
85
+ continue
86
+
87
+ try:
88
+ fpath = Path(root) / f
89
+ mtime = datetime.fromtimestamp(fpath.stat().st_mtime)
90
+
91
+ if mtime < cutoff:
92
+ # Calcular caminho relativo ao INBOX
93
+ rel_path = fpath.relative_to(INBOX_PATH)
94
+ folder = rel_path.parent if rel_path.parent != Path(".") else "ROOT"
95
+
96
+ old_files.append(
97
+ {
98
+ "path": str(fpath),
99
+ "relative_path": str(rel_path),
100
+ "name": f,
101
+ "age_days": (datetime.now() - mtime).days,
102
+ "folder": str(folder),
103
+ "size_kb": round(fpath.stat().st_size / 1024, 2),
104
+ "modified_at": mtime.isoformat(),
105
+ }
106
+ )
107
+ except (OSError, PermissionError) as e:
108
+ # Ignorar arquivos inacessiveis
109
+ continue
110
+
111
+ return sorted(old_files, key=lambda x: x["age_days"], reverse=True)
112
+
113
+
114
+ def count_by_folder(old_files: List[Dict]) -> Dict[str, int]:
115
+ """Agrupa arquivos antigos por pasta."""
116
+ folder_counts = {}
117
+ for f in old_files:
118
+ folder = f["folder"]
119
+ folder_counts[folder] = folder_counts.get(folder, 0) + 1
120
+ return dict(sorted(folder_counts.items(), key=lambda x: x[1], reverse=True))
121
+
122
+
123
+ def generate_alert(old_files: List[Dict]) -> str:
124
+ """
125
+ Gera mensagem de alerta formatada no estilo JARVIS.
126
+
127
+ Args:
128
+ old_files: Lista de arquivos antigos
129
+
130
+ Returns:
131
+ String formatada com o alerta
132
+ """
133
+ if not old_files:
134
+ return ""
135
+
136
+ folder_counts = count_by_folder(old_files)
137
+ total_size = sum(f["size_kb"] for f in old_files)
138
+
139
+ # Construir alerta visual
140
+ alert = f"""
141
+ +==============================================================================+
142
+ | REGRA #7 ALERTA - INBOX TEMPORARIO |
143
+ +==============================================================================+
144
+
145
+ ATENCAO, senhor. {len(old_files)} arquivo(s) no INBOX com mais de {MAX_AGE_DAYS} dias.
146
+
147
+ +------------------------------------------------------------------------------+
148
+ | METRICAS |
149
+ +------------------------------------------------------------------------------+
150
+ | Total de arquivos antigos: {len(old_files):>4} |
151
+ | Tamanho total: {total_size:>8.1f} KB |
152
+ | Arquivo mais antigo: {old_files[0]["age_days"]:>4} dias |
153
+ +------------------------------------------------------------------------------+
154
+
155
+ +------------------------------------------------------------------------------+
156
+ | POR PASTA |
157
+ +------------------------------------------------------------------------------+
158
+ """
159
+
160
+ for folder, count in list(folder_counts.items())[:8]:
161
+ folder_display = folder[:40] if len(folder) <= 40 else folder[:37] + "..."
162
+ alert += f"| {folder_display:<42} {count:>3} arquivo(s) |\n"
163
+
164
+ if len(folder_counts) > 8:
165
+ alert += f"| ... e mais {len(folder_counts) - 8} pastas |\n"
166
+
167
+ alert += """+------------------------------------------------------------------------------+
168
+
169
+ +------------------------------------------------------------------------------+
170
+ | ARQUIVOS MAIS ANTIGOS |
171
+ +------------------------------------------------------------------------------+
172
+ """
173
+
174
+ for f in old_files[:10]:
175
+ name_display = (
176
+ f["name"][:50] if len(f["name"]) <= 50 else f["name"][:47] + "..."
177
+ )
178
+ alert += f"| [{f['age_days']:>3}d] {name_display:<50} |\n"
179
+
180
+ if len(old_files) > 10:
181
+ alert += f"| ... e mais {len(old_files) - 10} arquivos |\n"
182
+
183
+ alert += """+------------------------------------------------------------------------------+
184
+
185
+ +------------------------------------------------------------------------------+
186
+ | ACAO RECOMENDADA |
187
+ +------------------------------------------------------------------------------+
188
+ | Executar: python3 SCRIPTS/organize_inbox_to_knowledge.py --execute |
189
+ | Ou: /inbox para ver lista completa |
190
+ +------------------------------------------------------------------------------+
191
+
192
+ REGRA #7: INBOX E TEMPORARIO - Organizar, nao acumular.
193
+ """
194
+
195
+ return alert
196
+
197
+
198
+ def generate_summary(old_files: List[Dict]) -> str:
199
+ """Gera resumo curto para o contexto do JARVIS."""
200
+ if not old_files:
201
+ return ""
202
+
203
+ return f"REGRA #7: {len(old_files)} arquivo(s) antigos no INBOX (>{MAX_AGE_DAYS} dias). Mais antigo: {old_files[0]['age_days']} dias."
204
+
205
+
206
+ def log_alert(old_files: List[Dict]) -> bool:
207
+ """
208
+ Loga alerta em jsonl para historico.
209
+
210
+ Args:
211
+ old_files: Lista de arquivos antigos
212
+
213
+ Returns:
214
+ True se logou com sucesso
215
+ """
216
+ try:
217
+ # Garantir que diretorio existe
218
+ ALERT_LOG.parent.mkdir(parents=True, exist_ok=True)
219
+
220
+ log_entry = {
221
+ "timestamp": datetime.now().isoformat(),
222
+ "alert_type": "inbox_age",
223
+ "rule": "REGRA_7",
224
+ "total_files": len(old_files),
225
+ "max_age_days_threshold": MAX_AGE_DAYS,
226
+ "oldest_file_days": old_files[0]["age_days"] if old_files else 0,
227
+ "folders_affected": count_by_folder(old_files),
228
+ "files": old_files[:20], # Limitar a 20 arquivos no log
229
+ "action_suggested": "python3 SCRIPTS/organize_inbox_to_knowledge.py --execute",
230
+ }
231
+
232
+ with open(ALERT_LOG, "a", encoding="utf-8") as f:
233
+ f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")
234
+
235
+ return True
236
+
237
+ except Exception as e:
238
+ # Nao bloquear execucao por falha de log
239
+ sys.stderr.write(f"[INBOX_ALERT] Erro ao logar: {e}\n")
240
+ return False
241
+
242
+
243
+ def check_inbox_health() -> Dict:
244
+ """
245
+ Verifica saude geral do INBOX.
246
+
247
+ Returns:
248
+ Dict com metricas de saude
249
+ """
250
+ if not INBOX_PATH.exists():
251
+ return {"status": "error", "message": "INBOX path not found"}
252
+
253
+ total_files = 0
254
+ total_size = 0
255
+
256
+ for root, dirs, files in os.walk(INBOX_PATH):
257
+ # Ignorar pastas de backup
258
+ dirs[:] = [
259
+ d
260
+ for d in dirs
261
+ if not any(d.startswith(p) for p in IGNORE_PREFIXES)
262
+ and d not in IGNORE_FOLDERS
263
+ ]
264
+
265
+ for f in files:
266
+ if any(f.startswith(p) for p in IGNORE_PREFIXES):
267
+ continue
268
+ try:
269
+ fpath = Path(root) / f
270
+ total_files += 1
271
+ total_size += fpath.stat().st_size
272
+ except:
273
+ continue
274
+
275
+ old_files = get_old_files()
276
+
277
+ # Determinar status
278
+ if len(old_files) == 0:
279
+ status = "healthy"
280
+ elif len(old_files) < 10:
281
+ status = "warning"
282
+ else:
283
+ status = "critical"
284
+
285
+ return {
286
+ "status": status,
287
+ "total_files": total_files,
288
+ "total_size_mb": round(total_size / (1024 * 1024), 2),
289
+ "old_files_count": len(old_files),
290
+ "oldest_file_days": old_files[0]["age_days"] if old_files else 0,
291
+ "threshold_days": MAX_AGE_DAYS,
292
+ }
293
+
294
+
295
+ # ==============================================================================
296
+ # INTEGRACAO COM SESSION_START
297
+ # ==============================================================================
298
+
299
+
300
+ def get_session_context(old_files: List[Dict]) -> Dict:
301
+ """
302
+ Retorna contexto para integracao com session_start.
303
+
304
+ Args:
305
+ old_files: Lista de arquivos antigos
306
+
307
+ Returns:
308
+ Dict com contexto para o JARVIS
309
+ """
310
+ if not old_files:
311
+ return {"has_alert": False, "summary": "", "alert": ""}
312
+
313
+ return {
314
+ "has_alert": True,
315
+ "summary": generate_summary(old_files),
316
+ "alert": generate_alert(old_files),
317
+ "file_count": len(old_files),
318
+ "oldest_days": old_files[0]["age_days"],
319
+ "health": check_inbox_health(),
320
+ }
321
+
322
+
323
+ # ==============================================================================
324
+ # MAIN
325
+ # ==============================================================================
326
+
327
+
328
+ def main():
329
+ """
330
+ Hook entry point for Claude Code SessionStart event.
331
+ Reads JSON from stdin, outputs JSON to stdout.
332
+ """
333
+ try:
334
+ input_data = sys.stdin.read()
335
+ hook_input = json.loads(input_data) if input_data else {}
336
+
337
+ old_files = get_old_files()
338
+
339
+ if old_files:
340
+ log_alert(old_files)
341
+ summary = generate_summary(old_files)
342
+ print(json.dumps({'continue': True, 'feedback': summary}))
343
+ else:
344
+ print(json.dumps({'continue': True}))
345
+
346
+ except Exception:
347
+ print(json.dumps({'continue': True}))
348
+
349
+
350
+ def cli_test():
351
+ """CLI test mode - run directly for debugging."""
352
+ old_files = get_old_files()
353
+ if old_files:
354
+ alert = generate_alert(old_files)
355
+ print(alert)
356
+ else:
357
+ print("[INBOX_ALERT] No old files found. INBOX is clean.")
358
+
359
+ health = check_inbox_health()
360
+ print(f"\nHealth: {json.dumps(health, indent=2)}")
361
+
362
+
363
+ if __name__ == "__main__":
364
+ if len(sys.argv) > 1 and sys.argv[1] == '--test':
365
+ cli_test()
366
+ else:
367
+ main()