omni-cortex 1.3.0__py3-none-any.whl → 1.11.3__py3-none-any.whl
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.
- omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/.env.example +12 -0
- omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/backfill_summaries.py +280 -0
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/chat_service.py +19 -10
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/database.py +97 -18
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/image_service.py +21 -12
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/logging_config.py +34 -4
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/main.py +390 -13
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/models.py +64 -12
- omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/prompt_security.py +111 -0
- omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/security.py +104 -0
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/websocket_manager.py +24 -2
- omni_cortex-1.11.3.data/data/share/omni-cortex/hooks/post_tool_use.py +429 -0
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/hooks/pre_tool_use.py +52 -2
- omni_cortex-1.11.3.data/data/share/omni-cortex/hooks/session_utils.py +186 -0
- {omni_cortex-1.3.0.dist-info → omni_cortex-1.11.3.dist-info}/METADATA +237 -8
- omni_cortex-1.11.3.dist-info/RECORD +25 -0
- omni_cortex-1.3.0.data/data/share/omni-cortex/hooks/post_tool_use.py +0 -160
- omni_cortex-1.3.0.dist-info/RECORD +0 -20
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/project_config.py +0 -0
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/project_scanner.py +0 -0
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/pyproject.toml +0 -0
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/dashboard/backend/uv.lock +0 -0
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/hooks/stop.py +0 -0
- {omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/hooks/subagent_stop.py +0 -0
- {omni_cortex-1.3.0.dist-info → omni_cortex-1.11.3.dist-info}/WHEEL +0 -0
- {omni_cortex-1.3.0.dist-info → omni_cortex-1.11.3.dist-info}/entry_points.txt +0 -0
- {omni_cortex-1.3.0.dist-info → omni_cortex-1.11.3.dist-info}/licenses/LICENSE +0 -0
{omni_cortex-1.3.0.data → omni_cortex-1.11.3.data}/data/share/omni-cortex/hooks/pre_tool_use.py
RENAMED
|
@@ -18,12 +18,57 @@ Hook configuration for settings.json:
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
import json
|
|
21
|
+
import re
|
|
21
22
|
import sys
|
|
22
23
|
import os
|
|
23
24
|
import sqlite3
|
|
24
25
|
from datetime import datetime, timezone
|
|
25
26
|
from pathlib import Path
|
|
26
27
|
|
|
28
|
+
# Import shared session management
|
|
29
|
+
from session_utils import get_or_create_session
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Patterns for sensitive field names that should be redacted
|
|
33
|
+
SENSITIVE_FIELD_PATTERNS = [
|
|
34
|
+
r'(?i)(api[_-]?key|apikey)',
|
|
35
|
+
r'(?i)(password|passwd|pwd)',
|
|
36
|
+
r'(?i)(secret|token|credential)',
|
|
37
|
+
r'(?i)(auth[_-]?token|access[_-]?token)',
|
|
38
|
+
r'(?i)(private[_-]?key|ssh[_-]?key)',
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def redact_sensitive_fields(data: dict) -> dict:
|
|
43
|
+
"""Redact sensitive fields from a dictionary for safe logging.
|
|
44
|
+
|
|
45
|
+
Recursively processes nested dicts and lists.
|
|
46
|
+
"""
|
|
47
|
+
if not isinstance(data, dict):
|
|
48
|
+
return data
|
|
49
|
+
|
|
50
|
+
result = {}
|
|
51
|
+
for key, value in data.items():
|
|
52
|
+
# Check if key matches sensitive patterns
|
|
53
|
+
is_sensitive = any(
|
|
54
|
+
re.search(pattern, str(key))
|
|
55
|
+
for pattern in SENSITIVE_FIELD_PATTERNS
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if is_sensitive:
|
|
59
|
+
result[key] = '[REDACTED]'
|
|
60
|
+
elif isinstance(value, dict):
|
|
61
|
+
result[key] = redact_sensitive_fields(value)
|
|
62
|
+
elif isinstance(value, list):
|
|
63
|
+
result[key] = [
|
|
64
|
+
redact_sensitive_fields(item) if isinstance(item, dict) else item
|
|
65
|
+
for item in value
|
|
66
|
+
]
|
|
67
|
+
else:
|
|
68
|
+
result[key] = value
|
|
69
|
+
|
|
70
|
+
return result
|
|
71
|
+
|
|
27
72
|
|
|
28
73
|
def get_db_path() -> Path:
|
|
29
74
|
"""Get the database path for the current project."""
|
|
@@ -115,13 +160,18 @@ def main():
|
|
|
115
160
|
print(json.dumps({}))
|
|
116
161
|
return
|
|
117
162
|
|
|
118
|
-
session_id = os.environ.get("CLAUDE_SESSION_ID")
|
|
119
163
|
project_path = os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
|
|
120
164
|
|
|
121
165
|
# Auto-initialize database (creates if not exists)
|
|
122
166
|
db_path = get_db_path()
|
|
123
167
|
conn = ensure_database(db_path)
|
|
124
168
|
|
|
169
|
+
# Get or create session (auto-manages session lifecycle)
|
|
170
|
+
session_id = get_or_create_session(conn, project_path)
|
|
171
|
+
|
|
172
|
+
# Redact sensitive fields before logging
|
|
173
|
+
safe_input = redact_sensitive_fields(tool_input) if isinstance(tool_input, dict) else tool_input
|
|
174
|
+
|
|
125
175
|
# Insert activity record
|
|
126
176
|
cursor = conn.cursor()
|
|
127
177
|
cursor.execute(
|
|
@@ -138,7 +188,7 @@ def main():
|
|
|
138
188
|
datetime.now(timezone.utc).isoformat(),
|
|
139
189
|
"pre_tool_use",
|
|
140
190
|
tool_name,
|
|
141
|
-
truncate(json.dumps(
|
|
191
|
+
truncate(json.dumps(safe_input, default=str)),
|
|
142
192
|
project_path,
|
|
143
193
|
),
|
|
144
194
|
)
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Shared session management utilities for Claude Code hooks.
|
|
3
|
+
|
|
4
|
+
This module provides session management functionality that can be shared
|
|
5
|
+
across pre_tool_use.py and post_tool_use.py hooks to ensure consistent
|
|
6
|
+
session tracking.
|
|
7
|
+
|
|
8
|
+
Session Management Logic:
|
|
9
|
+
1. Check for existing session file at `.omni-cortex/current_session.json`
|
|
10
|
+
2. If session exists and is valid (not timed out), use it
|
|
11
|
+
3. If no valid session, create a new one in both file and database
|
|
12
|
+
4. Update last_activity_at on each use to track session activity
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
import os
|
|
17
|
+
import sqlite3
|
|
18
|
+
import time
|
|
19
|
+
from datetime import datetime, timezone
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
from typing import Optional
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Session timeout in seconds (4 hours of inactivity = new session)
|
|
25
|
+
SESSION_TIMEOUT_SECONDS = 4 * 60 * 60
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def generate_session_id() -> str:
|
|
29
|
+
"""Generate a unique session ID matching the MCP format.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Session ID in format: sess_{timestamp_ms}_{random_hex}
|
|
33
|
+
"""
|
|
34
|
+
timestamp_ms = int(time.time() * 1000)
|
|
35
|
+
random_hex = os.urandom(4).hex()
|
|
36
|
+
return f"sess_{timestamp_ms}_{random_hex}"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def get_session_file_path() -> Path:
|
|
40
|
+
"""Get the path to the current session file.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Path to .omni-cortex/current_session.json
|
|
44
|
+
"""
|
|
45
|
+
project_path = os.environ.get("CLAUDE_PROJECT_DIR", os.getcwd())
|
|
46
|
+
return Path(project_path) / ".omni-cortex" / "current_session.json"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def load_session_file() -> Optional[dict]:
|
|
50
|
+
"""Load the current session from file if it exists.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
Session data dict or None if file doesn't exist or is invalid
|
|
54
|
+
"""
|
|
55
|
+
session_file = get_session_file_path()
|
|
56
|
+
if not session_file.exists():
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
with open(session_file, "r") as f:
|
|
61
|
+
return json.load(f)
|
|
62
|
+
except (json.JSONDecodeError, IOError):
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def save_session_file(session_data: dict) -> None:
|
|
67
|
+
"""Save the current session to file.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
session_data: Dict containing session_id, project_path, started_at, last_activity_at
|
|
71
|
+
"""
|
|
72
|
+
session_file = get_session_file_path()
|
|
73
|
+
session_file.parent.mkdir(parents=True, exist_ok=True)
|
|
74
|
+
|
|
75
|
+
with open(session_file, "w") as f:
|
|
76
|
+
json.dump(session_data, f, indent=2)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def is_session_valid(session_data: dict) -> bool:
|
|
80
|
+
"""Check if a session is still valid (not timed out).
|
|
81
|
+
|
|
82
|
+
A session is valid if:
|
|
83
|
+
- It has a last_activity_at timestamp
|
|
84
|
+
- The timestamp is within SESSION_TIMEOUT_SECONDS of now
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
session_data: Session dict with last_activity_at field
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
True if session is valid, False otherwise
|
|
91
|
+
"""
|
|
92
|
+
last_activity = session_data.get("last_activity_at")
|
|
93
|
+
if not last_activity:
|
|
94
|
+
return False
|
|
95
|
+
|
|
96
|
+
try:
|
|
97
|
+
last_time = datetime.fromisoformat(last_activity.replace("Z", "+00:00"))
|
|
98
|
+
now = datetime.now(timezone.utc)
|
|
99
|
+
elapsed_seconds = (now - last_time).total_seconds()
|
|
100
|
+
return elapsed_seconds < SESSION_TIMEOUT_SECONDS
|
|
101
|
+
except (ValueError, TypeError):
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def create_session_in_db(conn: sqlite3.Connection, session_id: str, project_path: str) -> None:
|
|
106
|
+
"""Create a new session record in the database.
|
|
107
|
+
|
|
108
|
+
Also creates the sessions table if it doesn't exist (for first-run scenarios).
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
conn: SQLite database connection
|
|
112
|
+
session_id: The session ID to create
|
|
113
|
+
project_path: The project directory path
|
|
114
|
+
"""
|
|
115
|
+
cursor = conn.cursor()
|
|
116
|
+
now = datetime.now(timezone.utc).isoformat()
|
|
117
|
+
|
|
118
|
+
# Check if sessions table exists (it might not if only activities table was created)
|
|
119
|
+
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='sessions'")
|
|
120
|
+
if cursor.fetchone() is None:
|
|
121
|
+
# Create sessions table with minimal schema
|
|
122
|
+
conn.executescript("""
|
|
123
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
124
|
+
id TEXT PRIMARY KEY,
|
|
125
|
+
project_path TEXT NOT NULL,
|
|
126
|
+
started_at TEXT NOT NULL,
|
|
127
|
+
ended_at TEXT,
|
|
128
|
+
summary TEXT,
|
|
129
|
+
tags TEXT,
|
|
130
|
+
metadata TEXT
|
|
131
|
+
);
|
|
132
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at DESC);
|
|
133
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_path);
|
|
134
|
+
""")
|
|
135
|
+
conn.commit()
|
|
136
|
+
|
|
137
|
+
cursor.execute(
|
|
138
|
+
"""
|
|
139
|
+
INSERT OR IGNORE INTO sessions (id, project_path, started_at)
|
|
140
|
+
VALUES (?, ?, ?)
|
|
141
|
+
""",
|
|
142
|
+
(session_id, project_path, now),
|
|
143
|
+
)
|
|
144
|
+
conn.commit()
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def get_or_create_session(conn: sqlite3.Connection, project_path: str) -> str:
|
|
148
|
+
"""Get the current session ID, creating a new one if needed.
|
|
149
|
+
|
|
150
|
+
Session management logic:
|
|
151
|
+
1. Check for existing session file
|
|
152
|
+
2. If exists and not timed out, use it and update last_activity
|
|
153
|
+
3. If doesn't exist or timed out, create new session
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
conn: SQLite database connection
|
|
157
|
+
project_path: The project directory path
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
The session ID to use for activity logging
|
|
161
|
+
"""
|
|
162
|
+
session_data = load_session_file()
|
|
163
|
+
now_iso = datetime.now(timezone.utc).isoformat()
|
|
164
|
+
|
|
165
|
+
if session_data and is_session_valid(session_data):
|
|
166
|
+
# Update last activity time
|
|
167
|
+
session_data["last_activity_at"] = now_iso
|
|
168
|
+
save_session_file(session_data)
|
|
169
|
+
return session_data["session_id"]
|
|
170
|
+
|
|
171
|
+
# Create new session
|
|
172
|
+
session_id = generate_session_id()
|
|
173
|
+
|
|
174
|
+
# Create in database
|
|
175
|
+
create_session_in_db(conn, session_id, project_path)
|
|
176
|
+
|
|
177
|
+
# Save to file
|
|
178
|
+
session_data = {
|
|
179
|
+
"session_id": session_id,
|
|
180
|
+
"project_path": project_path,
|
|
181
|
+
"started_at": now_iso,
|
|
182
|
+
"last_activity_at": now_iso,
|
|
183
|
+
}
|
|
184
|
+
save_session_file(session_data)
|
|
185
|
+
|
|
186
|
+
return session_id
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: omni-cortex
|
|
3
|
-
Version: 1.3
|
|
3
|
+
Version: 1.11.3
|
|
4
4
|
Summary: Give Claude Code a perfect memory - auto-logs everything, searches smartly, and gets smarter over time
|
|
5
5
|
Project-URL: Homepage, https://github.com/AllCytes/Omni-Cortex
|
|
6
6
|
Project-URL: Repository, https://github.com/AllCytes/Omni-Cortex
|
|
@@ -21,9 +21,11 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
21
21
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
22
22
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
23
|
Requires-Python: >=3.10
|
|
24
|
+
Requires-Dist: claude-agent-sdk>=0.1.0
|
|
24
25
|
Requires-Dist: httpx>=0.25.0
|
|
25
26
|
Requires-Dist: mcp>=1.0.0
|
|
26
27
|
Requires-Dist: pydantic>=2.0.0
|
|
28
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
27
29
|
Requires-Dist: pyyaml>=6.0.0
|
|
28
30
|
Provides-Extra: dev
|
|
29
31
|
Requires-Dist: black>=23.0.0; extra == 'dev'
|
|
@@ -76,7 +78,180 @@ A universal memory system for Claude Code that combines activity logging with in
|
|
|
76
78
|
- **Importance Decay**: Frequently accessed memories naturally surface
|
|
77
79
|
- **Auto Activity Logging**: Automatically logs all tool calls via hooks
|
|
78
80
|
|
|
79
|
-
##
|
|
81
|
+
## Getting Started (5 Minutes)
|
|
82
|
+
|
|
83
|
+
A step-by-step guide to get Omni Cortex running on your machine.
|
|
84
|
+
|
|
85
|
+
### Prerequisites
|
|
86
|
+
|
|
87
|
+
- **Python 3.10+** - Check with `python --version`
|
|
88
|
+
- **Claude Code CLI** - The Anthropic CLI tool
|
|
89
|
+
- **pip** - Python package manager (comes with Python)
|
|
90
|
+
|
|
91
|
+
### Step 1: Install the Package
|
|
92
|
+
|
|
93
|
+
**Option A: From PyPI (Recommended for most users)**
|
|
94
|
+
```bash
|
|
95
|
+
pip install omni-cortex
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Option B: From Source (For development/contributions)**
|
|
99
|
+
```bash
|
|
100
|
+
git clone https://github.com/AllCytes/Omni-Cortex.git
|
|
101
|
+
cd Omni-Cortex
|
|
102
|
+
pip install -e ".[semantic]"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Expected output:**
|
|
106
|
+
```
|
|
107
|
+
Successfully installed omni-cortex-1.7.1
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Step 2: Run the Setup
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
omni-cortex-setup
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This automatically:
|
|
117
|
+
- Adds Omni Cortex as an MCP server in `~/.claude.json`
|
|
118
|
+
- Configures hooks in `~/.claude/settings.json` for activity logging
|
|
119
|
+
|
|
120
|
+
**Expected output:**
|
|
121
|
+
```
|
|
122
|
+
✓ MCP server configured
|
|
123
|
+
✓ Hooks configured
|
|
124
|
+
Setup complete! Restart Claude Code to activate.
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Step 3: Restart Claude Code
|
|
128
|
+
|
|
129
|
+
Close and reopen your Claude Code terminal. This loads the new MCP configuration.
|
|
130
|
+
|
|
131
|
+
### Step 4: Verify It's Working
|
|
132
|
+
|
|
133
|
+
In Claude Code, try storing a memory:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
Ask Claude: "Remember that the database uses SQLite for storage"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Claude should use the `cortex_remember` tool. Then verify:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
Ask Claude: "What do you remember about the database?"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Claude should use `cortex_recall` and find your memory.
|
|
146
|
+
|
|
147
|
+
### Step 5: Start the Dashboard (Optional)
|
|
148
|
+
|
|
149
|
+
The web dashboard lets you browse and search memories visually.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Start the dashboard (opens http://localhost:5173)
|
|
153
|
+
omni-cortex-dashboard
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Or manually:
|
|
157
|
+
```bash
|
|
158
|
+
# Terminal 1: Backend (uses dashboard's own venv)
|
|
159
|
+
cd dashboard/backend
|
|
160
|
+
.venv/Scripts/python -m uvicorn main:app --host 127.0.0.1 --port 8765 --reload
|
|
161
|
+
|
|
162
|
+
# Terminal 2: Frontend
|
|
163
|
+
cd dashboard/frontend
|
|
164
|
+
npm install
|
|
165
|
+
npm run dev
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Open http://localhost:5173 in your browser.
|
|
169
|
+
|
|
170
|
+
**Note:** The dashboard has its own virtual environment at `dashboard/backend/.venv` with FastAPI and other web dependencies. This is separate from the project root `.venv` which contains the MCP server package.
|
|
171
|
+
|
|
172
|
+
### Troubleshooting
|
|
173
|
+
|
|
174
|
+
<details>
|
|
175
|
+
<summary><b>❌ "omni-cortex-setup" command not found</b></summary>
|
|
176
|
+
|
|
177
|
+
**Cause:** pip installed to a location not in your PATH.
|
|
178
|
+
|
|
179
|
+
**Solution:**
|
|
180
|
+
```bash
|
|
181
|
+
# Find where pip installed it
|
|
182
|
+
python -m omni_cortex.setup
|
|
183
|
+
|
|
184
|
+
# Or add Python scripts to PATH (Windows)
|
|
185
|
+
# Add %APPDATA%\Python\Python3x\Scripts to your PATH
|
|
186
|
+
|
|
187
|
+
# On macOS/Linux, ensure ~/.local/bin is in PATH
|
|
188
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
189
|
+
```
|
|
190
|
+
</details>
|
|
191
|
+
|
|
192
|
+
<details>
|
|
193
|
+
<summary><b>❌ Claude doesn't see cortex_* tools</b></summary>
|
|
194
|
+
|
|
195
|
+
**Cause:** MCP server not configured or Claude Code not restarted.
|
|
196
|
+
|
|
197
|
+
**Solution:**
|
|
198
|
+
1. Check `~/.claude.json` contains the `omni-cortex` MCP server entry
|
|
199
|
+
2. Fully close and reopen Claude Code (not just the terminal)
|
|
200
|
+
3. Run `omni-cortex-setup` again if needed
|
|
201
|
+
</details>
|
|
202
|
+
|
|
203
|
+
<details>
|
|
204
|
+
<summary><b>❌ "ModuleNotFoundError: No module named 'omni_cortex'"</b></summary>
|
|
205
|
+
|
|
206
|
+
**Cause:** Python environment mismatch.
|
|
207
|
+
|
|
208
|
+
**Solution:**
|
|
209
|
+
```bash
|
|
210
|
+
# Ensure you're using the same Python that pip used
|
|
211
|
+
which python # or `where python` on Windows
|
|
212
|
+
pip show omni-cortex # Check if installed
|
|
213
|
+
|
|
214
|
+
# Reinstall if needed
|
|
215
|
+
pip install --force-reinstall omni-cortex
|
|
216
|
+
```
|
|
217
|
+
</details>
|
|
218
|
+
|
|
219
|
+
<details>
|
|
220
|
+
<summary><b>❌ Dashboard won't start</b></summary>
|
|
221
|
+
|
|
222
|
+
**Cause:** Missing dependencies or port conflict.
|
|
223
|
+
|
|
224
|
+
**Solution:**
|
|
225
|
+
```bash
|
|
226
|
+
# Install backend dependencies
|
|
227
|
+
cd dashboard/backend
|
|
228
|
+
pip install -e .
|
|
229
|
+
|
|
230
|
+
# Check if port 8765 is in use
|
|
231
|
+
# Windows: netstat -ano | findstr :8765
|
|
232
|
+
# macOS/Linux: lsof -i :8765
|
|
233
|
+
|
|
234
|
+
# Use a different port if needed
|
|
235
|
+
uvicorn main:app --port 8766
|
|
236
|
+
```
|
|
237
|
+
</details>
|
|
238
|
+
|
|
239
|
+
<details>
|
|
240
|
+
<summary><b>❌ Semantic search not working</b></summary>
|
|
241
|
+
|
|
242
|
+
**Cause:** Semantic extras not installed.
|
|
243
|
+
|
|
244
|
+
**Solution:**
|
|
245
|
+
```bash
|
|
246
|
+
pip install omni-cortex[semantic]
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
First search will download the embedding model (~100MB).
|
|
250
|
+
</details>
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Installation (Detailed)
|
|
80
255
|
|
|
81
256
|
### Quick Install (Recommended)
|
|
82
257
|
|
|
@@ -294,18 +469,72 @@ The PDFs use a light theme with blue/purple/green accents. Edit `docs/create_pdf
|
|
|
294
469
|
|
|
295
470
|
## Development
|
|
296
471
|
|
|
472
|
+
### Quick Setup (with Claude Code)
|
|
473
|
+
|
|
474
|
+
If you're using Claude Code, just run:
|
|
475
|
+
|
|
297
476
|
```bash
|
|
298
|
-
|
|
299
|
-
|
|
477
|
+
/dev-setup
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
This will guide you through setting up the development environment.
|
|
481
|
+
|
|
482
|
+
### Manual Setup
|
|
300
483
|
|
|
301
|
-
|
|
484
|
+
```bash
|
|
485
|
+
# Clone and install in editable mode
|
|
486
|
+
git clone https://github.com/AllCytes/Omni-Cortex.git
|
|
487
|
+
cd Omni-Cortex
|
|
488
|
+
pip install -e .
|
|
489
|
+
|
|
490
|
+
# Dashboard backend has its own venv (already included in repo)
|
|
491
|
+
# If missing, set it up:
|
|
492
|
+
cd dashboard/backend
|
|
493
|
+
python -m venv .venv
|
|
494
|
+
.venv/Scripts/pip install -r requirements.txt # Windows
|
|
495
|
+
# .venv/bin/pip install -r requirements.txt # macOS/Linux
|
|
496
|
+
cd ../frontend && npm install
|
|
497
|
+
cd ../..
|
|
498
|
+
|
|
499
|
+
# Verify installation
|
|
500
|
+
omni-cortex --help
|
|
501
|
+
omni-cortex-dashboard --help
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
**Important**: Always use `pip install -e .` (editable mode) so changes are immediately reflected without reinstalling.
|
|
505
|
+
|
|
506
|
+
### Project Structure
|
|
507
|
+
|
|
508
|
+
```
|
|
509
|
+
omni-cortex/
|
|
510
|
+
├── .venv/ # Project root venv (omni-cortex MCP package)
|
|
511
|
+
├── src/omni_cortex/ # MCP server source code
|
|
512
|
+
├── dashboard/
|
|
513
|
+
│ ├── backend/
|
|
514
|
+
│ │ ├── .venv/ # Dashboard backend venv (FastAPI, uvicorn)
|
|
515
|
+
│ │ ├── main.py # FastAPI application
|
|
516
|
+
│ │ └── database.py # Database queries
|
|
517
|
+
│ └── frontend/ # Vue 3 + Vite frontend
|
|
518
|
+
├── adws/ # Agentic Development Workflows
|
|
519
|
+
├── specs/ # Implementation plans
|
|
520
|
+
│ ├── todo/ # Plans waiting to be built
|
|
521
|
+
│ └── done/ # Completed plans
|
|
522
|
+
└── tests/ # Unit tests
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
**Why two venvs?** The dashboard is a standalone web application that can be packaged/deployed separately from the MCP server. They have different dependencies (MCP server needs `mcp`, dashboard needs `fastapi`).
|
|
526
|
+
|
|
527
|
+
### Running Tests
|
|
528
|
+
|
|
529
|
+
```bash
|
|
302
530
|
pytest
|
|
303
531
|
|
|
304
|
-
#
|
|
305
|
-
|
|
306
|
-
ruff check src tests
|
|
532
|
+
# With coverage
|
|
533
|
+
pytest --cov=src/omni_cortex
|
|
307
534
|
```
|
|
308
535
|
|
|
536
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for full development guidelines.
|
|
537
|
+
|
|
309
538
|
## Security
|
|
310
539
|
|
|
311
540
|
Omni Cortex v1.0.3 has been security reviewed:
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/hooks/post_tool_use.py,sha256=kHBRCP6VctSk3evApsgDaL3UElGSEBGwRfV4hBZPqgE,14539
|
|
2
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/hooks/pre_tool_use.py,sha256=mkZ7eeBnjWkIgNnrqfYSXIhhLNYYk4hQx_6F0pNrGoc,6395
|
|
3
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/hooks/session_utils.py,sha256=3SKPCytqWuRPOupWdzmwBoKBDJqtLcT1Nle_pueDQUY,5746
|
|
4
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/hooks/stop.py,sha256=T1bwcmbTLj0gzjrVvFBT1zB6wff4J2YkYBAY-ZxZI5g,5336
|
|
5
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/hooks/subagent_stop.py,sha256=V9HQSFGNOfkg8ZCstPEy4h5V8BP4AbrVr8teFzN1kNk,3314
|
|
6
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/.env.example,sha256=9xS7-UiWlMddRwzlyyyKNHAMlNTsgH-2sPV266guJpQ,372
|
|
7
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/backfill_summaries.py,sha256=ElchfcBv4pmVr2PsePCgFlCyuvf4_jDJj_C3AmMhu7U,8973
|
|
8
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/chat_service.py,sha256=5UCvLayZGeSdGsYAzOeupumclAhoFLusGYLdyl33ANc,9304
|
|
9
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/database.py,sha256=LAN7GSM2tvMcJaL0RrGJurH9-tw3cs2QtPduqCbLvj0,34974
|
|
10
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/image_service.py,sha256=NP6ojFpHb6iNTYRkXqYu1CL6WvooZpZ54mjLiWSWG_g,19205
|
|
11
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/logging_config.py,sha256=WnunFGET9zlsn9WBpVsio2zI7BiUQanE0xzAQQxIhII,3944
|
|
12
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/main.py,sha256=rJrmYJvkGhRsXOdYKOTRPMVnwA00W5QoGJ_Aa3v-TRE,46219
|
|
13
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/models.py,sha256=LkmcYq1imsyDlMYnX3Z_FOTmPsu37MQEfJSI-w5EjvM,7330
|
|
14
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/project_config.py,sha256=ZxGoeRpHvN5qQyf2hRxrAZiHrPSwdQp59f0di6O1LKM,4352
|
|
15
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/project_scanner.py,sha256=lwFXS8iJbOoxf7FAyo2TjH25neaMHiJ8B3jS57XxtDI,5713
|
|
16
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/prompt_security.py,sha256=LcdZhYy1CfpSq_4BPO6lMJ15phc2ZXLUSBAnAvODVCI,3423
|
|
17
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/pyproject.toml,sha256=9pbbGQXLe1Xd06nZAtDySCHIlfMWvPaB-C6tGZR6umc,502
|
|
18
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/security.py,sha256=nQsoPE0n5dtY9ive00d33W1gL48GgK7C5Ae0BK2oW2k,3479
|
|
19
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/uv.lock,sha256=miB9zGGSirBkjDE-OZTPCnv43Yc98xuAz_Ne8vTNFHg,186004
|
|
20
|
+
omni_cortex-1.11.3.data/data/share/omni-cortex/dashboard/backend/websocket_manager.py,sha256=gNQLd94AcC-InumGQmUolREhiogCzilYWpLN8SRZjHI,3645
|
|
21
|
+
omni_cortex-1.11.3.dist-info/METADATA,sha256=oM6RvKOj_J7rCFrqbgZOiYHxFLxy-eLnIlq5QHIEf_o,15712
|
|
22
|
+
omni_cortex-1.11.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
23
|
+
omni_cortex-1.11.3.dist-info/entry_points.txt,sha256=rohx4mFH2ffZmMb9QXPZmFf-ZGjA3jpKVDVeET-ttiM,150
|
|
24
|
+
omni_cortex-1.11.3.dist-info/licenses/LICENSE,sha256=oG_397owMmi-Umxp5sYocJ6RPohp9_bDNnnEu9OUphg,1072
|
|
25
|
+
omni_cortex-1.11.3.dist-info/RECORD,,
|