ocerebro 0.4.8 → 0.4.9
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/cerebro/cerebro_setup.py +12 -7
- package/package.json +1 -1
- package/pyproject.toml +1 -1
- package/src/hooks/custom_loader.py +4 -1
- package/src/mcp/server.py +9 -4
package/cerebro/cerebro_setup.py
CHANGED
|
@@ -101,10 +101,11 @@ def find_claude_desktop_config() -> Path | None:
|
|
|
101
101
|
def get_ocerebro_path() -> Path:
|
|
102
102
|
"""Retorna o caminho absoluto do OCerebro instalado"""
|
|
103
103
|
# Tenta encontrar o package instalado via pip
|
|
104
|
+
# NOTA: O package se chama 'ocerebro' mas o modulo interno e 'cerebro'
|
|
104
105
|
try:
|
|
105
|
-
import
|
|
106
|
-
|
|
107
|
-
return
|
|
106
|
+
import ocerebro
|
|
107
|
+
ocerebro_path = Path(ocerebro.__file__).parent
|
|
108
|
+
return ocerebro_path.resolve()
|
|
108
109
|
except ImportError:
|
|
109
110
|
pass
|
|
110
111
|
|
|
@@ -132,16 +133,19 @@ def generate_mcp_config(ocerebro_path: Path) -> dict:
|
|
|
132
133
|
SECURITY: Não salva API keys no config file.
|
|
133
134
|
As variáveis de ambiente são herdadas do sistema.
|
|
134
135
|
Configure no seu shell: ~/.bashrc ou ~/.zshrc
|
|
136
|
+
|
|
137
|
+
WINDOWS FIX: Paths com espaços são tratados corretamente.
|
|
135
138
|
"""
|
|
136
139
|
|
|
137
|
-
# Determina o comando Python
|
|
140
|
+
# Determina o comando Python (path completo para evitar issues no Windows)
|
|
138
141
|
python_cmd = sys.executable
|
|
139
142
|
|
|
140
|
-
# Estratégia 1: usa python -m
|
|
143
|
+
# Estratégia 1: usa python -m src.mcp.server (robusto para pip install)
|
|
144
|
+
# NOTA: O cwd precisa ser path absoluto para evitar issues com paths relativos
|
|
141
145
|
mcp_config = {
|
|
142
146
|
"command": python_cmd,
|
|
143
147
|
"args": ["-m", "src.mcp.server"],
|
|
144
|
-
"cwd": str(ocerebro_path.parent),
|
|
148
|
+
"cwd": str(ocerebro_path.parent.resolve()), # resolve() para path absoluto
|
|
145
149
|
}
|
|
146
150
|
|
|
147
151
|
# Estratégia 2: path direto se arquivo existe
|
|
@@ -150,7 +154,8 @@ def generate_mcp_config(ocerebro_path: Path) -> dict:
|
|
|
150
154
|
mcp_server = ocerebro_path.parent / "src" / "mcp" / "server.py"
|
|
151
155
|
|
|
152
156
|
if mcp_server.exists():
|
|
153
|
-
|
|
157
|
+
# Usa path absoluto e resolved para spaces no Windows
|
|
158
|
+
mcp_config["args"] = [str(mcp_server.resolve())]
|
|
154
159
|
|
|
155
160
|
# SECURITY: NÃO salvar API keys no config
|
|
156
161
|
mcp_config["env"] = {}
|
package/package.json
CHANGED
package/pyproject.toml
CHANGED
|
@@ -79,6 +79,7 @@ class HooksLoader:
|
|
|
79
79
|
Carrega módulo Python dinamicamente.
|
|
80
80
|
|
|
81
81
|
SECURITY FIX: Valida path para evitar path traversal
|
|
82
|
+
WINDOWS FIX: Suporte a paths com espaços
|
|
82
83
|
|
|
83
84
|
Args:
|
|
84
85
|
module_path: Path do módulo relativo ao projeto
|
|
@@ -93,6 +94,7 @@ class HooksLoader:
|
|
|
93
94
|
if module_path in self._loaded_modules:
|
|
94
95
|
return self._loaded_modules[module_path]
|
|
95
96
|
|
|
97
|
+
# WINDOWS FIX: Usa resolve() para paths absolutos com espaços
|
|
96
98
|
# SECURITY: Resolve path absoluto e verifica se está dentro do diretório permitido
|
|
97
99
|
path = Path(module_path).resolve()
|
|
98
100
|
allowed_root = self.config_path.parent.resolve()
|
|
@@ -113,9 +115,10 @@ class HooksLoader:
|
|
|
113
115
|
if path.suffix != ".py":
|
|
114
116
|
raise ValueError(f"Hook deve ser arquivo .py: {path}")
|
|
115
117
|
|
|
118
|
+
# WINDOWS FIX: Usa str(path) em vez de path direto para evitar issues
|
|
116
119
|
spec = importlib.util.spec_from_file_location(
|
|
117
120
|
f"hook_{path.stem}",
|
|
118
|
-
path
|
|
121
|
+
str(path) # Converte para string para evitar issues no Windows
|
|
119
122
|
)
|
|
120
123
|
|
|
121
124
|
if spec is None or spec.loader is None:
|
package/src/mcp/server.py
CHANGED
|
@@ -105,12 +105,17 @@ class CerebroMCP:
|
|
|
105
105
|
self.raw_storage
|
|
106
106
|
)
|
|
107
107
|
|
|
108
|
-
# Inicializa hooks
|
|
109
|
-
#
|
|
108
|
+
# Inicializa hooks APENAS se .ocerebro existir e hooks.yaml estiver presente
|
|
109
|
+
# FIX: Não carrega hooks em projetos sem .ocerebro
|
|
110
110
|
hooks_config = self.cerebro_path.parent / "hooks.yaml"
|
|
111
111
|
try:
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
# Verifica se hooks.yaml existe antes de carregar
|
|
113
|
+
if hooks_config.exists():
|
|
114
|
+
self.hooks_loader = HooksLoader(hooks_config)
|
|
115
|
+
self.hooks_runner = HookRunner(self.hooks_loader)
|
|
116
|
+
else:
|
|
117
|
+
self.hooks_loader = None
|
|
118
|
+
self.hooks_runner = None
|
|
114
119
|
except Exception as e:
|
|
115
120
|
# WINDOWS FIX: Usa _safe_print_error para evitar UnicodeEncodeError
|
|
116
121
|
_safe_print_error(f"[CEREBRO] Aviso: hooks.yaml com erro ({e}). Hooks desativados.")
|