omni-cortex 1.0.4__py3-none-any.whl → 1.3.0__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.
Files changed (22) hide show
  1. omni_cortex-1.3.0.data/data/share/omni-cortex/dashboard/backend/chat_service.py +308 -0
  2. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/dashboard/backend/database.py +286 -0
  3. omni_cortex-1.3.0.data/data/share/omni-cortex/dashboard/backend/image_service.py +543 -0
  4. omni_cortex-1.3.0.data/data/share/omni-cortex/dashboard/backend/logging_config.py +92 -0
  5. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/dashboard/backend/main.py +385 -42
  6. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/dashboard/backend/models.py +93 -0
  7. omni_cortex-1.3.0.data/data/share/omni-cortex/dashboard/backend/project_config.py +170 -0
  8. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/dashboard/backend/project_scanner.py +45 -22
  9. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/dashboard/backend/uv.lock +414 -1
  10. {omni_cortex-1.0.4.dist-info → omni_cortex-1.3.0.dist-info}/METADATA +26 -2
  11. omni_cortex-1.3.0.dist-info/RECORD +20 -0
  12. omni_cortex-1.0.4.data/data/share/omni-cortex/dashboard/backend/chat_service.py +0 -140
  13. omni_cortex-1.0.4.dist-info/RECORD +0 -17
  14. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/dashboard/backend/pyproject.toml +0 -0
  15. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/dashboard/backend/websocket_manager.py +0 -0
  16. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/hooks/post_tool_use.py +0 -0
  17. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/hooks/pre_tool_use.py +0 -0
  18. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/hooks/stop.py +0 -0
  19. {omni_cortex-1.0.4.data → omni_cortex-1.3.0.data}/data/share/omni-cortex/hooks/subagent_stop.py +0 -0
  20. {omni_cortex-1.0.4.dist-info → omni_cortex-1.3.0.dist-info}/WHEEL +0 -0
  21. {omni_cortex-1.0.4.dist-info → omni_cortex-1.3.0.dist-info}/entry_points.txt +0 -0
  22. {omni_cortex-1.0.4.dist-info → omni_cortex-1.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,170 @@
1
+ """Project configuration manager for user preferences."""
2
+
3
+ import json
4
+ import platform
5
+ from datetime import datetime
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+ from pydantic import BaseModel
10
+
11
+
12
+ class RegisteredProject(BaseModel):
13
+ """A manually registered project."""
14
+
15
+ path: str
16
+ display_name: Optional[str] = None
17
+ added_at: datetime
18
+
19
+
20
+ class RecentProject(BaseModel):
21
+ """A recently accessed project."""
22
+
23
+ path: str
24
+ last_accessed: datetime
25
+
26
+
27
+ class ProjectConfig(BaseModel):
28
+ """User project configuration."""
29
+
30
+ version: int = 1
31
+ scan_directories: list[str] = []
32
+ registered_projects: list[RegisteredProject] = []
33
+ favorites: list[str] = []
34
+ recent: list[RecentProject] = []
35
+
36
+
37
+ CONFIG_PATH = Path.home() / ".omni-cortex" / "projects.json"
38
+
39
+
40
+ def get_default_scan_dirs() -> list[str]:
41
+ """Return platform-appropriate default scan directories."""
42
+ home = Path.home()
43
+
44
+ dirs = [
45
+ str(home / "projects"),
46
+ str(home / "Projects"),
47
+ str(home / "code"),
48
+ str(home / "Code"),
49
+ str(home / "dev"),
50
+ str(home / "workspace"),
51
+ ]
52
+
53
+ if platform.system() == "Windows":
54
+ dirs.insert(0, "D:/Projects")
55
+
56
+ return [d for d in dirs if Path(d).exists()]
57
+
58
+
59
+ def load_config() -> ProjectConfig:
60
+ """Load config from disk, creating defaults if missing."""
61
+ if CONFIG_PATH.exists():
62
+ try:
63
+ data = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
64
+ return ProjectConfig(**data)
65
+ except Exception:
66
+ pass
67
+
68
+ # Create default config
69
+ config = ProjectConfig(scan_directories=get_default_scan_dirs())
70
+ save_config(config)
71
+ return config
72
+
73
+
74
+ def save_config(config: ProjectConfig) -> None:
75
+ """Save config to disk."""
76
+ CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
77
+ CONFIG_PATH.write_text(config.model_dump_json(indent=2), encoding="utf-8")
78
+
79
+
80
+ def add_registered_project(path: str, display_name: Optional[str] = None) -> bool:
81
+ """Register a new project by path."""
82
+ config = load_config()
83
+
84
+ # Validate path has cortex.db
85
+ db_path = Path(path) / ".omni-cortex" / "cortex.db"
86
+ if not db_path.exists():
87
+ return False
88
+
89
+ # Check if already registered
90
+ if any(p.path == path for p in config.registered_projects):
91
+ return False
92
+
93
+ config.registered_projects.append(
94
+ RegisteredProject(path=path, display_name=display_name, added_at=datetime.now())
95
+ )
96
+ save_config(config)
97
+ return True
98
+
99
+
100
+ def remove_registered_project(path: str) -> bool:
101
+ """Remove a registered project."""
102
+ config = load_config()
103
+ original_len = len(config.registered_projects)
104
+ config.registered_projects = [
105
+ p for p in config.registered_projects if p.path != path
106
+ ]
107
+
108
+ if len(config.registered_projects) < original_len:
109
+ save_config(config)
110
+ return True
111
+ return False
112
+
113
+
114
+ def toggle_favorite(path: str) -> bool:
115
+ """Toggle favorite status for a project. Returns new favorite status."""
116
+ config = load_config()
117
+
118
+ if path in config.favorites:
119
+ config.favorites.remove(path)
120
+ is_favorite = False
121
+ else:
122
+ config.favorites.append(path)
123
+ is_favorite = True
124
+
125
+ save_config(config)
126
+ return is_favorite
127
+
128
+
129
+ def update_recent(path: str) -> None:
130
+ """Update recent projects list."""
131
+ config = load_config()
132
+
133
+ # Remove if already in list
134
+ config.recent = [r for r in config.recent if r.path != path]
135
+
136
+ # Add to front
137
+ config.recent.insert(0, RecentProject(path=path, last_accessed=datetime.now()))
138
+
139
+ # Keep only last 10
140
+ config.recent = config.recent[:10]
141
+
142
+ save_config(config)
143
+
144
+
145
+ def add_scan_directory(directory: str) -> bool:
146
+ """Add a directory to scan list."""
147
+ config = load_config()
148
+
149
+ # Expand user path
150
+ expanded = str(Path(directory).expanduser())
151
+
152
+ if not Path(expanded).is_dir():
153
+ return False
154
+
155
+ if expanded not in config.scan_directories:
156
+ config.scan_directories.append(expanded)
157
+ save_config(config)
158
+ return True
159
+ return False
160
+
161
+
162
+ def remove_scan_directory(directory: str) -> bool:
163
+ """Remove a directory from scan list."""
164
+ config = load_config()
165
+
166
+ if directory in config.scan_directories:
167
+ config.scan_directories.remove(directory)
168
+ save_config(config)
169
+ return True
170
+ return False
@@ -1,11 +1,11 @@
1
1
  """Scanner to discover all omni-cortex databases on the system."""
2
2
 
3
- import os
4
3
  import sqlite3
5
4
  from datetime import datetime
6
5
  from pathlib import Path
7
6
 
8
7
  from models import ProjectInfo
8
+ from project_config import load_config
9
9
 
10
10
 
11
11
  def get_global_db_path() -> Path:
@@ -65,54 +65,70 @@ def scan_projects() -> list[ProjectInfo]:
65
65
  projects: list[ProjectInfo] = []
66
66
  seen_paths: set[str] = set()
67
67
 
68
+ # Load user config
69
+ config = load_config()
70
+
68
71
  # 1. Add global index if exists
69
72
  global_path = get_global_db_path()
70
73
  if global_path.exists():
71
74
  stat = global_path.stat()
75
+ global_project_path = str(global_path.parent)
72
76
  projects.append(
73
77
  ProjectInfo(
74
78
  name="Global Index",
75
- path=str(global_path.parent),
79
+ path=global_project_path,
76
80
  db_path=str(global_path),
77
81
  last_modified=datetime.fromtimestamp(stat.st_mtime),
78
82
  memory_count=get_memory_count(global_path),
79
83
  is_global=True,
84
+ is_favorite=global_project_path in config.favorites,
80
85
  )
81
86
  )
82
87
  seen_paths.add(str(global_path))
83
88
 
84
- # 2. Scan common project directories
85
- scan_dirs = [
86
- Path("D:/Projects"),
87
- Path.home() / "projects",
88
- Path.home() / "Projects",
89
- Path.home() / "code",
90
- Path.home() / "Code",
91
- Path.home() / "dev",
92
- Path.home() / "Dev",
93
- Path.home() / "src",
94
- Path.home() / "workspace",
95
- ]
96
-
97
- for scan_dir in scan_dirs:
98
- if scan_dir.exists():
99
- for db_path in scan_directory_for_cortex(scan_dir):
89
+ # 2. Use CONFIGURABLE scan directories
90
+ for scan_dir in config.scan_directories:
91
+ scan_path = Path(scan_dir).expanduser()
92
+ if scan_path.exists():
93
+ for db_path in scan_directory_for_cortex(scan_path):
100
94
  if str(db_path) not in seen_paths:
101
95
  project_dir = db_path.parent.parent
102
96
  stat = db_path.stat()
97
+ project_path = str(project_dir)
103
98
  projects.append(
104
99
  ProjectInfo(
105
100
  name=project_dir.name,
106
- path=str(project_dir),
101
+ path=project_path,
107
102
  db_path=str(db_path),
108
103
  last_modified=datetime.fromtimestamp(stat.st_mtime),
109
104
  memory_count=get_memory_count(db_path),
110
105
  is_global=False,
106
+ is_favorite=project_path in config.favorites,
111
107
  )
112
108
  )
113
109
  seen_paths.add(str(db_path))
114
110
 
115
- # 3. Add paths from global db that we haven't seen
111
+ # 3. Add REGISTERED projects (manual additions)
112
+ for reg in config.registered_projects:
113
+ db_path = Path(reg.path) / ".omni-cortex" / "cortex.db"
114
+ if db_path.exists() and str(db_path) not in seen_paths:
115
+ stat = db_path.stat()
116
+ projects.append(
117
+ ProjectInfo(
118
+ name=Path(reg.path).name,
119
+ path=reg.path,
120
+ db_path=str(db_path),
121
+ last_modified=datetime.fromtimestamp(stat.st_mtime),
122
+ memory_count=get_memory_count(db_path),
123
+ is_global=False,
124
+ is_favorite=reg.path in config.favorites,
125
+ is_registered=True,
126
+ display_name=reg.display_name,
127
+ )
128
+ )
129
+ seen_paths.add(str(db_path))
130
+
131
+ # 4. Add paths from global db that we haven't seen
116
132
  for project_path in get_projects_from_global_db():
117
133
  db_path = Path(project_path) / ".omni-cortex" / "cortex.db"
118
134
  if db_path.exists() and str(db_path) not in seen_paths:
@@ -125,12 +141,19 @@ def scan_projects() -> list[ProjectInfo]:
125
141
  last_modified=datetime.fromtimestamp(stat.st_mtime),
126
142
  memory_count=get_memory_count(db_path),
127
143
  is_global=False,
144
+ is_favorite=project_path in config.favorites,
128
145
  )
129
146
  )
130
147
  seen_paths.add(str(db_path))
131
148
 
132
- # Sort by last_modified (most recent first), with global always first
133
- projects.sort(key=lambda p: (not p.is_global, -(p.last_modified.timestamp() if p.last_modified else 0)))
149
+ # Sort: favorites first, then by last_modified (most recent first), with global always first
150
+ projects.sort(
151
+ key=lambda p: (
152
+ not p.is_global,
153
+ not p.is_favorite,
154
+ -(p.last_modified.timestamp() if p.last_modified else 0),
155
+ )
156
+ )
134
157
 
135
158
  return projects
136
159