ocerebro 0.2.1 → 0.2.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocerebro",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "OCerebro - Sistema de Memoria para Agentes (Claude Code/MCP)",
5
5
  "main": "bin/ocerebro.js",
6
6
  "bin": {
package/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ocerebro"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "OCerebro - Sistema de Memoria para Agentes (Claude Code/MCP)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
package/src/mcp/server.py CHANGED
@@ -296,20 +296,16 @@ class CerebroMCP:
296
296
  ),
297
297
  Tool(
298
298
  name="cerebro_capture_memory",
299
- description="Captura memórias da conversa atual e salva nos arquivos - requer prompt do cerebro_dream",
299
+ description="Salva uma memória diretamente em ~/.claude/memory/ (formato nativo Claude Code). Chame uma vez por memória com o conteúdo Markdown completo.",
300
300
  inputSchema={
301
301
  "type": "object",
302
302
  "properties": {
303
- "prompt": {
303
+ "memory_content": {
304
304
  "type": "string",
305
- "description": "Prompt de extração retornado por cerebro_dream"
306
- },
307
- "memory_dir": {
308
- "type": "string",
309
- "description": "Diretório de memória (opcional)"
305
+ "description": "Conteúdo Markdown completo com frontmatter obrigatório: name, description, type (user|feedback|project|reference)"
310
306
  }
311
307
  },
312
- "required": ["prompt"]
308
+ "required": ["memory_content"]
313
309
  }
314
310
  ),
315
311
  Tool(
@@ -651,40 +647,53 @@ class CerebroMCP:
651
647
  {full_prompt}
652
648
 
653
649
  ---
654
- INSTRUÇÃO: Copie este prompt e use a ferramenta cerebro_capture_memory com:
655
- {{"prompt": "<cole o prompt acima>"}}
650
+ INSTRUÇÃO CRÍTICA: Analise esta conversa usando o prompt acima.
651
+ Para CADA memória identificada, chame cerebro_capture_memory UMA vez:
652
+
653
+ cerebro_capture_memory(memory_content="---\\nname: <nome>\\ndescription: <descrição>\\ntype: <user|feedback|project|reference>\\n---\\n\\n<conteúdo>")
656
654
 
657
- Ou execute manualmente: ocerebro dream --since {since_days} --apply
655
+ NÃO use FileWrite. NÃO use FileEdit. APENAS cerebro_capture_memory.
656
+ Uma chamada por memória. O sistema salva e indexa automaticamente.
658
657
  """
659
658
 
660
659
  def _capture_memory(self, args: Dict[str, Any]) -> str:
661
- """Captura memórias usando o prompt fornecido.
662
-
663
- Esta ferramenta deve ser chamada após cerebro_dream retornar o prompt.
664
- """
665
- prompt = args.get("prompt")
666
- if not prompt:
667
- return "Erro: 'prompt' é obrigatório para cerebro_capture_memory"
668
-
669
- memory_dir_str = args.get("memory_dir")
670
- memory_dir = Path(memory_dir_str) if memory_dir_str else get_auto_mem_path()
671
-
672
- # Instrui o Claude a usar o prompt para extrair memórias
673
- return f"""Prompt de extração recebido.
674
-
675
- Diretório de memória: {memory_dir}
676
-
677
- O Claude deve agora analisar a conversa usando este prompt e salvar as memórias
678
- nos arquivos .md apropriados em {memory_dir}
679
-
680
- Formato esperado:
681
- - user_*.md para memórias sobre o usuário
682
- - feedback_*.md para feedbacks e convenções
683
- - project_*.md para decisões e fatos do projeto
684
- - reference_*.md para ponteiros externos
660
+ """Salva uma memória no diretório nativo do Claude Code."""
661
+ import re
662
+ from datetime import datetime
663
+ from src.core.paths import get_memory_index
664
+
665
+ content = args.get("memory_content", "")
666
+ if not content:
667
+ return "Erro: 'memory_content' é obrigatório"
668
+
669
+ name_match = re.search(r'name:\s*(.*)', content)
670
+ if not name_match:
671
+ return "Erro: frontmatter 'name' é obrigatório no memory_content"
672
+
673
+ mem_name = name_match.group(1).strip().lower().replace(' ', '-')
674
+ mem_dir = get_auto_mem_path()
675
+ mem_dir.mkdir(parents=True, exist_ok=True)
676
+
677
+ file_path = mem_dir / f"{mem_name}.md"
678
+ file_path.write_text(content, encoding="utf-8")
679
+
680
+ desc_match = re.search(r'description:\s*(.*)', content)
681
+ type_match = re.search(r'type:\s*(.*)', content)
682
+ desc = desc_match.group(1).strip() if desc_match else "sem descrição"
683
+ m_type = type_match.group(1).strip() if type_match else "project"
684
+ ts = datetime.now().strftime("%Y-%m-%d")
685
+ entry = f"- [{m_type}] {mem_name}.md ({ts}): {desc}\n"
686
+
687
+ index_path = get_memory_index(mem_dir)
688
+ if index_path.exists():
689
+ existing = index_path.read_text(encoding="utf-8")
690
+ if mem_name not in existing:
691
+ with open(index_path, "a", encoding="utf-8") as f:
692
+ f.write(entry)
693
+ else:
694
+ index_path.write_text(f"# Memórias do Projeto\n\n{entry}", encoding="utf-8")
685
695
 
686
- Use FileWrite para criar os arquivos de memória.
687
- """
696
+ return f"✅ Memória '{mem_name}' salva em {file_path}"
688
697
 
689
698
  def _remember(self, args: Dict[str, Any]) -> str:
690
699
  """Revisão e promoção de memórias"""