mega-brain-ai 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mega-brain-ai might be problematic. Click here for more details.
- package/.claude/CLAUDE.md +155 -0
- package/.claude/commands/agents.md +161 -0
- package/.claude/commands/ask.md +117 -0
- package/.claude/commands/benchmark.md +224 -0
- package/.claude/commands/chat.md +343 -0
- package/.claude/commands/compare.md +116 -0
- package/.claude/commands/conclave.md +194 -0
- package/.claude/commands/config.md +133 -0
- package/.claude/commands/council.md +194 -0
- package/.claude/commands/create-agent.md +452 -0
- package/.claude/commands/debate.md +157 -0
- package/.claude/commands/documentation/create-architecture-documentation.md +175 -0
- package/.claude/commands/dossiers.md +180 -0
- package/.claude/commands/evolve.md +223 -0
- package/.claude/commands/extract-dna.md +170 -0
- package/.claude/commands/extract-knowledge.md +507 -0
- package/.claude/commands/inbox.md +296 -0
- package/.claude/commands/ingest-empresa.md +191 -0
- package/.claude/commands/ingest.md +182 -0
- package/.claude/commands/jarvis-briefing.md +67 -0
- package/.claude/commands/jarvis-control.md +169 -0
- package/.claude/commands/jarvis-full.md +181 -0
- package/.claude/commands/jarvis.md +212 -0
- package/.claude/commands/ler-drive.md +212 -0
- package/.claude/commands/log.md +158 -0
- package/.claude/commands/loop.md +133 -0
- package/.claude/commands/loops.md +73 -0
- package/.claude/commands/mission-autopilot.md +538 -0
- package/.claude/commands/mission.md +353 -0
- package/.claude/commands/process-inbox.md +148 -0
- package/.claude/commands/process-jarvis.md +3036 -0
- package/.claude/commands/process-video.md +131 -0
- package/.claude/commands/rag-search.md +78 -0
- package/.claude/commands/resume.md +33 -0
- package/.claude/commands/save.md +38 -0
- package/.claude/commands/scan-inbox.md +125 -0
- package/.claude/commands/setup.md +99 -0
- package/.claude/commands/system-digest.md +243 -0
- package/.claude/commands/verify.md +182 -0
- package/.claude/commands/view-dna.md +169 -0
- package/.claude/hooks/agent_doctor.py +433 -0
- package/.claude/hooks/agent_memory_persister.py +203 -0
- package/.claude/hooks/auto_formatter.py +158 -0
- package/.claude/hooks/checkpoint_writer.py +244 -0
- package/.claude/hooks/claude_md_guard.py +146 -0
- package/.claude/hooks/creation_validator.py +357 -0
- package/.claude/hooks/enforce_dual_location.py +501 -0
- package/.claude/hooks/enforce_plan_mode.py +220 -0
- package/.claude/hooks/inbox_age_alert.py +367 -0
- package/.claude/hooks/jarvis_briefing.py +506 -0
- package/.claude/hooks/ledger_updater.py +301 -0
- package/.claude/hooks/memory_hints_injector.py +251 -0
- package/.claude/hooks/memory_updater.py +202 -0
- package/.claude/hooks/multi_agent_hook.py +464 -0
- package/.claude/hooks/notification_system.py +120 -0
- package/.claude/hooks/pattern_analyzer.py +526 -0
- package/.claude/hooks/pending_tracker.py +188 -0
- package/.claude/hooks/post_batch_cascading.py +1740 -0
- package/.claude/hooks/post_output_validator.py +358 -0
- package/.claude/hooks/post_tool_use.py +120 -0
- package/.claude/hooks/post_write_validator.py +200 -0
- package/.claude/hooks/quality_watchdog.py +394 -0
- package/.claude/hooks/ralph_wiggum.py +277 -0
- package/.claude/hooks/session-source-sync.py +218 -0
- package/.claude/hooks/session_autosave_v2.py +1135 -0
- package/.claude/hooks/session_end.py +203 -0
- package/.claude/hooks/session_start.py +939 -0
- package/.claude/hooks/skill_indexer.py +48 -0
- package/.claude/hooks/skill_router.py +358 -0
- package/.claude/hooks/stop_hook_completeness.py +178 -0
- package/.claude/hooks/subagent_tracker.py +163 -0
- package/.claude/hooks/token_checkpoint.py +584 -0
- package/.claude/hooks/user_prompt_submit.py +125 -0
- package/.claude/rules/ANTHROPIC-STANDARDS.md +384 -0
- package/.claude/rules/CLAUDE-LITE.md +201 -0
- package/.claude/rules/RULE-GROUP-1.md +320 -0
- package/.claude/rules/RULE-GROUP-2.md +307 -0
- package/.claude/rules/RULE-GROUP-3.md +248 -0
- package/.claude/rules/RULE-GROUP-4.md +427 -0
- package/.claude/rules/RULE-GROUP-5.md +388 -0
- package/.claude/rules/RULE-GROUP-6.md +387 -0
- package/.claude/rules/logging.md +53 -0
- package/.claude/rules/mcp-governance.md +128 -0
- package/.claude/rules/pipeline.md +60 -0
- package/.claude/rules/state-management.md +93 -0
- package/.claude/scripts/apply-tags.py +77 -0
- package/.claude/scripts/batch-extract-transcriptions.py +132 -0
- package/.claude/scripts/build-complete-index.py +250 -0
- package/.claude/scripts/build-planilha-index.py +170 -0
- package/.claude/scripts/complete-tag-matching.py +250 -0
- package/.claude/scripts/deduplicate-inbox.py +139 -0
- package/.claude/scripts/docx-xml-extractor.py +141 -0
- package/.claude/scripts/extract-docx-text.py +58 -0
- package/.claude/scripts/extract-single-transcription.py +74 -0
- package/.claude/scripts/extract_docx_from_gdrive.py +77 -0
- package/.claude/scripts/organized-downloader.py +246 -0
- package/.claude/scripts/planilha-tagger.py +187 -0
- package/.claude/scripts/revert-tags.py +70 -0
- package/.claude/scripts/source-sync.py +265 -0
- package/.claude/scripts/tag-inbox-files.py +276 -0
- package/.claude/scripts/tag-inbox-v2.py +253 -0
- package/.claude/scripts/test-extraction.py +35 -0
- package/.claude/scripts/test-full-extraction.py +74 -0
- package/.claude/skills/00-SKILL-CREATOR/SKILL.md +186 -0
- package/.claude/skills/01-SKILL-DOCS-MEGABRAIN/SKILL.md +251 -0
- package/.claude/skills/02-SKILL-PYTHON-MEGABRAIN/SKILL.md +323 -0
- package/.claude/skills/03-SKILL-AGENT-CREATION/SKILL.md +374 -0
- package/.claude/skills/04-SKILL-KNOWLEDGE-EXTRACTION/SKILL.md +318 -0
- package/.claude/skills/05-SKILL-PIPELINE-JARVIS/SKILL.md +430 -0
- package/.claude/skills/06-SKILL-BRAINSTORMING/SKILL.md +72 -0
- package/.claude/skills/07-SKILL-DISPATCHING-PARALLEL-AGENTS/SKILL.md +193 -0
- package/.claude/skills/08-SKILL-EXECUTING-PLANS/SKILL.md +114 -0
- package/.claude/skills/09-SKILL-WRITING-PLANS/SKILL.md +184 -0
- package/.claude/skills/10-SKILL-VERIFICATION-BEFORE-COMPLETION/SKILL.md +130 -0
- package/.claude/skills/11-SKILL-USING-SUPERPOWERS/SKILL.md +105 -0
- package/.claude/skills/DETECTION-PROTOCOL.md +217 -0
- package/.claude/skills/README.md +240 -0
- package/.claude/skills/SKILL-REGISTRY.md +284 -0
- package/.claude/skills/SKILL-SUGGESTIONS.md +114 -0
- package/.claude/skills/_TEMPLATES/SKILL-WRITER-GUIDE.md +385 -0
- package/.claude/skills/chronicler/SKILL.md +146 -0
- package/.claude/skills/chronicler/chronicler_core.py +468 -0
- package/.claude/skills/code-review/SKILL.md +160 -0
- package/.claude/skills/council/SKILL.md +210 -0
- package/.claude/skills/executor/SKILL.md +161 -0
- package/.claude/skills/fase-2-5-tagging/SKILL.md +182 -0
- package/.claude/skills/feature-dev/SKILL.md +154 -0
- package/.claude/skills/finance-agent/SKILL.md +137 -0
- package/.claude/skills/frontend-design/SKILL.md +165 -0
- package/.claude/skills/gdrive-transcription-downloader/SKILL.md +249 -0
- package/.claude/skills/gemini-fallback/SKILL.md +67 -0
- package/.claude/skills/gemini-fallback/gemini_fetch.py +0 -0
- package/.claude/skills/gha/SKILL.md +96 -0
- package/.claude/skills/gha/gha_diagnostic.py +227 -0
- package/.claude/skills/github-workflow/SKILL.md +190 -0
- package/.claude/skills/hookify/SKILL.md +134 -0
- package/.claude/skills/hybrid-source-reading/SKILL.md +265 -0
- package/.claude/skills/jarvis/SKILL.md +546 -0
- package/.claude/skills/jarvis-briefing/SKILL.md +340 -0
- package/.claude/skills/ler-planilha/SKILL.md +281 -0
- package/.claude/skills/plugin-dev/SKILL.md +176 -0
- package/.claude/skills/pr-review-toolkit/SKILL.md +178 -0
- package/.claude/skills/resume/SKILL.md +61 -0
- package/.claude/skills/save/SKILL.md +87 -0
- package/.claude/skills/skill-writer/SKILL.md +153 -0
- package/.claude/skills/skill-writer/examples.md +191 -0
- package/.claude/skills/skill-writer/troubleshooting.md +205 -0
- package/.claude/skills/smart-download-tagger/SKILL.md +148 -0
- package/.claude/skills/source-sync/SKILL.md +240 -0
- package/.claude/skills/sync-docs/SKILL.md +193 -0
- package/.claude/skills/sync-docs/config.json +37 -0
- package/.claude/skills/sync-docs/gdrive_sync.py +358 -0
- package/.claude/skills/sync-docs/reauth.py +71 -0
- package/.claude/skills/talent-agent/SKILL.md +183 -0
- package/.claude/skills/verify/SKILL.md +154 -0
- package/.claude/skills/verify/verify_runner.py +0 -0
- package/.claude/skills/verify-6-levels/SKILL.md +234 -0
- package/.claude/templates/BATCH-LOG-TEMPLATE.md +221 -0
- package/.claudeignore +9 -0
- package/.gitattributes +4 -0
- package/.github/layer1-allowlist.txt +80 -0
- package/.github/layer2-manifest.txt +40 -0
- package/.gitignore +219 -0
- package/README.md +1210 -0
- package/agents/_templates/INDEX.md +741 -0
- package/agents/_templates/TEMPLATE-AGENT-MD-ULTRA-ROBUSTO-V3.md +2399 -0
- package/agents/boardroom/CHECKLIST-MASTER.md +281 -0
- package/agents/boardroom/INTEGRATION-GUIDE.md +406 -0
- package/agents/boardroom/README.md +238 -0
- package/agents/boardroom/config/BOARDROOM-CONFIG.md +186 -0
- package/agents/boardroom/config/TTS-INTEGRATION.md +258 -0
- package/agents/boardroom/config/VOICE-PROFILES.md +624 -0
- package/agents/boardroom/config/voice_mapping.json +128 -0
- package/agents/boardroom/scripts/audio_generator.py +375 -0
- package/agents/boardroom/scripts/audio_generator_edge.py +353 -0
- package/agents/boardroom/scripts/jarvis_boardroom_hook.py +415 -0
- package/agents/boardroom/scripts/notebooklm_generator.py +578 -0
- package/agents/boardroom/templates/EPISODE-TEMPLATE.md +367 -0
- package/agents/boardroom/templates/scene-templates/SCENE-AGENT-DEBATE.md +252 -0
- package/agents/boardroom/templates/scene-templates/SCENE-COUNCIL.md +270 -0
- package/agents/boardroom/templates/scene-templates/SCENE-DNA-CONSULTATION.md +126 -0
- package/agents/boardroom/templates/scene-templates/SCENE-QUESTION.md +174 -0
- package/agents/boardroom/workflows/WORKFLOW-AUDIO-GENERATION.md +421 -0
- package/agents/constitution/BASE-CONSTITUTION.md +254 -0
- package/agents/council/CRITIC.md +197 -0
- package/agents/council/DEVILS-ADVOCATE.md +274 -0
- package/agents/council/SYNTHESIZER.md +293 -0
- package/agents/council/advogado-do-diabo/AGENT.md +489 -0
- package/agents/council/advogado-do-diabo/SOUL.md +100 -0
- package/agents/council/critico-metodologico/AGENT.md +670 -0
- package/agents/council/critico-metodologico/SOUL.md +107 -0
- package/agents/council/sintetizador/AGENT.md +558 -0
- package/agents/council/sintetizador/SOUL.md +94 -0
- package/agents/persons/_example/AGENT-EXAMPLE.md +42 -0
- package/agents/persons/_example/DNA-EXAMPLE.yaml +61 -0
- package/agents/protocols/AGENT-COGNITION-PROTOCOL.md +779 -0
- package/agents/protocols/AGENT-INTEGRITY-PROTOCOL.md +692 -0
- package/agents/protocols/BATCH-VISUAL-PROTOCOL.md +841 -0
- package/agents/protocols/DNA-CONFIG-TEMPLATE.yaml +181 -0
- package/agents/protocols/DNA-EXTRACTION-PROTOCOL.md +370 -0
- package/agents/protocols/EPISTEMIC-PROTOCOL.md +333 -0
- package/agents/protocols/LOG-STRUCTURE-PROTOCOL.md +65 -0
- package/agents/protocols/MEMORY-PROTOCOL.md +567 -0
- package/agents/protocols/NARRATIVE-SYNTHESIS-PROTOCOL.md +278 -0
- package/agents/protocols/PHASE-4-VERIFICATION-CHECKPOINT.md +146 -0
- package/agents/protocols/SOUL-TEMPLATE.md +416 -0
- package/agents/protocols/TEMPLATE-EVOLUTION-PROTOCOL.md +544 -0
- package/agents/protocols/VISUAL-DIFF-PROTOCOL.md +159 -0
- package/agents/sua-empresa/README.md +44 -0
- package/agents/sua-empresa/_example/jds/EXAMPLE-JD.md +42 -0
- package/agents/sua-empresa/_example/org/EXAMPLE-ORG.md +32 -0
- package/agents/sua-empresa/_example/roles/EXAMPLE-ROLE.md +38 -0
- package/bin/cli.js +2 -0
- package/bin/lib/ascii-art.js +234 -0
- package/bin/lib/installer.js +402 -0
- package/bin/lib/setup-wizard.js +95 -0
- package/bin/lib/validate-email.js +109 -0
- package/bin/mega-brain.js +97 -0
- package/bin/push.js +342 -0
- package/bin/templates/env.example +38 -0
- package/inbox/.gitkeep +0 -0
- package/integrations/README.md +46 -0
- package/integrations/mcps/MCP-REGISTRY.md +56 -0
- package/integrations/mcps/excalidraw/CONFIG.md +56 -0
- package/integrations/mcps/gdrive/CONFIG.md +38 -0
- package/knowledge/dna/.gitkeep +0 -0
- package/knowledge/dossiers/persons/.gitkeep +0 -0
- package/knowledge/dossiers/persons/DOSSIER-EXAMPLE.md +49 -0
- package/knowledge/dossiers/system/.gitkeep +0 -0
- package/knowledge/dossiers/themes/.gitkeep +0 -0
- package/knowledge/playbooks/.gitkeep +0 -0
- package/knowledge/playbooks/PLAYBOOK-EXAMPLE.md +50 -0
- package/knowledge/sources/.gitkeep +0 -0
- package/logs/.gitkeep +0 -0
- package/package.json +128 -0
- package/processing/canonical/.gitkeep +0 -0
- package/processing/chunks/.gitkeep +0 -0
- package/processing/insights/.gitkeep +0 -0
- package/processing/narratives/.gitkeep +0 -0
- package/reference/CONSELHO.md +337 -0
- package/reference/CONTEXT7_README.md +28 -0
- package/reference/JARVIS-LOGGING-PROTOCOL.md +380 -0
- package/reference/QUICK-START.md +197 -0
- package/reference/README-RALPH-CASCATEAMENTO.md +207 -0
- package/reference/TEMPLATE-MASTER.md +727 -0
- package/reference/prds/prd-jarvis-mega-brain-v3.md +1305 -0
- package/reference/templates/phase5/IMPLEMENTATION-GUIDE.md +355 -0
- package/reference/templates/phase5/MOGA-BRAIN-PHASE5-TEMPLATES.md +1284 -0
- package/reference/templates/phase5/README.md +165 -0
- package/reference/workflow-claude-code-boris-cherny-continuous-claude.md +2232 -0
- package/system/database/001_moneyclub_buyers.sql +160 -0
- package/system/database/002_premium_token.sql +97 -0
- package/system/database/apply-migration.mjs +129 -0
- package/system/docs/MEGA-BRAIN-DEMO-COMPLETA.md +1226 -0
- package/system/docs/MEGA-BRAIN-MANIFESTO-COMPLETO.md +1054 -0
- package/system/docs/MOGA-BRAIN-EXPLICACAO-COMPLETA.md +791 -0
- package/system/docs/STRATEGIC-INTEGRATION-GUIDE.md +725 -0
- package/system/docs/architecture/01-system-context.md +136 -0
- package/system/docs/architecture/02-components.md +225 -0
- package/system/docs/architecture/03-data-flow.md +235 -0
- package/system/docs/architecture/04-integrations.md +283 -0
- package/system/docs/architecture/README.md +71 -0
- package/system/docs/architecture/diagrams/component-diagram.mmd +50 -0
- package/system/docs/architecture/diagrams/data-flow.mmd +39 -0
- package/system/docs/architecture/diagrams/system-overview.mmd +68 -0
- package/system/protocols/AGENT-AUTHORITY.md +217 -0
- package/system/protocols/CONSTITUICAO-BASE.md +115 -0
- package/system/protocols/CONSTITUTION.md +231 -0
- package/system/protocols/GOVERNANCE-MAP.md +123 -0
- package/system/protocols/HOOK-SECURITY-THREAT-MODEL.md +152 -0
- package/system/protocols/ORQUESTRACAO-PROTOCOL.md +215 -0
- package/system/protocols/_archive/CHUNKING-PROTOCOL.md +207 -0
- package/system/protocols/_archive/ENTITY-RESOLUTION-PROTOCOL.md +269 -0
- package/system/protocols/_archive/INSIGHT-EXTRACTION-PROTOCOL.md +257 -0
- package/system/protocols/_archive/NARRATIVE-SYNTHESIS-PROTOCOL.md +290 -0
- package/system/protocols/agents/AGENT-INTERACTION.md +315 -0
- package/system/protocols/agents/CORTEX-PROTOCOL.md +520 -0
- package/system/protocols/agents/EPISTEMIC-PROTOCOL.md +465 -0
- package/system/protocols/agents/MEMORY-PROTOCOL.md +366 -0
- package/system/protocols/agents/WAR-ROOM.md +355 -0
- package/system/protocols/company/COMPANY-DOCUMENT-PROTOCOL.md +793 -0
- package/system/protocols/company/COMPANY-ENRICHMENT-PROTOCOL.md +679 -0
- package/system/protocols/conclave/CONCLAVE-LOG-TEMPLATE-v2.md +309 -0
- package/system/protocols/conclave/CONCLAVE-PROTOCOL.md +518 -0
- package/system/protocols/conclave/DEBATE-DYNAMICS-CONFIG.yaml +322 -0
- package/system/protocols/conclave/DEBATE-DYNAMICS-PROTOCOL.md +613 -0
- package/system/protocols/conclave/DEBATE-PROTOCOL.md +323 -0
- package/system/protocols/council/COUNCIL-LOG-TEMPLATE-v2.md +309 -0
- package/system/protocols/council/COUNCIL-PROTOCOL.md +518 -0
- package/system/protocols/council/DEBATE-DYNAMICS-CONFIG.yaml +322 -0
- package/system/protocols/council/DEBATE-DYNAMICS-PROTOCOL.md +613 -0
- package/system/protocols/council/DEBATE-PROTOCOL.md +323 -0
- package/system/protocols/dna/DNA-EXTRACTION-PROTOCOL.md +1214 -0
- package/system/protocols/dna/ENRICHMENT-PROTOCOL.md +408 -0
- package/system/protocols/dna/REASONING-MODEL-PROTOCOL.md +331 -0
- package/system/protocols/pipeline/DOSSIER-COMPILATION-PROTOCOL.md +790 -0
- package/system/protocols/pipeline/NARRATIVE-METABOLISM-PROTOCOL.md +292 -0
- package/system/protocols/pipeline/PIPELINE-JARVIS-v2.1.md +606 -0
- package/system/protocols/pipeline/PROMPT-1.1-CHUNKING.md +154 -0
- package/system/protocols/pipeline/PROMPT-1.2-ENTITY-RESOLUTION.md +186 -0
- package/system/protocols/pipeline/PROMPT-2.1-DNA-TAGS-INCREMENT.md +208 -0
- package/system/protocols/pipeline/PROMPT-2.1-INSIGHT-EXTRACTION.md +191 -0
- package/system/protocols/pipeline/PROMPT-3.1-NARRATIVE-SYNTHESIS.md +331 -0
- package/system/protocols/pipeline/SOURCES-COMPILATION-PROTOCOL.md +340 -0
- package/system/protocols/system/AUTO-LOG-PROTOCOL.md +369 -0
- package/system/protocols/system/CHECKPOINT-ENFORCEMENT.md +176 -0
- package/system/protocols/system/ENFORCEMENT.md +435 -0
- package/system/protocols/system/LOG-TEMPLATES.md +1068 -0
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
AUTO FORMATTER HOOK
|
|
4
|
+
===================
|
|
5
|
+
Formata código automaticamente após Write/Edit.
|
|
6
|
+
|
|
7
|
+
Baseado em Boris Cherny: "bun run format || true"
|
|
8
|
+
|
|
9
|
+
Formatters suportados:
|
|
10
|
+
- Python: black, autopep8
|
|
11
|
+
- JavaScript/TypeScript: prettier
|
|
12
|
+
- JSON: jq
|
|
13
|
+
- YAML: yamlfmt
|
|
14
|
+
- Markdown: prettier
|
|
15
|
+
|
|
16
|
+
Usage (via hook):
|
|
17
|
+
python3 auto_formatter.py "$TOOL_INPUT"
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import sys
|
|
21
|
+
import os
|
|
22
|
+
import subprocess
|
|
23
|
+
import json
|
|
24
|
+
import re
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
PROJECT_ROOT = Path(os.environ.get('CLAUDE_PROJECT_DIR', '.'))
|
|
28
|
+
|
|
29
|
+
# File extensions and their formatters
|
|
30
|
+
FORMATTERS = {
|
|
31
|
+
'.py': ['black', '--quiet', '--line-length', '100'],
|
|
32
|
+
'.js': ['prettier', '--write'],
|
|
33
|
+
'.ts': ['prettier', '--write'],
|
|
34
|
+
'.jsx': ['prettier', '--write'],
|
|
35
|
+
'.tsx': ['prettier', '--write'],
|
|
36
|
+
'.json': ['prettier', '--write'],
|
|
37
|
+
'.md': ['prettier', '--write', '--prose-wrap', 'always'],
|
|
38
|
+
'.yaml': ['prettier', '--write'],
|
|
39
|
+
'.yml': ['prettier', '--write'],
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# Alternative formatters if primary not available
|
|
43
|
+
FALLBACK_FORMATTERS = {
|
|
44
|
+
'.py': ['autopep8', '--in-place', '--aggressive'],
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def extract_file_path(tool_input: str) -> str:
|
|
49
|
+
"""Extract file path from tool input"""
|
|
50
|
+
# Try to parse as JSON first
|
|
51
|
+
try:
|
|
52
|
+
data = json.loads(tool_input)
|
|
53
|
+
return data.get('file_path', '')
|
|
54
|
+
except:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
# Try regex for file_path
|
|
58
|
+
match = re.search(r'"file_path"\s*:\s*"([^"]+)"', tool_input)
|
|
59
|
+
if match:
|
|
60
|
+
return match.group(1)
|
|
61
|
+
|
|
62
|
+
# Try to find any path-like string
|
|
63
|
+
match = re.search(r'(/[^\s"]+\.\w+)', tool_input)
|
|
64
|
+
if match:
|
|
65
|
+
return match.group(1)
|
|
66
|
+
|
|
67
|
+
return ''
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def check_formatter_available(formatter: list) -> bool:
|
|
71
|
+
"""Check if formatter is installed"""
|
|
72
|
+
try:
|
|
73
|
+
subprocess.run(
|
|
74
|
+
[formatter[0], '--version'],
|
|
75
|
+
capture_output=True,
|
|
76
|
+
timeout=5
|
|
77
|
+
)
|
|
78
|
+
return True
|
|
79
|
+
except:
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def format_file(filepath: str) -> tuple[bool, str]:
|
|
84
|
+
"""Format a file using appropriate formatter"""
|
|
85
|
+
if not os.path.exists(filepath):
|
|
86
|
+
return False, f"File not found: {filepath}"
|
|
87
|
+
|
|
88
|
+
ext = Path(filepath).suffix.lower()
|
|
89
|
+
|
|
90
|
+
if ext not in FORMATTERS:
|
|
91
|
+
return True, f"No formatter for {ext}"
|
|
92
|
+
|
|
93
|
+
formatter = FORMATTERS[ext]
|
|
94
|
+
|
|
95
|
+
# Check if formatter is available
|
|
96
|
+
if not check_formatter_available(formatter):
|
|
97
|
+
# Try fallback
|
|
98
|
+
if ext in FALLBACK_FORMATTERS:
|
|
99
|
+
formatter = FALLBACK_FORMATTERS[ext]
|
|
100
|
+
if not check_formatter_available(formatter):
|
|
101
|
+
return True, f"No formatter available for {ext}"
|
|
102
|
+
else:
|
|
103
|
+
return True, f"Formatter {formatter[0]} not installed"
|
|
104
|
+
|
|
105
|
+
# Run formatter
|
|
106
|
+
try:
|
|
107
|
+
cmd = formatter + [filepath]
|
|
108
|
+
result = subprocess.run(
|
|
109
|
+
cmd,
|
|
110
|
+
capture_output=True,
|
|
111
|
+
text=True,
|
|
112
|
+
timeout=30
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
if result.returncode == 0:
|
|
116
|
+
return True, f"Formatted with {formatter[0]}"
|
|
117
|
+
else:
|
|
118
|
+
# Don't fail on formatter errors - just report
|
|
119
|
+
return True, f"Formatter warning: {result.stderr[:100]}"
|
|
120
|
+
|
|
121
|
+
except subprocess.TimeoutExpired:
|
|
122
|
+
return True, "Formatter timeout"
|
|
123
|
+
except Exception as e:
|
|
124
|
+
return True, f"Formatter error: {str(e)[:100]}"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def main():
|
|
128
|
+
if len(sys.argv) < 2:
|
|
129
|
+
sys.exit(0)
|
|
130
|
+
|
|
131
|
+
tool_input = sys.argv[1]
|
|
132
|
+
filepath = extract_file_path(tool_input)
|
|
133
|
+
|
|
134
|
+
if not filepath:
|
|
135
|
+
sys.exit(0)
|
|
136
|
+
|
|
137
|
+
# Skip non-code files
|
|
138
|
+
ext = Path(filepath).suffix.lower()
|
|
139
|
+
if ext not in FORMATTERS:
|
|
140
|
+
sys.exit(0)
|
|
141
|
+
|
|
142
|
+
# Skip files outside project
|
|
143
|
+
if str(PROJECT_ROOT) not in filepath:
|
|
144
|
+
sys.exit(0)
|
|
145
|
+
|
|
146
|
+
# Format
|
|
147
|
+
success, message = format_file(filepath)
|
|
148
|
+
|
|
149
|
+
if success:
|
|
150
|
+
print(f"✨ {message}: {Path(filepath).name}")
|
|
151
|
+
else:
|
|
152
|
+
print(f"⚠️ {message}")
|
|
153
|
+
|
|
154
|
+
sys.exit(0)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
if __name__ == '__main__':
|
|
158
|
+
main()
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
JARVIS Checkpoint Writer v1.0
|
|
4
|
+
Salva estado completo antes de compactação de contexto.
|
|
5
|
+
|
|
6
|
+
Arquivos gerados:
|
|
7
|
+
- CURRENT-TASK.md (tarefa atual destacada)
|
|
8
|
+
- CONTEXT-SNAPSHOT.md (resumo do contexto atual)
|
|
9
|
+
- INSIGHTS-SESSION.md (insights da sessão)
|
|
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_checkpoint_trigger():
|
|
23
|
+
"""Carrega dados do trigger de checkpoint."""
|
|
24
|
+
project_dir = get_project_dir()
|
|
25
|
+
trigger_path = Path(project_dir) / '.claude' / 'mission-control' / 'CHECKPOINT-TRIGGER.json'
|
|
26
|
+
|
|
27
|
+
if trigger_path.exists():
|
|
28
|
+
with open(trigger_path, 'r', encoding='utf-8') as f:
|
|
29
|
+
return json.load(f)
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
def load_jarvis_state():
|
|
33
|
+
"""Carrega estado do JARVIS."""
|
|
34
|
+
project_dir = get_project_dir()
|
|
35
|
+
|
|
36
|
+
# Tentar .claude/jarvis/ primeiro
|
|
37
|
+
state_path = Path(project_dir) / '.claude' / 'jarvis' / 'STATE.json'
|
|
38
|
+
if state_path.exists():
|
|
39
|
+
with open(state_path, 'r', encoding='utf-8') as f:
|
|
40
|
+
return json.load(f)
|
|
41
|
+
|
|
42
|
+
# Fallback
|
|
43
|
+
state_path = Path(project_dir) / 'system' / 'JARVIS-STATE.json'
|
|
44
|
+
if state_path.exists():
|
|
45
|
+
with open(state_path, 'r', encoding='utf-8') as f:
|
|
46
|
+
return json.load(f)
|
|
47
|
+
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
def load_pending():
|
|
51
|
+
"""Carrega pendências atuais."""
|
|
52
|
+
project_dir = get_project_dir()
|
|
53
|
+
pending_path = Path(project_dir) / '.claude' / 'jarvis' / 'PENDING.md'
|
|
54
|
+
|
|
55
|
+
if pending_path.exists():
|
|
56
|
+
with open(pending_path, 'r', encoding='utf-8') as f:
|
|
57
|
+
return f.read()
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
def update_current_task(trigger_data, state):
|
|
61
|
+
"""Atualiza CURRENT-TASK.md com estado atual."""
|
|
62
|
+
project_dir = get_project_dir()
|
|
63
|
+
task_path = Path(project_dir) / '.claude' / 'jarvis' / 'CURRENT-TASK.md'
|
|
64
|
+
|
|
65
|
+
# Construir conteúdo
|
|
66
|
+
objective = "Continuar tarefa da sessão anterior"
|
|
67
|
+
context = "Checkpoint automático disparado por uso de contexto."
|
|
68
|
+
|
|
69
|
+
if state:
|
|
70
|
+
if 'next_action' in state:
|
|
71
|
+
objective = state['next_action'].get('description', objective)
|
|
72
|
+
if 'mission' in state:
|
|
73
|
+
mission = state['mission']
|
|
74
|
+
context = f"Missão: Fase {mission.get('phase', '?')} | Batch {mission.get('batch', '?')}"
|
|
75
|
+
|
|
76
|
+
content = f"""# CURRENT-TASK.md
|
|
77
|
+
|
|
78
|
+
> Tarefa atual em andamento. Atualizado automaticamente via checkpoint.
|
|
79
|
+
> Lido no início de cada sessão para continuidade.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Objetivo
|
|
84
|
+
|
|
85
|
+
{objective}
|
|
86
|
+
|
|
87
|
+
## Contexto
|
|
88
|
+
|
|
89
|
+
{context}
|
|
90
|
+
|
|
91
|
+
## Checkpoint Info
|
|
92
|
+
|
|
93
|
+
- Razão: {trigger_data.get('reason', 'MANUAL')}
|
|
94
|
+
- Tokens estimados: {trigger_data.get('tokens_estimated', 'N/A')}
|
|
95
|
+
- Uso de contexto: {trigger_data.get('usage_percent', 'N/A')}%
|
|
96
|
+
- Mensagens na sessão: {trigger_data.get('messages_count', 'N/A')}
|
|
97
|
+
|
|
98
|
+
## Próximos Passos
|
|
99
|
+
|
|
100
|
+
1. Verificar PENDING.md para tarefas pendentes
|
|
101
|
+
2. Consultar JARVIS-MEMORY.md para contexto relacional
|
|
102
|
+
3. Retomar de onde parou
|
|
103
|
+
|
|
104
|
+
## Insights da Sessão
|
|
105
|
+
|
|
106
|
+
*Adicione insights importantes aqui durante a sessão*
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
*Atualizado: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
|
|
111
|
+
*Checkpoint automático JARVIS Memory System v2.0*
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
with open(task_path, 'w', encoding='utf-8') as f:
|
|
115
|
+
f.write(content)
|
|
116
|
+
|
|
117
|
+
return task_path
|
|
118
|
+
|
|
119
|
+
def create_context_snapshot(trigger_data, state):
|
|
120
|
+
"""Cria snapshot do contexto atual."""
|
|
121
|
+
project_dir = get_project_dir()
|
|
122
|
+
timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')
|
|
123
|
+
snapshot_path = Path(project_dir) / '.claude' / 'jarvis' / 'snapshots' / f'CONTEXT-{timestamp}.md'
|
|
124
|
+
snapshot_path.parent.mkdir(parents=True, exist_ok=True)
|
|
125
|
+
|
|
126
|
+
# Estado da missão
|
|
127
|
+
mission_info = "Não disponível"
|
|
128
|
+
if state and 'mission' in state:
|
|
129
|
+
m = state['mission']
|
|
130
|
+
mission_info = f"Fase {m.get('phase', '?')} | Batch {m.get('batch', '?')}/{m.get('total_batches', '?')} | {m.get('status', 'UNKNOWN')}"
|
|
131
|
+
|
|
132
|
+
# Progresso acumulado
|
|
133
|
+
progress_info = "Não disponível"
|
|
134
|
+
if state and 'accumulated' in state:
|
|
135
|
+
a = state['accumulated']
|
|
136
|
+
progress_info = f"{a.get('progress_percent', 0)}% | {a.get('files', 0)} arquivos | {a.get('insights', 0)} insights"
|
|
137
|
+
|
|
138
|
+
content = f"""# CONTEXT SNAPSHOT
|
|
139
|
+
|
|
140
|
+
> Snapshot automático do contexto da sessão.
|
|
141
|
+
> Gerado em: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Trigger
|
|
146
|
+
|
|
147
|
+
| Campo | Valor |
|
|
148
|
+
|-------|-------|
|
|
149
|
+
| Razão | {trigger_data.get('reason', 'N/A')} |
|
|
150
|
+
| Tokens | {trigger_data.get('tokens_estimated', 'N/A')} |
|
|
151
|
+
| Uso % | {trigger_data.get('usage_percent', 'N/A')}% |
|
|
152
|
+
| Mensagens | {trigger_data.get('messages_count', 'N/A')} |
|
|
153
|
+
|
|
154
|
+
## Estado da Missão
|
|
155
|
+
|
|
156
|
+
{mission_info}
|
|
157
|
+
|
|
158
|
+
## Progresso Acumulado
|
|
159
|
+
|
|
160
|
+
{progress_info}
|
|
161
|
+
|
|
162
|
+
## Arquivos de Memória
|
|
163
|
+
|
|
164
|
+
| Arquivo | Status |
|
|
165
|
+
|---------|--------|
|
|
166
|
+
| JARVIS-MEMORY.md | Verificar |
|
|
167
|
+
| PENDING.md | Verificar |
|
|
168
|
+
| STATE.json | {'Carregado' if state else 'Não encontrado'} |
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
*Snapshot JARVIS Memory System v2.0*
|
|
173
|
+
"""
|
|
174
|
+
|
|
175
|
+
with open(snapshot_path, 'w', encoding='utf-8') as f:
|
|
176
|
+
f.write(content)
|
|
177
|
+
|
|
178
|
+
# Também manter um LATEST
|
|
179
|
+
latest_path = Path(project_dir) / '.claude' / 'jarvis' / 'CONTEXT-SNAPSHOT-LATEST.md'
|
|
180
|
+
with open(latest_path, 'w', encoding='utf-8') as f:
|
|
181
|
+
f.write(content)
|
|
182
|
+
|
|
183
|
+
return snapshot_path
|
|
184
|
+
|
|
185
|
+
def log_checkpoint(trigger_data, files_created):
|
|
186
|
+
"""Loga o checkpoint executado."""
|
|
187
|
+
project_dir = get_project_dir()
|
|
188
|
+
log_path = Path(project_dir) / 'logs' / 'checkpoints.jsonl'
|
|
189
|
+
|
|
190
|
+
log_entry = {
|
|
191
|
+
'timestamp': datetime.now().isoformat(),
|
|
192
|
+
'trigger': trigger_data,
|
|
193
|
+
'files_created': [str(f) for f in files_created]
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
log_path.parent.mkdir(parents=True, exist_ok=True)
|
|
197
|
+
with open(log_path, 'a', encoding='utf-8') as f:
|
|
198
|
+
f.write(json.dumps(log_entry, ensure_ascii=False) + '\n')
|
|
199
|
+
|
|
200
|
+
def main():
|
|
201
|
+
"""Função principal do checkpoint writer."""
|
|
202
|
+
try:
|
|
203
|
+
# Carregar trigger data
|
|
204
|
+
trigger_data = load_checkpoint_trigger()
|
|
205
|
+
if not trigger_data:
|
|
206
|
+
trigger_data = {
|
|
207
|
+
'reason': 'MANUAL',
|
|
208
|
+
'timestamp': datetime.now().isoformat()
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
# Carregar estado
|
|
212
|
+
state = load_jarvis_state()
|
|
213
|
+
|
|
214
|
+
# Criar arquivos de checkpoint
|
|
215
|
+
files_created = []
|
|
216
|
+
|
|
217
|
+
# 1. Atualizar CURRENT-TASK.md
|
|
218
|
+
task_file = update_current_task(trigger_data, state)
|
|
219
|
+
files_created.append(task_file)
|
|
220
|
+
|
|
221
|
+
# 2. Criar snapshot de contexto
|
|
222
|
+
snapshot_file = create_context_snapshot(trigger_data, state)
|
|
223
|
+
files_created.append(snapshot_file)
|
|
224
|
+
|
|
225
|
+
# 3. Logar checkpoint
|
|
226
|
+
log_checkpoint(trigger_data, files_created)
|
|
227
|
+
|
|
228
|
+
# Output
|
|
229
|
+
output = {
|
|
230
|
+
'success': True,
|
|
231
|
+
'files_created': [str(f) for f in files_created],
|
|
232
|
+
'message': f"Checkpoint salvo com sucesso. {len(files_created)} arquivos criados."
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
print(json.dumps(output))
|
|
236
|
+
|
|
237
|
+
except Exception as e:
|
|
238
|
+
print(json.dumps({
|
|
239
|
+
'success': False,
|
|
240
|
+
'error': str(e)
|
|
241
|
+
}))
|
|
242
|
+
|
|
243
|
+
if __name__ == '__main__':
|
|
244
|
+
main()
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
CLAUDE.md Guard Hook - VETO: Blocks CLAUDE.md creation outside sanctioned locations.
|
|
4
|
+
|
|
5
|
+
Hook Type: PreToolUse (Write|Edit)
|
|
6
|
+
Adapted from: aios-core/.claude/hooks/claude_md_guard.py
|
|
7
|
+
Date: 2026-02-18
|
|
8
|
+
|
|
9
|
+
Architecture Rule Enforced:
|
|
10
|
+
CLAUDE.md files are ONLY allowed in these locations:
|
|
11
|
+
- .claude/CLAUDE.md (project instructions)
|
|
12
|
+
- CLAUDE.md (repo root)
|
|
13
|
+
|
|
14
|
+
Agent memory MUST use .claude/agent-memory/{slug}/MEMORY.md
|
|
15
|
+
NEVER create CLAUDE.md in code directories, data dirs, or subfolders.
|
|
16
|
+
|
|
17
|
+
VETO CONDITIONS:
|
|
18
|
+
- Any Write/Edit targeting a CLAUDE.md outside sanctioned paths -> BLOCK
|
|
19
|
+
- Any content containing <claude-mem-context> outside .claude/ -> BLOCK
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
import json
|
|
23
|
+
import sys
|
|
24
|
+
import os
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
|
|
27
|
+
# Sanctioned CLAUDE.md locations (relative to project root)
|
|
28
|
+
SANCTIONED_CLAUDE_MD = {
|
|
29
|
+
"CLAUDE.md", # Repo root
|
|
30
|
+
".claude/CLAUDE.md", # Project instructions
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Patterns that indicate auto-generated memory spam
|
|
34
|
+
SPAM_INDICATORS = [
|
|
35
|
+
"<claude-mem-context>",
|
|
36
|
+
"<!-- This section is auto-generated by claude-mem",
|
|
37
|
+
"# Recent Activity",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def normalize_path(file_path: str) -> str:
|
|
42
|
+
"""Normalize path to relative, forward-slash format."""
|
|
43
|
+
project_dir = os.environ.get('CLAUDE_PROJECT_DIR', '.')
|
|
44
|
+
|
|
45
|
+
fp = Path(file_path).resolve()
|
|
46
|
+
pd = Path(project_dir).resolve()
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
rel = fp.relative_to(pd)
|
|
50
|
+
return str(rel).replace("\\", "/")
|
|
51
|
+
except ValueError:
|
|
52
|
+
return file_path.replace("\\", "/")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def is_claude_md(file_path: str) -> bool:
|
|
56
|
+
"""Check if the file is a CLAUDE.md file."""
|
|
57
|
+
normalized = file_path.replace("\\", "/")
|
|
58
|
+
return normalized.endswith("/CLAUDE.md") or normalized == "CLAUDE.md"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def is_sanctioned(relative_path: str) -> bool:
|
|
62
|
+
"""Check if the CLAUDE.md path is in a sanctioned location."""
|
|
63
|
+
return relative_path in SANCTIONED_CLAUDE_MD
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def content_is_spam(content: str) -> bool:
|
|
67
|
+
"""Check if content contains auto-generated memory spam markers."""
|
|
68
|
+
if not content:
|
|
69
|
+
return False
|
|
70
|
+
for indicator in SPAM_INDICATORS:
|
|
71
|
+
if indicator in content:
|
|
72
|
+
return True
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def main():
|
|
77
|
+
try:
|
|
78
|
+
input_data = sys.stdin.read()
|
|
79
|
+
if not input_data:
|
|
80
|
+
print(json.dumps({"decision": "allow"}))
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
hook_input = json.loads(input_data)
|
|
84
|
+
tool_name = hook_input.get("tool_name", "")
|
|
85
|
+
tool_input = hook_input.get("tool_input", {})
|
|
86
|
+
|
|
87
|
+
# Only check Write and Edit tools
|
|
88
|
+
if tool_name not in ("Write", "Edit", "write", "edit"):
|
|
89
|
+
print(json.dumps({"decision": "allow"}))
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
file_path = tool_input.get("file_path", "")
|
|
93
|
+
if not file_path:
|
|
94
|
+
print(json.dumps({"decision": "allow"}))
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
relative_path = normalize_path(file_path)
|
|
98
|
+
|
|
99
|
+
# Check if targeting a CLAUDE.md file
|
|
100
|
+
if not is_claude_md(relative_path):
|
|
101
|
+
print(json.dumps({"decision": "allow"}))
|
|
102
|
+
return
|
|
103
|
+
|
|
104
|
+
# Check if it's a sanctioned location
|
|
105
|
+
if is_sanctioned(relative_path):
|
|
106
|
+
content = tool_input.get("content", "")
|
|
107
|
+
if not content:
|
|
108
|
+
content = tool_input.get("new_string", "")
|
|
109
|
+
|
|
110
|
+
if content_is_spam(content):
|
|
111
|
+
print(json.dumps({
|
|
112
|
+
"decision": "allow",
|
|
113
|
+
"message": (
|
|
114
|
+
"Warning: CLAUDE.md Guard: Detected claude-mem-context in sanctioned file. "
|
|
115
|
+
"Agent memory should use .claude/agent-memory/{slug}/MEMORY.md instead."
|
|
116
|
+
)
|
|
117
|
+
}))
|
|
118
|
+
return
|
|
119
|
+
|
|
120
|
+
print(json.dumps({"decision": "allow"}))
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
# UNSANCTIONED CLAUDE.md -> BLOCK
|
|
124
|
+
print(json.dumps({
|
|
125
|
+
"decision": "block",
|
|
126
|
+
"reason": (
|
|
127
|
+
f"VETO: CLAUDE.md Guard\n"
|
|
128
|
+
f" Path: {relative_path}\n"
|
|
129
|
+
f" Rule: CLAUDE.md files are NOT allowed outside sanctioned locations.\n"
|
|
130
|
+
f" Sanctioned: {', '.join(sorted(SANCTIONED_CLAUDE_MD))}\n"
|
|
131
|
+
f" Agent memory -> .claude/agent-memory/{{slug}}/MEMORY.md"
|
|
132
|
+
)
|
|
133
|
+
}))
|
|
134
|
+
|
|
135
|
+
except json.JSONDecodeError:
|
|
136
|
+
print(json.dumps({"decision": "allow"}))
|
|
137
|
+
except Exception as e:
|
|
138
|
+
# Fail-open: don't block on errors
|
|
139
|
+
print(json.dumps({
|
|
140
|
+
"decision": "allow",
|
|
141
|
+
"message": f"CLAUDE.md Guard error (fail-open): {str(e)}"
|
|
142
|
+
}))
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
main()
|