basic-memory 0.13.7.dev1__py3-none-any.whl → 0.13.8.dev1__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.

Potentially problematic release.


This version of basic-memory might be problematic. Click here for more details.

basic_memory/__init__.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
3
  # Package version - updated by release automation
4
- __version__ = "0.13.6"
4
+ __version__ = "0.13.7"
5
5
 
6
6
  # API version for FastAPI - independent of package version
7
7
  __api_version__ = "v0"
@@ -1,13 +1,14 @@
1
1
  """Database management commands."""
2
2
 
3
3
  import asyncio
4
+ from pathlib import Path
4
5
 
5
6
  import typer
6
7
  from loguru import logger
7
8
 
8
9
  from basic_memory import db
9
10
  from basic_memory.cli.app import app
10
- from basic_memory.config import app_config
11
+ from basic_memory.config import app_config, config_manager
11
12
 
12
13
 
13
14
  @app.command()
@@ -25,6 +26,12 @@ def reset(
25
26
  db_path.unlink()
26
27
  logger.info(f"Database file deleted: {db_path}")
27
28
 
29
+ # Reset project configuration
30
+ config_manager.config.projects = {"main": str(Path.home() / "basic-memory")}
31
+ config_manager.config.default_project = "main"
32
+ config_manager.save_config(config_manager.config)
33
+ logger.info("Project configuration reset to default")
34
+
28
35
  # Create a new empty database
29
36
  asyncio.run(db.run_migrations(app_config))
30
37
  logger.info("Database reset complete")
@@ -78,6 +78,7 @@ def mcp(
78
78
  if transport == "stdio":
79
79
  mcp_server.run(
80
80
  transport=transport,
81
+ log_level="INFO",
81
82
  )
82
83
  elif transport == "streamable-http" or transport == "sse":
83
84
  mcp_server.run(
@@ -85,4 +86,5 @@ def mcp(
85
86
  host=host,
86
87
  port=port,
87
88
  path=path,
89
+ log_level="INFO",
88
90
  )
@@ -120,7 +120,7 @@ def set_default_project(
120
120
  try:
121
121
  project_name = generate_permalink(name)
122
122
 
123
- response = asyncio.run(call_put(client, f"projects/{project_name}/default"))
123
+ response = asyncio.run(call_put(client, f"/projects/{project_name}/default"))
124
124
  result = ProjectStatusResponse.model_validate(response.json())
125
125
 
126
126
  console.print(f"[green]{result.message}[/green]")
@@ -128,12 +128,8 @@ def set_default_project(
128
128
  console.print(f"[red]Error setting default project: {str(e)}[/red]")
129
129
  raise typer.Exit(1)
130
130
 
131
- # Reload configuration to apply the change
132
- from importlib import reload
133
- from basic_memory import config as config_module
134
-
135
- reload(config_module)
136
-
131
+ # The API call above should have updated both config and MCP session
132
+ # No need for manual reload - the project service handles this automatically
137
133
  console.print("[green]Project activated for current session[/green]")
138
134
 
139
135
 
basic_memory/db.py CHANGED
@@ -95,11 +95,12 @@ async def get_or_create_db(
95
95
 
96
96
  if _engine is None:
97
97
  _engine, _session_maker = _create_engine_and_session(db_path, db_type)
98
-
98
+
99
99
  # Run migrations automatically unless explicitly disabled
100
100
  if ensure_migrations:
101
101
  if app_config is None:
102
102
  from basic_memory.config import app_config as global_app_config
103
+
103
104
  app_config = global_app_config
104
105
  await run_migrations(app_config, db_type)
105
106
 
@@ -170,12 +171,12 @@ async def run_migrations(
170
171
  ): # pragma: no cover
171
172
  """Run any pending alembic migrations."""
172
173
  global _migrations_completed
173
-
174
+
174
175
  # Skip if migrations already completed unless forced
175
176
  if _migrations_completed and not force:
176
177
  logger.debug("Migrations already completed in this session, skipping")
177
178
  return
178
-
179
+
179
180
  logger.info("Running database migrations...")
180
181
  try:
181
182
  # Get the absolute path to the alembic directory relative to this file
@@ -206,7 +207,7 @@ async def run_migrations(
206
207
  # initialize the search Index schema
207
208
  # the project_id is not used for init_search_index, so we pass a dummy value
208
209
  await SearchRepository(session_maker, 1).init_search_index()
209
-
210
+
210
211
  # Mark migrations as completed
211
212
  _migrations_completed = True
212
213
  except Exception as e: # pragma: no cover
@@ -8,7 +8,7 @@ from dataclasses import dataclass
8
8
  from typing import Optional
9
9
  from loguru import logger
10
10
 
11
- from basic_memory.config import ProjectConfig, get_project_config
11
+ from basic_memory.config import ProjectConfig, get_project_config, config_manager
12
12
 
13
13
 
14
14
  @dataclass
@@ -64,6 +64,21 @@ class ProjectSession:
64
64
  self.current_project = self.default_project # pragma: no cover
65
65
  logger.info(f"Reset project context to default: {self.default_project}") # pragma: no cover
66
66
 
67
+ def refresh_from_config(self) -> None:
68
+ """Refresh session state from current configuration.
69
+
70
+ This method reloads the default project from config and reinitializes
71
+ the session. This should be called when the default project is changed
72
+ via CLI or API to ensure MCP session stays in sync.
73
+ """
74
+ # Reload config to get latest default project
75
+ current_config = config_manager.load_config()
76
+ new_default = current_config.default_project
77
+
78
+ # Reinitialize with new default
79
+ self.initialize(new_default)
80
+ logger.info(f"Refreshed project session from config, new default: {new_default}")
81
+
67
82
 
68
83
  # Global session instance
69
84
  session = ProjectSession()
@@ -12,10 +12,6 @@ from basic_memory.mcp.server import mcp
12
12
  )
13
13
  async def sync_status_prompt() -> str:
14
14
  """Get sync status with AI assistant guidance.
15
-
16
- This prompt provides detailed sync status information along with
17
- recommendations for how AI assistants should handle different sync states.
18
-
19
15
  Returns:
20
16
  Formatted sync status with AI assistant guidance
21
17
  """
@@ -105,6 +105,5 @@ auth_settings, auth_provider = create_auth_config()
105
105
  # Create the shared server instance
106
106
  mcp = FastMCP(
107
107
  name="Basic Memory",
108
- log_level="DEBUG",
109
108
  auth=auth_provider,
110
109
  )
@@ -102,14 +102,14 @@ class EntityRepository(Repository[Entity]):
102
102
 
103
103
  async def upsert_entity(self, entity: Entity) -> Entity:
104
104
  """Insert or update entity using a hybrid approach.
105
-
105
+
106
106
  This method provides a cleaner alternative to the try/catch approach
107
- for handling permalink and file_path conflicts. It first tries direct
107
+ for handling permalink and file_path conflicts. It first tries direct
108
108
  insertion, then handles conflicts intelligently.
109
-
109
+
110
110
  Args:
111
111
  entity: The entity to insert or update
112
-
112
+
113
113
  Returns:
114
114
  The inserted or updated entity
115
115
  """
@@ -117,29 +117,28 @@ class EntityRepository(Repository[Entity]):
117
117
  async with db.scoped_session(self.session_maker) as session:
118
118
  # Set project_id if applicable and not already set
119
119
  self._set_project_id_if_needed(entity)
120
-
120
+
121
121
  # Check for existing entity with same file_path first
122
122
  existing_by_path = await session.execute(
123
123
  select(Entity).where(
124
- Entity.file_path == entity.file_path,
125
- Entity.project_id == entity.project_id
124
+ Entity.file_path == entity.file_path, Entity.project_id == entity.project_id
126
125
  )
127
126
  )
128
127
  existing_path_entity = existing_by_path.scalar_one_or_none()
129
-
128
+
130
129
  if existing_path_entity:
131
130
  # Update existing entity with same file path
132
131
  for key, value in {
133
- 'title': entity.title,
134
- 'entity_type': entity.entity_type,
135
- 'entity_metadata': entity.entity_metadata,
136
- 'content_type': entity.content_type,
137
- 'permalink': entity.permalink,
138
- 'checksum': entity.checksum,
139
- 'updated_at': entity.updated_at,
132
+ "title": entity.title,
133
+ "entity_type": entity.entity_type,
134
+ "entity_metadata": entity.entity_metadata,
135
+ "content_type": entity.content_type,
136
+ "permalink": entity.permalink,
137
+ "checksum": entity.checksum,
138
+ "updated_at": entity.updated_at,
140
139
  }.items():
141
140
  setattr(existing_path_entity, key, value)
142
-
141
+
143
142
  await session.flush()
144
143
  # Return with relationships loaded
145
144
  query = (
@@ -150,15 +149,17 @@ class EntityRepository(Repository[Entity]):
150
149
  result = await session.execute(query)
151
150
  found = result.scalar_one_or_none()
152
151
  if not found: # pragma: no cover
153
- raise RuntimeError(f"Failed to retrieve entity after update: {entity.file_path}")
152
+ raise RuntimeError(
153
+ f"Failed to retrieve entity after update: {entity.file_path}"
154
+ )
154
155
  return found
155
-
156
+
156
157
  # No existing entity with same file_path, try insert
157
158
  try:
158
159
  # Simple insert for new entity
159
160
  session.add(entity)
160
161
  await session.flush()
161
-
162
+
162
163
  # Return with relationships loaded
163
164
  query = (
164
165
  select(Entity)
@@ -168,36 +169,37 @@ class EntityRepository(Repository[Entity]):
168
169
  result = await session.execute(query)
169
170
  found = result.scalar_one_or_none()
170
171
  if not found: # pragma: no cover
171
- raise RuntimeError(f"Failed to retrieve entity after insert: {entity.file_path}")
172
+ raise RuntimeError(
173
+ f"Failed to retrieve entity after insert: {entity.file_path}"
174
+ )
172
175
  return found
173
-
176
+
174
177
  except IntegrityError:
175
178
  # Could be either file_path or permalink conflict
176
179
  await session.rollback()
177
-
180
+
178
181
  # Check if it's a file_path conflict (race condition)
179
182
  existing_by_path_check = await session.execute(
180
183
  select(Entity).where(
181
- Entity.file_path == entity.file_path,
182
- Entity.project_id == entity.project_id
184
+ Entity.file_path == entity.file_path, Entity.project_id == entity.project_id
183
185
  )
184
186
  )
185
187
  race_condition_entity = existing_by_path_check.scalar_one_or_none()
186
-
188
+
187
189
  if race_condition_entity:
188
190
  # Race condition: file_path conflict detected after our initial check
189
191
  # Update the existing entity instead
190
192
  for key, value in {
191
- 'title': entity.title,
192
- 'entity_type': entity.entity_type,
193
- 'entity_metadata': entity.entity_metadata,
194
- 'content_type': entity.content_type,
195
- 'permalink': entity.permalink,
196
- 'checksum': entity.checksum,
197
- 'updated_at': entity.updated_at,
193
+ "title": entity.title,
194
+ "entity_type": entity.entity_type,
195
+ "entity_metadata": entity.entity_metadata,
196
+ "content_type": entity.content_type,
197
+ "permalink": entity.permalink,
198
+ "checksum": entity.checksum,
199
+ "updated_at": entity.updated_at,
198
200
  }.items():
199
201
  setattr(race_condition_entity, key, value)
200
-
202
+
201
203
  await session.flush()
202
204
  # Return the updated entity with relationships loaded
203
205
  query = (
@@ -208,7 +210,9 @@ class EntityRepository(Repository[Entity]):
208
210
  result = await session.execute(query)
209
211
  found = result.scalar_one_or_none()
210
212
  if not found: # pragma: no cover
211
- raise RuntimeError(f"Failed to retrieve entity after race condition update: {entity.file_path}")
213
+ raise RuntimeError(
214
+ f"Failed to retrieve entity after race condition update: {entity.file_path}"
215
+ )
212
216
  return found
213
217
  else:
214
218
  # Must be permalink conflict - generate unique permalink
@@ -218,14 +222,13 @@ class EntityRepository(Repository[Entity]):
218
222
  """Handle permalink conflicts by generating a unique permalink."""
219
223
  base_permalink = entity.permalink
220
224
  suffix = 1
221
-
225
+
222
226
  # Find a unique permalink
223
227
  while True:
224
228
  test_permalink = f"{base_permalink}-{suffix}"
225
229
  existing = await session.execute(
226
230
  select(Entity).where(
227
- Entity.permalink == test_permalink,
228
- Entity.project_id == entity.project_id
231
+ Entity.permalink == test_permalink, Entity.project_id == entity.project_id
229
232
  )
230
233
  )
231
234
  if existing.scalar_one_or_none() is None:
@@ -233,11 +236,11 @@ class EntityRepository(Repository[Entity]):
233
236
  entity.permalink = test_permalink
234
237
  break
235
238
  suffix += 1
236
-
239
+
237
240
  # Insert with unique permalink (no conflict possible now)
238
241
  session.add(entity)
239
242
  await session.flush()
240
-
243
+
241
244
  # Return the inserted entity with relationships loaded
242
245
  query = (
243
246
  select(Entity)
@@ -302,7 +302,7 @@ class EntityService(BaseService[EntityModel]):
302
302
 
303
303
  Creates the entity with null checksum to indicate sync not complete.
304
304
  Relations will be added in second pass.
305
-
305
+
306
306
  Uses UPSERT approach to handle permalink/file_path conflicts cleanly.
307
307
  """
308
308
  logger.debug(f"Creating entity: {markdown.frontmatter.title} file_path: {file_path}")
@@ -310,7 +310,7 @@ class EntityService(BaseService[EntityModel]):
310
310
 
311
311
  # Mark as incomplete because we still need to add relations
312
312
  model.checksum = None
313
-
313
+
314
314
  # Use UPSERT to handle conflicts cleanly
315
315
  try:
316
316
  return await self.repository.upsert_entity(model)
@@ -21,9 +21,9 @@ async def initialize_database(app_config: BasicMemoryConfig) -> None:
21
21
 
22
22
  Args:
23
23
  app_config: The Basic Memory project configuration
24
-
24
+
25
25
  Note:
26
- Database migrations are now handled automatically when the database
26
+ Database migrations are now handled automatically when the database
27
27
  connection is first established via get_or_create_db().
28
28
  """
29
29
  # Trigger database initialization and migrations by getting the database connection
@@ -50,7 +50,9 @@ async def reconcile_projects_with_config(app_config: BasicMemoryConfig):
50
50
 
51
51
  # Get database session - migrations handled centrally
52
52
  _, session_maker = await db.get_or_create_db(
53
- db_path=app_config.database_path, db_type=db.DatabaseType.FILESYSTEM, ensure_migrations=False
53
+ db_path=app_config.database_path,
54
+ db_type=db.DatabaseType.FILESYSTEM,
55
+ ensure_migrations=False,
54
56
  )
55
57
  project_repository = ProjectRepository(session_maker)
56
58
 
@@ -71,7 +73,9 @@ async def reconcile_projects_with_config(app_config: BasicMemoryConfig):
71
73
  async def migrate_legacy_projects(app_config: BasicMemoryConfig):
72
74
  # Get database session - migrations handled centrally
73
75
  _, session_maker = await db.get_or_create_db(
74
- db_path=app_config.database_path, db_type=db.DatabaseType.FILESYSTEM, ensure_migrations=False
76
+ db_path=app_config.database_path,
77
+ db_type=db.DatabaseType.FILESYSTEM,
78
+ ensure_migrations=False,
75
79
  )
76
80
  logger.info("Migrating legacy projects...")
77
81
  project_repository = ProjectRepository(session_maker)
@@ -140,7 +144,9 @@ async def initialize_file_sync(
140
144
 
141
145
  # Load app configuration - migrations handled centrally
142
146
  _, session_maker = await db.get_or_create_db(
143
- db_path=app_config.database_path, db_type=db.DatabaseType.FILESYSTEM, ensure_migrations=False
147
+ db_path=app_config.database_path,
148
+ db_type=db.DatabaseType.FILESYSTEM,
149
+ ensure_migrations=False,
144
150
  )
145
151
  project_repository = ProjectRepository(session_maker)
146
152
 
@@ -154,6 +154,15 @@ class ProjectService:
154
154
 
155
155
  logger.info(f"Project '{name}' set as default in configuration and database")
156
156
 
157
+ # Refresh MCP session to pick up the new default project
158
+ try:
159
+ from basic_memory.mcp.project_session import session
160
+
161
+ session.refresh_from_config()
162
+ except ImportError: # pragma: no cover
163
+ # MCP components might not be available in all contexts (e.g., CLI-only usage)
164
+ logger.debug("MCP session not available, skipping session refresh")
165
+
157
166
  async def _ensure_single_default_project(self) -> None:
158
167
  """Ensure only one project has is_default=True.
159
168
 
@@ -274,6 +283,15 @@ class ProjectService:
274
283
 
275
284
  logger.info("Project synchronization complete")
276
285
 
286
+ # Refresh MCP session to ensure it's in sync with current config
287
+ try:
288
+ from basic_memory.mcp.project_session import session
289
+
290
+ session.refresh_from_config()
291
+ except ImportError:
292
+ # MCP components might not be available in all contexts
293
+ logger.debug("MCP session not available, skipping session refresh")
294
+
277
295
  async def update_project( # pragma: no cover
278
296
  self, name: str, updated_path: Optional[str] = None, is_active: Optional[bool] = None
279
297
  ) -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.13.7.dev1
3
+ Version: 0.13.8.dev1
4
4
  Summary: Local-first knowledge management combining Zettelkasten with knowledge graphs
5
5
  Project-URL: Homepage, https://github.com/basicmachines-co/basic-memory
6
6
  Project-URL: Repository, https://github.com/basicmachines-co/basic-memory
@@ -449,6 +449,31 @@ Development versions are automatically published on every commit to main with ve
449
449
  pip install basic-memory --pre --force-reinstall
450
450
  ```
451
451
 
452
+ ### Docker
453
+
454
+ Run Basic Memory in a container with volume mounting for your Obsidian vault:
455
+
456
+ ```bash
457
+ # Clone and start with Docker Compose
458
+ git clone https://github.com/basicmachines-co/basic-memory.git
459
+ cd basic-memory
460
+
461
+ # Edit docker-compose.yml to point to your Obsidian vault
462
+ # Then start the container
463
+ docker-compose up -d
464
+ ```
465
+
466
+ Or use Docker directly:
467
+ ```bash
468
+ docker run -d \
469
+ --name basic-memory-server \
470
+ -v /path/to/your/obsidian-vault:/data/knowledge:rw \
471
+ -v basic-memory-config:/root/.basic-memory:rw \
472
+ ghcr.io/basicmachines-co/basic-memory:latest
473
+ ```
474
+
475
+ See [Docker Setup Guide](docs/Docker.md) for detailed configuration options, multiple project setup, and integration examples.
476
+
452
477
  ## License
453
478
 
454
479
  AGPL-3.0
@@ -1,6 +1,6 @@
1
- basic_memory/__init__.py,sha256=jY-dYXPDVPu0kvc-gebJZdd6zU-oKyz-d5OfbALCEes,256
1
+ basic_memory/__init__.py,sha256=lyC6nHbFkXl-Q5KVthLKDdH6q30O0-hAs7LPLP9pVrI,256
2
2
  basic_memory/config.py,sha256=OP8ygXZuiAEpKp2EvudMFWnJDiEf3ZWAUZqvqzkEo6g,11700
3
- basic_memory/db.py,sha256=UCN37mfGgK3EKCSpKDZjqxkbQVZqBsTOfkQ5OE8sFuc,7609
3
+ basic_memory/db.py,sha256=bFuJHj_PGEhaj5ZgRItIUSW0ujAFCGgYKO7nZsjbYD0,7582
4
4
  basic_memory/deps.py,sha256=zXOhqXCoSVIa1iIcO8U6uUiofJn5eT4ycwJkH9I2kX4,12102
5
5
  basic_memory/file_utils.py,sha256=eaxTKLLEbTIy_Mb_Iv_Dmt4IXAJSrZGVi-Knrpyci3E,6700
6
6
  basic_memory/utils.py,sha256=BL6DDRiMF1gNcDr_guRAYflooSrSlDniJh96ApdzuDY,7555
@@ -33,13 +33,13 @@ basic_memory/cli/app.py,sha256=BCIaiJBPV0ipk8KwPRLNiG2ACKBQH9wo1ewKZm7CV7o,2269
33
33
  basic_memory/cli/main.py,sha256=_0eW-TWYxj8WyCHSS9kFcrrntpeIsqJrA2P0n6LfFvY,475
34
34
  basic_memory/cli/commands/__init__.py,sha256=jtnGMOIgOBNJCXQ8xpKbLWhFUD3qgpOraRi19YRNaTc,411
35
35
  basic_memory/cli/commands/auth.py,sha256=mnTlb75eeQWocWYs67LaYbuEysaYvHkqP7gQ0FEXKjE,4858
36
- basic_memory/cli/commands/db.py,sha256=IVFCTQcj2tI_U5mWRjUbDTHH-GjLBM7FGh5OA69C8ko,1141
36
+ basic_memory/cli/commands/db.py,sha256=vhuXruyNBj9-9cQzYqKL29aEDUJE7IUQCxodu0wHuio,1481
37
37
  basic_memory/cli/commands/import_chatgpt.py,sha256=VU_Kfr4B0lVh_Z2_bmsTO3e3U40wrAOvTAvtblgjses,2773
38
38
  basic_memory/cli/commands/import_claude_conversations.py,sha256=sXnP0hjfwUapwHQDzxE2HEkCDe8FTaE4cogKILsD1EA,2866
39
39
  basic_memory/cli/commands/import_claude_projects.py,sha256=mWYIeA-mu_Pq23R7OEtY2XHXG5CAh1dMGIBhckB4zRk,2811
40
40
  basic_memory/cli/commands/import_memory_json.py,sha256=Vz5rt7KCel5B3Dtv57WPEUJTHCMwFUqQlOCm2djwUi8,2867
41
- basic_memory/cli/commands/mcp.py,sha256=jmRUv1U5FT3AQ1cDbvTfAUnjhBw6UsNEmIkpbNr-_qQ,3093
42
- basic_memory/cli/commands/project.py,sha256=MqRxfIvPJ7BD823gXXeEC0sEMutIdKVsoTMC2XCka94,12258
41
+ basic_memory/cli/commands/mcp.py,sha256=W7TnSjjEFYDkrImJHkRI_OFa3muBZU0zW_c9LSVbVdk,3153
42
+ basic_memory/cli/commands/project.py,sha256=9OJWoV9kSkLePETUPxNs0v5YceXLgPWO2fU45ZinP9g,12252
43
43
  basic_memory/cli/commands/status.py,sha256=708EK8-iPjyc1iE5MPECzAyZraGYoGpvYjLwTm-BlQs,5719
44
44
  basic_memory/cli/commands/sync.py,sha256=gOU_onrMj9_IRiIe8FWU_FLEvfjcOt-qhrvvFJuU-ws,8010
45
45
  basic_memory/cli/commands/tool.py,sha256=my-kALn3khv1W2Avi736NrHsfkpbyP57mDi5LjHwqe0,9540
@@ -60,15 +60,15 @@ basic_memory/mcp/__init__.py,sha256=dsDOhKqjYeIbCULbHIxfcItTbqudEuEg1Np86eq0GEQ,
60
60
  basic_memory/mcp/async_client.py,sha256=Eo345wANiBRSM4u3j_Vd6Ax4YtMg7qbWd9PIoFfj61I,236
61
61
  basic_memory/mcp/auth_provider.py,sha256=CTydkEBvxh_fg_Z0hxKjTT8nHJoFhxrwp5hTQuToiIU,9977
62
62
  basic_memory/mcp/external_auth_provider.py,sha256=Z1GDbr6P4C-flZVHMWkIqAu30kcfeHv2iSp0EYbFuxo,11483
63
- basic_memory/mcp/project_session.py,sha256=OP1X10iG4wIWHgfkwC2q7Inl6b68zrioqkD1-Ju_S6w,3462
64
- basic_memory/mcp/server.py,sha256=QbRkkYaDWK5Vrvez39ET8C6h5uGS6y4wDHMVaCgdD78,3787
63
+ basic_memory/mcp/project_session.py,sha256=KfObBqUFUKNGlcApCfQcsqMYsmtWs72OdIcQ79ZSWhk,4142
64
+ basic_memory/mcp/server.py,sha256=T8utX0fTA12rAC_TjtWgsfB1z-Q6pdTWJH4HISw73vg,3764
65
65
  basic_memory/mcp/supabase_auth_provider.py,sha256=MLHfSHjdx2Q5jr_Ljx0qZBaOwp7CkPdk_ybR_LQ7Mvw,16472
66
66
  basic_memory/mcp/prompts/__init__.py,sha256=UvaIw5KA8PaXj3Wz1Dr-VjlkEq6T5D8AGtYFVwaHqnA,683
67
67
  basic_memory/mcp/prompts/ai_assistant_guide.py,sha256=8TI5xObiRVcwv6w9by1xQHlX0whvyE7-LGsiqDMRTFg,821
68
68
  basic_memory/mcp/prompts/continue_conversation.py,sha256=rsmlC2V7e7G6DAK0K825vFsPKgsRQ702HFzn6lkHaDM,1998
69
69
  basic_memory/mcp/prompts/recent_activity.py,sha256=0v1c3b2SdDDxXVuF8eOjNooYy04uRYel0pdJ0rnggw4,3311
70
70
  basic_memory/mcp/prompts/search.py,sha256=nb88MZy9tdW_MmCLUVItiukrLdb3xEHWLv0JVLUlc4o,1692
71
- basic_memory/mcp/prompts/sync_status.py,sha256=_5EqnCavY9BTsaxX2tPp-AgQZLt4bUrqQ6TwbM0L5w8,4645
71
+ basic_memory/mcp/prompts/sync_status.py,sha256=0F6YowgqIbAFmGE3vFFJ-D-q1SrTqzGLKYWECgNWaxw,4495
72
72
  basic_memory/mcp/prompts/utils.py,sha256=VacrbqwYtySpIlYIrKHo5s6jtoTMscYJqrFRH3zpC6Q,5431
73
73
  basic_memory/mcp/resources/ai_assistant_guide.md,sha256=qnYWDkYlb-JmKuOoZ5llmRas_t4dWDXB_i8LE277Lgs,14777
74
74
  basic_memory/mcp/resources/project_info.py,sha256=LcUkTx4iXBfU6Lp4TVch78OqLopbOy4ljyKnfr4VXso,1906
@@ -94,7 +94,7 @@ basic_memory/models/knowledge.py,sha256=AFxfKS8fRa43Kq3EjJCAufpte4VNC7fs9YfshDrB
94
94
  basic_memory/models/project.py,sha256=oUrQaUOu7_muSl-i38Dh0HzmCFrMAtwgxALDUTt9k5c,2773
95
95
  basic_memory/models/search.py,sha256=PhQ8w4taApSvjh1DpPhB4cH9GTt2E2po-DFZzhnoZkY,1300
96
96
  basic_memory/repository/__init__.py,sha256=MWK-o8QikqzOpe5SyPbKQ2ioB5BWA0Upz65tgg-E0DU,327
97
- basic_memory/repository/entity_repository.py,sha256=ABEFD-ZJbJ05OwQTcZWpECxYtzlfVWfzXlMRIFOuuyQ,10520
97
+ basic_memory/repository/entity_repository.py,sha256=q5aYVsdBdJ8vvNP0J8zAlUSEgosu9y7rRlEHVQj--zk,10409
98
98
  basic_memory/repository/observation_repository.py,sha256=qhMvHLSjaoT3Fa_cQOKsT5jYPj66GXSytEBMwLAgygQ,2943
99
99
  basic_memory/repository/project_info_repository.py,sha256=8XLVAYKkBWQ6GbKj1iqA9OK0FGPHdTlOs7ZtfeUf9t8,338
100
100
  basic_memory/repository/project_repository.py,sha256=sgdKxKTSiiOZTzABwUNqli7K5mbXiPiQEAc5r0RD_jQ,3159
@@ -115,13 +115,13 @@ basic_memory/schemas/search.py,sha256=ywMsDGAQK2sO2TT5lc-da_k67OKW1x1TenXormHHWv
115
115
  basic_memory/services/__init__.py,sha256=XGt8WX3fX_0K9L37Msy8HF8nlMZYIG3uQ6mUX6_iJtg,259
116
116
  basic_memory/services/context_service.py,sha256=4ReLAF5qifA9ayOePGsVKusw1TWj8oBzRECjrsFiKPI,14462
117
117
  basic_memory/services/directory_service.py,sha256=_YOPXseQM4knd7PIFAho9LV_E-FljVE5WVJKQ0uflZs,6017
118
- basic_memory/services/entity_service.py,sha256=R6iXgkGepWscbtErFKHWwsqk2IXWVOmst15IRZ6eBCA,30181
118
+ basic_memory/services/entity_service.py,sha256=o5S0pE17lV-_mMq_7i78fpLamhdzKm_NMqlmzpY2z-c,30165
119
119
  basic_memory/services/exceptions.py,sha256=oVjQr50XQqnFq1-MNKBilI2ShtHDxypavyDk1UeyHhw,390
120
120
  basic_memory/services/file_service.py,sha256=jCrmnEkTQ4t9HF7L_M6BL7tdDqjjzty9hpTo9AzwhvM,10059
121
- basic_memory/services/initialization.py,sha256=Lbnq5qH2S2vkQQHPSHU8UsTt2d9x0oj-Rvmty0s8WLQ,9675
121
+ basic_memory/services/initialization.py,sha256=HN1NhFTEPHjpzBwabVkvFbJ_ldXJXuNaww4ugh7MJos,9717
122
122
  basic_memory/services/link_resolver.py,sha256=1-_VFsvqdT5rVBHe8Jrq63U59XQ0hxGezxY8c24Tiow,4594
123
123
  basic_memory/services/migration_service.py,sha256=pFJCSD7UgHLx1CHvtN4Df1CzDEp-CZ9Vqx4XYn1m1M0,6096
124
- basic_memory/services/project_service.py,sha256=YDZl_e7R36D6KcObpBeMqIiM05oh9nOIfZFIFgIRxbY,27151
124
+ basic_memory/services/project_service.py,sha256=uLIrQB6T1DY3BXrEsLdB2ZlcKnPgjubyn-g6V9vMBzA,27928
125
125
  basic_memory/services/search_service.py,sha256=c5Ky0ufz7YPFgHhVzNRQ4OecF_JUrt7nALzpMjobW4M,12782
126
126
  basic_memory/services/service.py,sha256=V-d_8gOV07zGIQDpL-Ksqs3ZN9l3qf3HZOK1f_YNTag,336
127
127
  basic_memory/services/sync_status_service.py,sha256=PRAnYrsNJY8EIlxaxCrDsY0TjySDdhktjta8ReQZyiY,6838
@@ -131,8 +131,8 @@ basic_memory/sync/sync_service.py,sha256=AxC5J1YTcPWTmA0HdzvOZBthi4-_LZ44kNF0KQo
131
131
  basic_memory/sync/watch_service.py,sha256=JAumrHUjV1lF9NtEK32jgg0myWBfLXotNXxONeIV9SM,15316
132
132
  basic_memory/templates/prompts/continue_conversation.hbs,sha256=trrDHSXA5S0JCbInMoUJL04xvCGRB_ku1RHNQHtl6ZI,3076
133
133
  basic_memory/templates/prompts/search.hbs,sha256=H1cCIsHKp4VC1GrH2KeUB8pGe5vXFPqb2VPotypmeCA,3098
134
- basic_memory-0.13.7.dev1.dist-info/METADATA,sha256=G327sRhrodlQfEbQ9nsjus1KFj4eySxZhjmekX2OMtc,16537
135
- basic_memory-0.13.7.dev1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
- basic_memory-0.13.7.dev1.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
137
- basic_memory-0.13.7.dev1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
138
- basic_memory-0.13.7.dev1.dist-info/RECORD,,
134
+ basic_memory-0.13.8.dev1.dist-info/METADATA,sha256=04rwU_da1RIYuWb5CO4EjTQy3oS2NUDHRAU4sToEY7E,17229
135
+ basic_memory-0.13.8.dev1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
+ basic_memory-0.13.8.dev1.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
137
+ basic_memory-0.13.8.dev1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
138
+ basic_memory-0.13.8.dev1.dist-info/RECORD,,