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,187 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
PLANILHA TAGGER - Tagueamento na Fonte
|
|
4
|
+
Mega Brain - Sistema de Inteligência de Negócios
|
|
5
|
+
|
|
6
|
+
Escreve TAGs diretamente na planilha de controle via MCP gdrive.
|
|
7
|
+
TAGs são escritas NA FONTE, não localmente.
|
|
8
|
+
|
|
9
|
+
USO: Este script é chamado pelo JARVIS via MCP, não diretamente.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import json
|
|
14
|
+
from datetime import datetime
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
# Configurações
|
|
18
|
+
MISSION_CONTROL = ".claude/mission-control"
|
|
19
|
+
PLANILHA_INDEX = f"{MISSION_CONTROL}/PLANILHA-INDEX.json"
|
|
20
|
+
SOURCE_SYNC_STATE = f"{MISSION_CONTROL}/SOURCE-SYNC-STATE.json"
|
|
21
|
+
|
|
22
|
+
# Mapeamento de abas → prefixos de TAG
|
|
23
|
+
SHEET_TO_PREFIX = {
|
|
24
|
+
"Jeremy Miner": "JM",
|
|
25
|
+
"Jeremy Haynes Sales Training": "JH-ST",
|
|
26
|
+
"Jeremy Haynes Inner Circle": "JH-IC",
|
|
27
|
+
"Inner Circle Weekly Group Call Recordings": "JH-WK",
|
|
28
|
+
"Agency Blueprint": "AOBA",
|
|
29
|
+
"Cold Video Pitch": "PCVP",
|
|
30
|
+
"Land Your First Agency Client": "LYFC",
|
|
31
|
+
"Marketer Mindset Masterclass": "MMM",
|
|
32
|
+
"30 Days Challenge": "30DC",
|
|
33
|
+
"Scale The Agency": "STA",
|
|
34
|
+
"Ultra High Ticket Closer": "UHTC",
|
|
35
|
+
"Cole Gordon": "CG",
|
|
36
|
+
"The Scalable Company": "TSC",
|
|
37
|
+
"Sales Training BR": "EDC",
|
|
38
|
+
"Alex Hormozi": "AH",
|
|
39
|
+
"Jeremy Haynes Program": "CA",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
TAG_COLUMN = "I"
|
|
43
|
+
TAG_COLUMN_INDEX = 8
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def load_planilha_index():
|
|
47
|
+
"""Carrega índice da planilha."""
|
|
48
|
+
if os.path.exists(PLANILHA_INDEX):
|
|
49
|
+
with open(PLANILHA_INDEX, 'r', encoding='utf-8') as f:
|
|
50
|
+
return json.load(f)
|
|
51
|
+
return {"entries": [], "timestamp": None}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def get_existing_tags(index, prefix):
|
|
55
|
+
"""Retorna todas as TAGs existentes para um prefixo."""
|
|
56
|
+
tags = set()
|
|
57
|
+
for entry in index.get('entries', []):
|
|
58
|
+
tag = entry.get('tag', '')
|
|
59
|
+
if tag.startswith(prefix + "-"):
|
|
60
|
+
tags.add(tag)
|
|
61
|
+
return tags
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def generate_next_tag(prefix, existing_tags):
|
|
65
|
+
"""Gera próxima TAG sequencial para um prefixo."""
|
|
66
|
+
max_num = 0
|
|
67
|
+
for tag in existing_tags:
|
|
68
|
+
if tag.startswith(prefix + "-"):
|
|
69
|
+
try:
|
|
70
|
+
num_part = tag.split("-")[-1]
|
|
71
|
+
num = int(num_part)
|
|
72
|
+
if num > max_num:
|
|
73
|
+
max_num = num
|
|
74
|
+
except ValueError:
|
|
75
|
+
continue
|
|
76
|
+
return f"{prefix}-{str(max_num + 1).zfill(4)}"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def identify_untagged_entries(delta_entries, index):
|
|
80
|
+
"""Identifica entradas que precisam de TAG."""
|
|
81
|
+
untagged = []
|
|
82
|
+
|
|
83
|
+
for entry in delta_entries:
|
|
84
|
+
if entry.get('tag') and entry['tag'].strip():
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
sheet_name = entry.get('sheet', '')
|
|
88
|
+
prefix = SHEET_TO_PREFIX.get(sheet_name)
|
|
89
|
+
|
|
90
|
+
if not prefix:
|
|
91
|
+
for sheet, pf in SHEET_TO_PREFIX.items():
|
|
92
|
+
if sheet.lower() in sheet_name.lower():
|
|
93
|
+
prefix = pf
|
|
94
|
+
break
|
|
95
|
+
|
|
96
|
+
if prefix:
|
|
97
|
+
untagged.append({
|
|
98
|
+
'entry': entry,
|
|
99
|
+
'prefix': prefix,
|
|
100
|
+
'sheet': sheet_name
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
return untagged
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def prepare_tag_operations(untagged, index):
|
|
107
|
+
"""Prepara operações de tagueamento para MCP."""
|
|
108
|
+
operations = []
|
|
109
|
+
by_prefix = {}
|
|
110
|
+
|
|
111
|
+
for item in untagged:
|
|
112
|
+
prefix = item['prefix']
|
|
113
|
+
if prefix not in by_prefix:
|
|
114
|
+
by_prefix[prefix] = []
|
|
115
|
+
by_prefix[prefix].append(item)
|
|
116
|
+
|
|
117
|
+
for prefix, items in by_prefix.items():
|
|
118
|
+
existing_tags = get_existing_tags(index, prefix)
|
|
119
|
+
|
|
120
|
+
for item in items:
|
|
121
|
+
new_tag = generate_next_tag(prefix, existing_tags)
|
|
122
|
+
existing_tags.add(new_tag)
|
|
123
|
+
|
|
124
|
+
entry = item['entry']
|
|
125
|
+
operations.append({
|
|
126
|
+
'type': 'write_tag',
|
|
127
|
+
'spreadsheet_id': entry.get('spreadsheet_id'),
|
|
128
|
+
'sheet_name': item['sheet'],
|
|
129
|
+
'row': entry.get('row'),
|
|
130
|
+
'column': TAG_COLUMN,
|
|
131
|
+
'range': f"'{item['sheet']}'!{TAG_COLUMN}{entry.get('row')}",
|
|
132
|
+
'value': new_tag,
|
|
133
|
+
'original_name': entry.get('name', ''),
|
|
134
|
+
'prefix': prefix
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
return operations
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def generate_tag_report(operations):
|
|
141
|
+
"""Gera relatório de operações de tagueamento."""
|
|
142
|
+
report = {
|
|
143
|
+
'timestamp': datetime.now().isoformat(),
|
|
144
|
+
'total_operations': len(operations),
|
|
145
|
+
'by_prefix': {},
|
|
146
|
+
'operations': operations
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
for op in operations:
|
|
150
|
+
prefix = op['prefix']
|
|
151
|
+
if prefix not in report['by_prefix']:
|
|
152
|
+
report['by_prefix'][prefix] = 0
|
|
153
|
+
report['by_prefix'][prefix] += 1
|
|
154
|
+
|
|
155
|
+
return report
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def main(delta_entries=None, preview=True):
|
|
159
|
+
"""Função principal do tagger."""
|
|
160
|
+
index = load_planilha_index()
|
|
161
|
+
|
|
162
|
+
if delta_entries is None:
|
|
163
|
+
print("PLANILHA TAGGER - Modo Standalone")
|
|
164
|
+
print("Passe delta_entries para executar.")
|
|
165
|
+
return None
|
|
166
|
+
|
|
167
|
+
untagged = identify_untagged_entries(delta_entries, index)
|
|
168
|
+
|
|
169
|
+
if not untagged:
|
|
170
|
+
print("✅ Todas as entradas já possuem TAG!")
|
|
171
|
+
return []
|
|
172
|
+
|
|
173
|
+
operations = prepare_tag_operations(untagged, index)
|
|
174
|
+
report = generate_tag_report(operations)
|
|
175
|
+
|
|
176
|
+
print(f"TAGs a escrever: {report['total_operations']}")
|
|
177
|
+
for prefix, count in sorted(report['by_prefix'].items()):
|
|
178
|
+
print(f" {prefix}: {count}")
|
|
179
|
+
|
|
180
|
+
if preview:
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
return operations
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
if __name__ == '__main__':
|
|
187
|
+
main()
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
REVERT - Remove TAGs incorretas dos arquivos
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
INBOX_PATH = "inbox"
|
|
11
|
+
|
|
12
|
+
def revert_tags():
|
|
13
|
+
print("=" * 60)
|
|
14
|
+
print("REVERTENDO TAGS INCORRETAS")
|
|
15
|
+
print("=" * 60)
|
|
16
|
+
|
|
17
|
+
# Encontrar arquivos com TAG
|
|
18
|
+
tagged_files = []
|
|
19
|
+
pattern = re.compile(r'^\[[\w-]+\]\s*')
|
|
20
|
+
|
|
21
|
+
for root, dirs, files in os.walk(INBOX_PATH):
|
|
22
|
+
if '_BACKUP' in root or '_TEMPLATE' in root:
|
|
23
|
+
continue
|
|
24
|
+
for filename in files:
|
|
25
|
+
if pattern.match(filename):
|
|
26
|
+
tagged_files.append(Path(root) / filename)
|
|
27
|
+
|
|
28
|
+
print(f"\nEncontrados: {len(tagged_files)} arquivos com TAG")
|
|
29
|
+
|
|
30
|
+
# Reverter
|
|
31
|
+
success = 0
|
|
32
|
+
errors = []
|
|
33
|
+
|
|
34
|
+
for filepath in tagged_files:
|
|
35
|
+
old_name = filepath.name
|
|
36
|
+
# Remove [TAG] do início
|
|
37
|
+
new_name = pattern.sub('', old_name)
|
|
38
|
+
new_path = filepath.parent / new_name
|
|
39
|
+
|
|
40
|
+
# Verificar se destino já existe
|
|
41
|
+
if new_path.exists():
|
|
42
|
+
errors.append({'path': str(filepath), 'error': f'Destino já existe: {new_name}'})
|
|
43
|
+
continue
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
filepath.rename(new_path)
|
|
47
|
+
success += 1
|
|
48
|
+
if success % 50 == 0:
|
|
49
|
+
print(f" Revertidos: {success}/{len(tagged_files)}")
|
|
50
|
+
except Exception as e:
|
|
51
|
+
errors.append({'path': str(filepath), 'error': str(e)})
|
|
52
|
+
|
|
53
|
+
print()
|
|
54
|
+
print("=" * 60)
|
|
55
|
+
print("RESULTADO")
|
|
56
|
+
print("=" * 60)
|
|
57
|
+
print(f" Sucesso: {success}")
|
|
58
|
+
print(f" Erros: {len(errors)}")
|
|
59
|
+
|
|
60
|
+
if errors:
|
|
61
|
+
print("\nERROS:")
|
|
62
|
+
for e in errors[:20]:
|
|
63
|
+
print(f" - {e['path']}: {e['error']}")
|
|
64
|
+
if len(errors) > 20:
|
|
65
|
+
print(f" ... e mais {len(errors) - 20} erros")
|
|
66
|
+
|
|
67
|
+
return success, errors
|
|
68
|
+
|
|
69
|
+
if __name__ == '__main__':
|
|
70
|
+
revert_tags()
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
SOURCE SYNC - Detecção de Delta e Sincronização com Planilha
|
|
4
|
+
=============================================================
|
|
5
|
+
|
|
6
|
+
Este script:
|
|
7
|
+
1. Carrega o snapshot local (PLANILHA-INDEX.json)
|
|
8
|
+
2. Compara com o estado atual da planilha (via MCP)
|
|
9
|
+
3. Detecta arquivos NOVOS (delta)
|
|
10
|
+
4. Gera relatório visual
|
|
11
|
+
5. Opcionalmente executa tagueamento + download
|
|
12
|
+
|
|
13
|
+
Uso:
|
|
14
|
+
python source-sync.py --check # Apenas verificar
|
|
15
|
+
python source-sync.py --execute # Verificar + baixar
|
|
16
|
+
python source-sync.py --source=JM # Filtrar por fonte
|
|
17
|
+
|
|
18
|
+
Autor: JARVIS
|
|
19
|
+
Versão: 1.0.0
|
|
20
|
+
Data: 2026-01-13
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import json
|
|
24
|
+
import os
|
|
25
|
+
import sys
|
|
26
|
+
from datetime import datetime
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
from typing import Dict, List, Optional, Tuple
|
|
29
|
+
|
|
30
|
+
# =============================================================================
|
|
31
|
+
# CONFIGURAÇÃO
|
|
32
|
+
# =============================================================================
|
|
33
|
+
|
|
34
|
+
MEGA_BRAIN_ROOT = Path(".")
|
|
35
|
+
MISSION_CONTROL = MEGA_BRAIN_ROOT / ".claude" / "mission-control"
|
|
36
|
+
INBOX_ROOT = MEGA_BRAIN_ROOT / "inbox"
|
|
37
|
+
|
|
38
|
+
# Arquivos de estado
|
|
39
|
+
PLANILHA_INDEX_FILE = MISSION_CONTROL / "PLANILHA-INDEX.json"
|
|
40
|
+
SYNC_STATE_FILE = MISSION_CONTROL / "SOURCE-SYNC-STATE.json"
|
|
41
|
+
DELTA_PENDING_FILE = MISSION_CONTROL / "DELTA-PENDING.json"
|
|
42
|
+
|
|
43
|
+
# ID da planilha principal
|
|
44
|
+
PLANILHA_ID = "1lVj2t1Ej97q1MTmFXR9NZUvGWxgv-RYXQ0SjZEGl7N4"
|
|
45
|
+
|
|
46
|
+
# =============================================================================
|
|
47
|
+
# MAPEAMENTO ABA → PREFIXO
|
|
48
|
+
# =============================================================================
|
|
49
|
+
|
|
50
|
+
SHEET_TO_PREFIX: Dict[str, str] = {
|
|
51
|
+
"Jeremy Miner": "JM",
|
|
52
|
+
"Jeremy Haynes Sales Training": "JH-ST",
|
|
53
|
+
"Jeremy Haynes Inner Circle": "JH-IC",
|
|
54
|
+
"Inner Circle Weekly Group Call Recordings": "JH-WK",
|
|
55
|
+
"Agency Blueprint": "AOBA",
|
|
56
|
+
"Cold Video Pitch": "PCVP",
|
|
57
|
+
"Land Your First Agency Client": "LYFC",
|
|
58
|
+
"Marketer Mindset Masterclass": "MMM",
|
|
59
|
+
"30 Days Challenge": "30DC",
|
|
60
|
+
"Scale The Agency": "STA",
|
|
61
|
+
"Ultra High Ticket Closer": "UHTC",
|
|
62
|
+
"The Scalable Company": "TSC",
|
|
63
|
+
"Cole Gordon": "CG",
|
|
64
|
+
"Sales Training BR": "EDC",
|
|
65
|
+
"Alex Hormozi": "AH",
|
|
66
|
+
"Jeremy Haynes Program": "CA",
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
# Mapeamento reverso para agrupamento
|
|
70
|
+
PREFIX_TO_SOURCE: Dict[str, str] = {
|
|
71
|
+
"JM": "JEREMY MINER",
|
|
72
|
+
"JH-ST": "JEREMY HAYNES (SALES TRAINING)",
|
|
73
|
+
"JH-IC": "JEREMY HAYNES (INNER CIRCLE)",
|
|
74
|
+
"JH-WK": "JEREMY HAYNES (WEEKLY CALLS)",
|
|
75
|
+
"AOBA": "AGENCY OWNERS BLUEPRINT",
|
|
76
|
+
"PCVP": "PERFECT COLD VIDEO PITCH",
|
|
77
|
+
"LYFC": "LAND YOUR FIRST CLIENT",
|
|
78
|
+
"MMM": "MARKETER MINDSET",
|
|
79
|
+
"30DC": "30 DAYS CHALLENGE",
|
|
80
|
+
"STA": "SCALE THE AGENCY",
|
|
81
|
+
"UHTC": "ULTRA HIGH TICKET CLOSER",
|
|
82
|
+
"TSC": "THE SCALABLE COMPANY",
|
|
83
|
+
"CG": "COLE GORDON",
|
|
84
|
+
"EDC": "SALES TRAINING BR",
|
|
85
|
+
"AH": "ALEX HORMOZI",
|
|
86
|
+
"CA": "JEREMY HAYNES PROGRAM",
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# =============================================================================
|
|
90
|
+
# FUNÇÕES AUXILIARES
|
|
91
|
+
# =============================================================================
|
|
92
|
+
|
|
93
|
+
def load_json(path: Path) -> dict:
|
|
94
|
+
"""Carrega arquivo JSON com tratamento de erro."""
|
|
95
|
+
if not path.exists():
|
|
96
|
+
return {}
|
|
97
|
+
try:
|
|
98
|
+
with open(path, 'r', encoding='utf-8') as f:
|
|
99
|
+
return json.load(f)
|
|
100
|
+
except json.JSONDecodeError:
|
|
101
|
+
print(f"⚠️ Erro ao ler {path}")
|
|
102
|
+
return {}
|
|
103
|
+
|
|
104
|
+
def save_json(data: dict, path: Path) -> None:
|
|
105
|
+
"""Salva dados em arquivo JSON."""
|
|
106
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
107
|
+
with open(path, 'w', encoding='utf-8') as f:
|
|
108
|
+
json.dump(data, f, ensure_ascii=False, indent=2)
|
|
109
|
+
|
|
110
|
+
def generate_next_tag(prefix: str, existing_tags: List[str]) -> str:
|
|
111
|
+
"""Gera próxima TAG sequencial para um prefixo."""
|
|
112
|
+
# Extrair números existentes para este prefixo
|
|
113
|
+
existing_nums = []
|
|
114
|
+
for tag in existing_tags:
|
|
115
|
+
if tag.startswith(prefix + "-"):
|
|
116
|
+
try:
|
|
117
|
+
num = int(tag.split("-")[-1])
|
|
118
|
+
existing_nums.append(num)
|
|
119
|
+
except ValueError:
|
|
120
|
+
continue
|
|
121
|
+
|
|
122
|
+
# Próximo número
|
|
123
|
+
next_num = max(existing_nums, default=0) + 1
|
|
124
|
+
return f"{prefix}-{next_num:04d}"
|
|
125
|
+
|
|
126
|
+
# =============================================================================
|
|
127
|
+
# FUNÇÕES PRINCIPAIS
|
|
128
|
+
# =============================================================================
|
|
129
|
+
|
|
130
|
+
def load_snapshot() -> dict:
|
|
131
|
+
"""Carrega snapshot local da planilha."""
|
|
132
|
+
snapshot = load_json(PLANILHA_INDEX_FILE)
|
|
133
|
+
if not snapshot:
|
|
134
|
+
snapshot = {
|
|
135
|
+
"entries": [],
|
|
136
|
+
"timestamp": None,
|
|
137
|
+
"total_count": 0
|
|
138
|
+
}
|
|
139
|
+
return snapshot
|
|
140
|
+
|
|
141
|
+
def get_snapshot_tags(snapshot: dict) -> set:
|
|
142
|
+
"""Extrai conjunto de TAGs do snapshot."""
|
|
143
|
+
return {entry.get("tag") for entry in snapshot.get("entries", []) if entry.get("tag")}
|
|
144
|
+
|
|
145
|
+
def detect_delta(current_entries: List[dict], snapshot_tags: set) -> Tuple[List[dict], List[dict]]:
|
|
146
|
+
"""
|
|
147
|
+
Detecta delta entre estado atual e snapshot.
|
|
148
|
+
|
|
149
|
+
Retorna:
|
|
150
|
+
- novos_com_tag: Arquivos novos que JÁ têm TAG na planilha
|
|
151
|
+
- novos_sem_tag: Arquivos novos que PRECISAM de TAG
|
|
152
|
+
"""
|
|
153
|
+
novos_com_tag = []
|
|
154
|
+
novos_sem_tag = []
|
|
155
|
+
|
|
156
|
+
for entry in current_entries:
|
|
157
|
+
tag = entry.get("tag")
|
|
158
|
+
|
|
159
|
+
# Se não está no snapshot, é novo
|
|
160
|
+
if tag and tag not in snapshot_tags:
|
|
161
|
+
novos_com_tag.append(entry)
|
|
162
|
+
elif not tag:
|
|
163
|
+
novos_sem_tag.append(entry)
|
|
164
|
+
|
|
165
|
+
return novos_com_tag, novos_sem_tag
|
|
166
|
+
|
|
167
|
+
def group_by_source(entries: List[dict]) -> Dict[str, List[dict]]:
|
|
168
|
+
"""Agrupa entries por fonte/aba."""
|
|
169
|
+
grouped = {}
|
|
170
|
+
for entry in entries:
|
|
171
|
+
sheet = entry.get("sheet", "UNKNOWN")
|
|
172
|
+
if sheet not in grouped:
|
|
173
|
+
grouped[sheet] = []
|
|
174
|
+
grouped[sheet].append(entry)
|
|
175
|
+
return grouped
|
|
176
|
+
|
|
177
|
+
def print_report(novos_com_tag: List[dict], novos_sem_tag: List[dict]) -> None:
|
|
178
|
+
"""Exibe relatório visual do delta detectado."""
|
|
179
|
+
total_novos = len(novos_com_tag) + len(novos_sem_tag)
|
|
180
|
+
|
|
181
|
+
print()
|
|
182
|
+
print("╔" + "═" * 78 + "╗")
|
|
183
|
+
print("║" + "SOURCE SYNC - RELATÓRIO DE DELTA".center(78) + "║")
|
|
184
|
+
print("╠" + "═" * 78 + "╣")
|
|
185
|
+
print(f"║ NOVOS ARQUIVOS DETECTADOS: {total_novos:<48}║")
|
|
186
|
+
print("║" + " " * 78 + "║")
|
|
187
|
+
|
|
188
|
+
# Agrupar por fonte
|
|
189
|
+
all_novos = novos_com_tag + novos_sem_tag
|
|
190
|
+
grouped = group_by_source(all_novos)
|
|
191
|
+
|
|
192
|
+
print("║ POR FONTE:" + " " * 66 + "║")
|
|
193
|
+
for sheet, entries in sorted(grouped.items()):
|
|
194
|
+
prefix = SHEET_TO_PREFIX.get(sheet, "??")
|
|
195
|
+
line = f" ├── {sheet[:30]:<30} ({prefix}): {len(entries):>3} novos"
|
|
196
|
+
print(f"║{line:<78}║")
|
|
197
|
+
|
|
198
|
+
print("║" + " " * 78 + "║")
|
|
199
|
+
print("║ AÇÕES NECESSÁRIAS:" + " " * 58 + "║")
|
|
200
|
+
print(f"║ ├── TAGs a gerar: {len(novos_sem_tag):<3} (arquivos sem TAG)" + " " * 27 + "║")
|
|
201
|
+
print(f"║ ├── Downloads: {total_novos:<3} arquivos" + " " * 34 + "║")
|
|
202
|
+
print("║ └── Destino: inbox/[FONTE]/[TIPO]/" + " " * 38 + "║")
|
|
203
|
+
print("╚" + "═" * 78 + "╝")
|
|
204
|
+
print()
|
|
205
|
+
|
|
206
|
+
def update_sync_state(novos_count: int, status: str = "CHECKED") -> None:
|
|
207
|
+
"""Atualiza estado da sincronização."""
|
|
208
|
+
state = {
|
|
209
|
+
"last_sync": datetime.now().isoformat(),
|
|
210
|
+
"last_status": status,
|
|
211
|
+
"last_delta_count": novos_count,
|
|
212
|
+
"planilha_id": PLANILHA_ID
|
|
213
|
+
}
|
|
214
|
+
save_json(state, SYNC_STATE_FILE)
|
|
215
|
+
|
|
216
|
+
def save_delta_pending(novos_com_tag: List[dict], novos_sem_tag: List[dict]) -> None:
|
|
217
|
+
"""Salva delta pendente para processamento posterior."""
|
|
218
|
+
delta = {
|
|
219
|
+
"timestamp": datetime.now().isoformat(),
|
|
220
|
+
"com_tag": novos_com_tag,
|
|
221
|
+
"sem_tag": novos_sem_tag,
|
|
222
|
+
"total": len(novos_com_tag) + len(novos_sem_tag)
|
|
223
|
+
}
|
|
224
|
+
save_json(delta, DELTA_PENDING_FILE)
|
|
225
|
+
|
|
226
|
+
# =============================================================================
|
|
227
|
+
# MAIN
|
|
228
|
+
# =============================================================================
|
|
229
|
+
|
|
230
|
+
def main():
|
|
231
|
+
"""Função principal - executa detecção de delta."""
|
|
232
|
+
print("\n" + "=" * 80)
|
|
233
|
+
print("SOURCE SYNC - Detecção de Delta")
|
|
234
|
+
print("=" * 80)
|
|
235
|
+
|
|
236
|
+
# 1. Carregar snapshot
|
|
237
|
+
print("\n📁 Carregando snapshot local...")
|
|
238
|
+
snapshot = load_snapshot()
|
|
239
|
+
snapshot_tags = get_snapshot_tags(snapshot)
|
|
240
|
+
print(f" → {len(snapshot_tags)} TAGs no snapshot")
|
|
241
|
+
|
|
242
|
+
# 2. NOTA: A leitura real da planilha deve ser feita via MCP no Claude
|
|
243
|
+
print("\n⚠️ Este script prepara a estrutura de dados.")
|
|
244
|
+
print(" A leitura real da planilha deve ser feita via MCP gdrive.")
|
|
245
|
+
print(" Use o comando /source-sync no Claude para execução completa.")
|
|
246
|
+
|
|
247
|
+
# 3. Exibir estado atual
|
|
248
|
+
print("\n📊 Estado atual:")
|
|
249
|
+
print(f" → Snapshot: {PLANILHA_INDEX_FILE}")
|
|
250
|
+
print(f" → State: {SYNC_STATE_FILE}")
|
|
251
|
+
print(f" → Delta: {DELTA_PENDING_FILE}")
|
|
252
|
+
|
|
253
|
+
# 4. Verificar se há delta pendente
|
|
254
|
+
if DELTA_PENDING_FILE.exists():
|
|
255
|
+
delta = load_json(DELTA_PENDING_FILE)
|
|
256
|
+
if delta.get("total", 0) > 0:
|
|
257
|
+
print(f"\n⚠️ DELTA PENDENTE: {delta['total']} arquivos aguardando")
|
|
258
|
+
print(f" → Timestamp: {delta.get('timestamp', 'N/A')}")
|
|
259
|
+
|
|
260
|
+
print("\n" + "=" * 80)
|
|
261
|
+
print("Use /source-sync no Claude para sincronização completa via MCP")
|
|
262
|
+
print("=" * 80 + "\n")
|
|
263
|
+
|
|
264
|
+
if __name__ == "__main__":
|
|
265
|
+
main()
|