flurryx-code-memory 0.4.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.
- code_memory/__init__.py +1 -0
- code_memory/claims/__init__.py +32 -0
- code_memory/claims/extractor.py +325 -0
- code_memory/claims/indexer.py +258 -0
- code_memory/claims/resolver.py +186 -0
- code_memory/claims/store.py +424 -0
- code_memory/cli.py +1192 -0
- code_memory/config.py +268 -0
- code_memory/embed/__init__.py +224 -0
- code_memory/embed/cache.py +204 -0
- code_memory/embed/m3.py +174 -0
- code_memory/embed/ollama.py +92 -0
- code_memory/embed/tei.py +106 -0
- code_memory/episodic/__init__.py +3 -0
- code_memory/episodic/sqlite_store.py +278 -0
- code_memory/extractor/__init__.py +3 -0
- code_memory/extractor/csproj.py +166 -0
- code_memory/extractor/dll.py +385 -0
- code_memory/extractor/gitignore.py +162 -0
- code_memory/extractor/nuget.py +275 -0
- code_memory/extractor/sanity.py +124 -0
- code_memory/extractor/sln.py +108 -0
- code_memory/extractor/treesitter.py +1172 -0
- code_memory/graph/__init__.py +3 -0
- code_memory/graph/falkor_store.py +740 -0
- code_memory/mcp_server.py +1816 -0
- code_memory/metrics.py +260 -0
- code_memory/orchestrator/__init__.py +13 -0
- code_memory/orchestrator/git_delta.py +211 -0
- code_memory/orchestrator/ingest_state.py +71 -0
- code_memory/orchestrator/pipeline.py +1478 -0
- code_memory/orchestrator/reset.py +130 -0
- code_memory/orchestrator/resolver.py +825 -0
- code_memory/orchestrator/retrieve.py +505 -0
- code_memory/resilience.py +73 -0
- code_memory/sync/__init__.py +20 -0
- code_memory/sync/autostart/__init__.py +42 -0
- code_memory/sync/autostart/base.py +106 -0
- code_memory/sync/autostart/launchd.py +115 -0
- code_memory/sync/autostart/schtasks.py +155 -0
- code_memory/sync/autostart/systemd.py +113 -0
- code_memory/sync/hooks.py +164 -0
- code_memory/sync/safety.py +65 -0
- code_memory/sync/snapshot.py +461 -0
- code_memory/sync/store.py +399 -0
- code_memory/sync/sync.py +405 -0
- code_memory/sync/watcher.py +320 -0
- code_memory/vector/__init__.py +3 -0
- code_memory/vector/qdrant_store.py +302 -0
- flurryx_code_memory-0.4.0.dist-info/METADATA +26 -0
- flurryx_code_memory-0.4.0.dist-info/RECORD +53 -0
- flurryx_code_memory-0.4.0.dist-info/WHEEL +4 -0
- flurryx_code_memory-0.4.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""Project reset utilities.
|
|
2
|
+
|
|
3
|
+
Two scopes:
|
|
4
|
+
|
|
5
|
+
- **code index** — Qdrant code collection + FalkorDB graph + SQLite
|
|
6
|
+
``ingest_state`` table. Wiping this leaves prior agent conversations
|
|
7
|
+
intact and is the common case (e.g. after broadening ignore rules).
|
|
8
|
+
- **episodes** — Qdrant episode collection + episodic SQLite DB. Wiping
|
|
9
|
+
this is destructive: it forgets every recorded task/episode for the
|
|
10
|
+
project. Opt-in via ``include_episodes=True``.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from dataclasses import dataclass
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from falkordb import FalkorDB
|
|
19
|
+
|
|
20
|
+
from ..config import CONFIG, slugify
|
|
21
|
+
from ..graph.falkor_store import FalkorStore
|
|
22
|
+
from ..vector.qdrant_store import QdrantStore
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass
|
|
26
|
+
class ResetResult:
|
|
27
|
+
project: str
|
|
28
|
+
vectors_dropped: bool
|
|
29
|
+
graph_cleared: bool
|
|
30
|
+
state_cleared: bool
|
|
31
|
+
episodes_dropped: bool
|
|
32
|
+
episodic_db_removed: bool
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def list_projects() -> list[str]:
|
|
36
|
+
"""Discover every project slug known to the storage backends.
|
|
37
|
+
|
|
38
|
+
Union of:
|
|
39
|
+
- Qdrant collections named ``<qdrant_code>__<slug>``
|
|
40
|
+
- FalkorDB graphs named ``<falkor_graph>__<slug>``
|
|
41
|
+
- subdirectories of ``data_dir`` (one dir per slug)
|
|
42
|
+
"""
|
|
43
|
+
slugs: set[str] = set()
|
|
44
|
+
|
|
45
|
+
code_prefix = f"{CONFIG.qdrant_code}__"
|
|
46
|
+
eps_prefix = f"{CONFIG.qdrant_episodes}__"
|
|
47
|
+
try:
|
|
48
|
+
client = QdrantStore().client
|
|
49
|
+
for c in client.get_collections().collections:
|
|
50
|
+
for prefix in (code_prefix, eps_prefix):
|
|
51
|
+
if c.name.startswith(prefix):
|
|
52
|
+
slugs.add(c.name[len(prefix) :])
|
|
53
|
+
except Exception:
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
graph_prefix = f"{CONFIG.falkor_graph}__"
|
|
57
|
+
try:
|
|
58
|
+
db = FalkorDB(host=CONFIG.falkor_host, port=CONFIG.falkor_port)
|
|
59
|
+
for name in db.list_graphs():
|
|
60
|
+
if name.startswith(graph_prefix):
|
|
61
|
+
slugs.add(name[len(graph_prefix) :])
|
|
62
|
+
except Exception:
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
if CONFIG.data_dir.is_dir():
|
|
66
|
+
for sub in CONFIG.data_dir.iterdir():
|
|
67
|
+
if sub.is_dir():
|
|
68
|
+
slugs.add(sub.name)
|
|
69
|
+
|
|
70
|
+
return sorted(slugs)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def reset_project(slug: str, *, include_episodes: bool = False) -> ResetResult:
|
|
74
|
+
"""Wipe code index (and optionally episodic memory) for one project."""
|
|
75
|
+
slug = slugify(slug)
|
|
76
|
+
cfg = CONFIG.for_project(slug)
|
|
77
|
+
|
|
78
|
+
result = ResetResult(
|
|
79
|
+
project=slug,
|
|
80
|
+
vectors_dropped=False,
|
|
81
|
+
graph_cleared=False,
|
|
82
|
+
state_cleared=False,
|
|
83
|
+
episodes_dropped=False,
|
|
84
|
+
episodic_db_removed=False,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
vector = QdrantStore()
|
|
89
|
+
vector.recreate_collection(cfg.qdrant_code)
|
|
90
|
+
result.vectors_dropped = True
|
|
91
|
+
except Exception:
|
|
92
|
+
pass
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
graph = FalkorStore(graph_name=cfg.falkor_graph)
|
|
96
|
+
graph.clear_graph()
|
|
97
|
+
result.graph_cleared = True
|
|
98
|
+
except Exception:
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
if include_episodes:
|
|
102
|
+
try:
|
|
103
|
+
QdrantStore().recreate_collection(cfg.qdrant_episodes)
|
|
104
|
+
result.episodes_dropped = True
|
|
105
|
+
except Exception:
|
|
106
|
+
pass
|
|
107
|
+
db_path = Path(cfg.episodic_db)
|
|
108
|
+
if db_path.is_file():
|
|
109
|
+
db_path.unlink(missing_ok=True)
|
|
110
|
+
result.episodic_db_removed = True
|
|
111
|
+
result.state_cleared = True
|
|
112
|
+
else:
|
|
113
|
+
# keep episodes; just clear ingest_state rows for this project's DB
|
|
114
|
+
from .ingest_state import IngestStateStore
|
|
115
|
+
|
|
116
|
+
db_path = Path(cfg.episodic_db)
|
|
117
|
+
if db_path.is_file():
|
|
118
|
+
store = IngestStateStore(db_path)
|
|
119
|
+
try:
|
|
120
|
+
store.conn.execute("DELETE FROM ingest_state")
|
|
121
|
+
store.conn.commit()
|
|
122
|
+
result.state_cleared = True
|
|
123
|
+
finally:
|
|
124
|
+
store.close()
|
|
125
|
+
|
|
126
|
+
return result
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def reset_all(*, include_episodes: bool = False) -> list[ResetResult]:
|
|
130
|
+
return [reset_project(s, include_episodes=include_episodes) for s in list_projects()]
|