ocerebro 0.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +288 -0
  3. package/bin/ocerebro.js +98 -0
  4. package/cerebro/__init__.py +7 -0
  5. package/cerebro/__main__.py +19 -0
  6. package/cerebro/cerebro_setup.py +459 -0
  7. package/hooks/__init__.py +1 -0
  8. package/hooks/cost_hook.py +45 -0
  9. package/hooks/coverage_hook.py +39 -0
  10. package/hooks/error_hook.py +48 -0
  11. package/hooks/expensive_hook.py +41 -0
  12. package/hooks/global_logger.py +32 -0
  13. package/package.json +49 -0
  14. package/pyproject.toml +77 -0
  15. package/src/__init__.py +2 -0
  16. package/src/cli/__init__.py +2 -0
  17. package/src/cli/dream.py +91 -0
  18. package/src/cli/gc.py +93 -0
  19. package/src/cli/main.py +583 -0
  20. package/src/cli/remember.py +74 -0
  21. package/src/consolidation/__init__.py +8 -0
  22. package/src/consolidation/checkpoints.py +96 -0
  23. package/src/consolidation/dream.py +465 -0
  24. package/src/consolidation/extractor.py +313 -0
  25. package/src/consolidation/promoter.py +435 -0
  26. package/src/consolidation/remember.py +544 -0
  27. package/src/consolidation/scorer.py +191 -0
  28. package/src/core/__init__.py +6 -0
  29. package/src/core/event_schema.py +55 -0
  30. package/src/core/jsonl_storage.py +238 -0
  31. package/src/core/paths.py +254 -0
  32. package/src/core/session_manager.py +76 -0
  33. package/src/diff/__init__.py +5 -0
  34. package/src/diff/memory_diff.py +571 -0
  35. package/src/forgetting/__init__.py +6 -0
  36. package/src/forgetting/decay.py +86 -0
  37. package/src/forgetting/gc.py +296 -0
  38. package/src/forgetting/guard_rails.py +126 -0
  39. package/src/hooks/__init__.py +11 -0
  40. package/src/hooks/core_captures.py +170 -0
  41. package/src/hooks/custom_loader.py +389 -0
  42. package/src/index/__init__.py +7 -0
  43. package/src/index/embeddings_db.py +419 -0
  44. package/src/index/metadata_db.py +230 -0
  45. package/src/index/queries.py +357 -0
  46. package/src/mcp/__init__.py +2 -0
  47. package/src/mcp/server.py +640 -0
  48. package/src/memdir/__init__.py +19 -0
  49. package/src/memdir/scanner.py +260 -0
  50. package/src/official/__init__.py +5 -0
  51. package/src/official/markdown_storage.py +173 -0
  52. package/src/official/templates.py +128 -0
  53. package/src/working/__init__.py +5 -0
  54. package/src/working/memory_view.py +150 -0
  55. package/src/working/yaml_storage.py +234 -0
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "ocerebro",
3
+ "version": "0.1.0",
4
+ "description": "OCerebro - Sistema de Memoria para Agentes (Claude Code/MCP)",
5
+ "main": "bin/ocerebro.js",
6
+ "bin": {
7
+ "ocerebro": "bin/ocerebro.js"
8
+ },
9
+ "scripts": {
10
+ "test": "echo \"Run Python tests with: pytest\" && exit 0"
11
+ },
12
+ "keywords": [
13
+ "claude",
14
+ "claude-code",
15
+ "memory",
16
+ "ai",
17
+ "agent",
18
+ "mcp"
19
+ ],
20
+ "author": "OARANHA",
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/OARANHA/ocerebro.git"
25
+ },
26
+ "homepage": "https://github.com/OARANHA/ocerebro#readme",
27
+ "bugs": {
28
+ "url": "https://github.com/OARANHA/ocerebro/issues"
29
+ },
30
+ "engines": {
31
+ "node": ">=16.0.0"
32
+ },
33
+ "files": [
34
+ "bin/",
35
+ "src/",
36
+ "cerebro/",
37
+ "hooks/",
38
+ "pyproject.toml",
39
+ "README.md",
40
+ "LICENSE",
41
+ "!**/__pycache__/**",
42
+ "!**/*.pyc",
43
+ "!**/*.pyo",
44
+ "!cerebro/config.yaml"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ }
49
+ }
package/pyproject.toml ADDED
@@ -0,0 +1,77 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ocerebro"
7
+ version = "0.1.0"
8
+ description = "OCerebro - Sistema de Memoria para Agentes (Claude Code/MCP)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ authors = [
12
+ {name = "OARANHA", email = "seu-aranha.com@gmail.com"}
13
+ ]
14
+ keywords = [
15
+ "claude",
16
+ "claude-code",
17
+ "memory",
18
+ "ai",
19
+ "agent",
20
+ "mcp",
21
+ "sqlite",
22
+ "sqlite-vec",
23
+ ]
24
+ classifiers = [
25
+ "Development Status :: 3 - Alpha",
26
+ "Intended Audience :: Developers",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Programming Language :: Python :: 3",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ ]
33
+ dependencies = [
34
+ "pyyaml>=6.0",
35
+ "pydantic>=2.0",
36
+ "sqlite-vec>=0.1.0",
37
+ "sentence-transformers>=2.2.0",
38
+ "mcp>=1.0.0",
39
+ "anthropic>=0.40.0",
40
+ ]
41
+
42
+ [project.optional-dependencies]
43
+ test = [
44
+ "pytest>=7.0",
45
+ "pytest-cov>=4.0",
46
+ ]
47
+ dev = [
48
+ "ocerebro[test]",
49
+ "black>=23.0",
50
+ "ruff>=0.1.0",
51
+ ]
52
+
53
+ [project.urls]
54
+ Homepage = "https://github.com/OARANHA/ocerebro"
55
+ Repository = "https://github.com/OARANHA/ocerebro.git"
56
+ Documentation = "https://github.com/OARANHA/ocerebro#readme"
57
+
58
+ [project.scripts]
59
+ ocerebro = "src.cli.main:main"
60
+ ocerebro-setup = "cerebro.cerebro_setup:main"
61
+
62
+ [tool.setuptools.packages.find]
63
+ where = ["."]
64
+ include = ["src*", "cerebro*"]
65
+
66
+ [tool.pytest.ini_options]
67
+ testpaths = ["tests"]
68
+ python_files = "test_*.py"
69
+ addopts = "-v --tb=short"
70
+
71
+ [tool.ruff]
72
+ line-length = 100
73
+ target-version = "py310"
74
+
75
+ [tool.ruff.lint]
76
+ select = ["E", "F", "W", "I"]
77
+ ignore = ["E501"]
@@ -0,0 +1,2 @@
1
+ """Cerebro - Sistema de Memória para Agentes de Código"""
2
+ __version__ = "0.1.0"
@@ -0,0 +1,2 @@
1
+ """CLI do Cerebro"""
2
+ __version__ = "0.1.0"
@@ -0,0 +1,91 @@
1
+ """Comando cerebro dream - Extração automática de memórias.
2
+
3
+ Replica o comando extractMemories do Claude Code (bloqueado por tengu_passport_quail=false).
4
+
5
+ Uso:
6
+ cerebro dream # Extrai memórias dos últimos 7 dias (dry-run)
7
+ cerebro dream --since 14 # Extrai memórias dos últimos 14 dias
8
+ cerebro dream --apply # Aplica extração diretamente
9
+ """
10
+
11
+ import argparse
12
+ from pathlib import Path
13
+ from typing import Optional
14
+
15
+ from src.core.paths import get_auto_mem_path
16
+ from src.consolidation.dream import run_dream, generate_dream_report
17
+
18
+
19
+ def cmd_dream(
20
+ project_root: Optional[Path] = None,
21
+ since_days: int = 7,
22
+ dry_run: bool = True
23
+ ) -> str:
24
+ """
25
+ Executa extração automática de memórias (dream).
26
+
27
+ Args:
28
+ project_root: Raiz do projeto (default: git root)
29
+ since_days: Dias para analisar (default: 7)
30
+ dry_run: Se True, apenas simula, não modifica nada
31
+
32
+ Returns:
33
+ Relatório da extração
34
+ """
35
+ # Resolve memory_dir
36
+ memory_dir = get_auto_mem_path(project_root)
37
+
38
+ # Executa dream
39
+ result = run_dream(
40
+ memory_dir=memory_dir,
41
+ since_days=since_days,
42
+ dry_run=dry_run
43
+ )
44
+
45
+ # Gera relatório
46
+ return generate_dream_report(result)
47
+
48
+
49
+ def main():
50
+ """Entry point do comando dream"""
51
+ parser = argparse.ArgumentParser(
52
+ prog="cerebro dream",
53
+ description="Extração automática de memórias (replica extractMemories do Claude Code)"
54
+ )
55
+
56
+ parser.add_argument(
57
+ "--since",
58
+ type=int,
59
+ default=7,
60
+ dest="since_days",
61
+ help="Dias para analisar (padrão: 7)"
62
+ )
63
+
64
+ parser.add_argument(
65
+ "--apply",
66
+ action="store_true",
67
+ dest="apply",
68
+ help="Aplicar extração (padrão: dry-run)"
69
+ )
70
+
71
+ parser.add_argument(
72
+ "--project",
73
+ type=Path,
74
+ default=None,
75
+ dest="project_root",
76
+ help="Raiz do projeto (padrão: git root)"
77
+ )
78
+
79
+ args = parser.parse_args()
80
+
81
+ result = cmd_dream(
82
+ project_root=args.project_root,
83
+ since_days=args.since_days,
84
+ dry_run=not args.apply
85
+ )
86
+
87
+ print(result)
88
+
89
+
90
+ if __name__ == "__main__":
91
+ main()
package/src/cli/gc.py ADDED
@@ -0,0 +1,93 @@
1
+ """Comando cerebro gc - Garbage collection de memórias.
2
+
3
+ Replica a lógica de garbage collection do Claude Code baseada em mtime.
4
+
5
+ Uso:
6
+ cerebro gc # Lista candidatas (dry-run)
7
+ cerebro gc --threshold 14 # Threshold de 14 dias
8
+ cerebro gc --apply # Aplica GC diretamente
9
+ """
10
+
11
+ import argparse
12
+ from pathlib import Path
13
+ from typing import Optional
14
+
15
+ from src.core.paths import get_auto_mem_path
16
+ from src.forgetting.gc import GarbageCollector
17
+
18
+
19
+ def cmd_gc(
20
+ project_root: Optional[Path] = None,
21
+ threshold_days: int = 7,
22
+ dry_run: bool = True
23
+ ) -> str:
24
+ """
25
+ Executa garbage collection de memórias.
26
+
27
+ Args:
28
+ project_root: Raiz do projeto (default: git root)
29
+ threshold_days: Dias para considerar memória stale (default: 7)
30
+ dry_run: Se True, apenas lista candidatas, não remove
31
+
32
+ Returns:
33
+ Relatório do GC
34
+ """
35
+ # Resolve memory_dir
36
+ memory_dir = get_auto_mem_path(project_root)
37
+
38
+ # Executa GC
39
+ gc = GarbageCollector(memory_dir)
40
+ results = gc.run_gc(
41
+ memory_dir=memory_dir,
42
+ archive_threshold_days=threshold_days,
43
+ deletion_threshold_days=threshold_days * 4, # 4x para deleção
44
+ dry_run=dry_run
45
+ )
46
+
47
+ # Gera relatório
48
+ return gc.generate_gc_report(results)
49
+
50
+
51
+ def main():
52
+ """Entry point do comando gc"""
53
+ parser = argparse.ArgumentParser(
54
+ prog="cerebro gc",
55
+ description="Garbage collection de memórias"
56
+ )
57
+
58
+ parser.add_argument(
59
+ "--threshold",
60
+ type=int,
61
+ default=7,
62
+ dest="threshold_days",
63
+ help="Dias para considerar memória stale (padrão: 7)"
64
+ )
65
+
66
+ parser.add_argument(
67
+ "--apply",
68
+ action="store_true",
69
+ dest="apply",
70
+ help="Aplicar GC (padrão: dry-run)"
71
+ )
72
+
73
+ parser.add_argument(
74
+ "--project",
75
+ type=Path,
76
+ default=None,
77
+ dest="project_root",
78
+ help="Raiz do projeto (padrão: git root)"
79
+ )
80
+
81
+ args = parser.parse_args()
82
+
83
+ result = cmd_gc(
84
+ project_root=args.project_root,
85
+ threshold_days=args.threshold_days,
86
+ dry_run=not args.apply
87
+ )
88
+
89
+ print(result)
90
+
91
+
92
+ if __name__ == "__main__":
93
+ main()