basic-memory 0.13.0b5__py3-none-any.whl → 0.13.1__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,3 +1,4 @@
1
1
  """basic-memory - Local-first knowledge management combining Zettelkasten with knowledge graphs"""
2
2
 
3
- __version__ = "0.13.0b5"
3
+ # API version for FastAPI - independent of package version
4
+ __version__ = "v0"
@@ -174,7 +174,7 @@ def display_project_info(
174
174
  """Display detailed information and statistics about the current project."""
175
175
  try:
176
176
  # Get project info
177
- info = asyncio.run(project_info())
177
+ info = asyncio.run(project_info.fn()) # type: ignore # pyright: ignore [reportAttributeAccessIssue]
178
178
 
179
179
  if json_output:
180
180
  # Convert to JSON and print
@@ -90,7 +90,7 @@ def write_note(
90
90
  typer.echo("Empty content provided. Please provide non-empty content.", err=True)
91
91
  raise typer.Exit(1)
92
92
 
93
- note = asyncio.run(mcp_write_note(title, content, folder, tags))
93
+ note = asyncio.run(mcp_write_note.fn(title, content, folder, tags))
94
94
  rprint(note)
95
95
  except Exception as e: # pragma: no cover
96
96
  if not isinstance(e, typer.Exit):
@@ -103,7 +103,7 @@ def write_note(
103
103
  def read_note(identifier: str, page: int = 1, page_size: int = 10):
104
104
  """Read a markdown note from the knowledge base."""
105
105
  try:
106
- note = asyncio.run(mcp_read_note(identifier, page, page_size))
106
+ note = asyncio.run(mcp_read_note.fn(identifier, page, page_size))
107
107
  rprint(note)
108
108
  except Exception as e: # pragma: no cover
109
109
  if not isinstance(e, typer.Exit):
@@ -124,7 +124,7 @@ def build_context(
124
124
  """Get context needed to continue a discussion."""
125
125
  try:
126
126
  context = asyncio.run(
127
- mcp_build_context(
127
+ mcp_build_context.fn(
128
128
  url=url,
129
129
  depth=depth,
130
130
  timeframe=timeframe,
@@ -157,7 +157,7 @@ def recent_activity(
157
157
  """Get recent activity across the knowledge base."""
158
158
  try:
159
159
  context = asyncio.run(
160
- mcp_recent_activity(
160
+ mcp_recent_activity.fn(
161
161
  type=type, # pyright: ignore [reportArgumentType]
162
162
  depth=depth,
163
163
  timeframe=timeframe,
@@ -210,7 +210,7 @@ def search_notes(
210
210
  search_type = "text" if search_type is None else search_type
211
211
 
212
212
  results = asyncio.run(
213
- mcp_search(
213
+ mcp_search.fn(
214
214
  query,
215
215
  search_type=search_type,
216
216
  page=page,
@@ -241,7 +241,7 @@ def continue_conversation(
241
241
  """Prompt to continue a previous conversation or work session."""
242
242
  try:
243
243
  # Prompt functions return formatted strings directly
244
- session = asyncio.run(mcp_continue_conversation(topic=topic, timeframe=timeframe))
244
+ session = asyncio.run(mcp_continue_conversation.fn(topic=topic, timeframe=timeframe)) # type: ignore
245
245
  rprint(session)
246
246
  except Exception as e: # pragma: no cover
247
247
  if not isinstance(e, typer.Exit):
@@ -38,7 +38,7 @@ async def recent_activity_prompt(
38
38
  """
39
39
  logger.info(f"Getting recent activity, timeframe: {timeframe}")
40
40
 
41
- recent = await recent_activity(timeframe=timeframe, type=[SearchItemType.ENTITY])
41
+ recent = await recent_activity.fn(timeframe=timeframe, type=[SearchItemType.ENTITY])
42
42
 
43
43
  # Extract primary results from the hierarchical structure
44
44
  primary_results = []
@@ -81,7 +81,7 @@ async def read_note(
81
81
 
82
82
  # Fallback 1: Try title search via API
83
83
  logger.info(f"Search title for: {identifier}")
84
- title_results = await search_notes(query=identifier, search_type="title", project=project)
84
+ title_results = await search_notes.fn(query=identifier, search_type="title", project=project)
85
85
 
86
86
  if title_results and title_results.results:
87
87
  result = title_results.results[0] # Get the first/best match
@@ -105,7 +105,7 @@ async def read_note(
105
105
 
106
106
  # Fallback 2: Text search as a last resort
107
107
  logger.info(f"Title search failed, trying text search for: {identifier}")
108
- text_results = await search_notes(query=identifier, search_type="text", project=project)
108
+ text_results = await search_notes.fn(query=identifier, search_type="text", project=project)
109
109
 
110
110
  # We didn't find a direct match, construct a helpful error message
111
111
  if not text_results or not text_results.results:
@@ -37,7 +37,7 @@ async def view_note(
37
37
  logger.info(f"Viewing note: {identifier}")
38
38
 
39
39
  # Call the existing read_note logic
40
- content = await read_note(identifier, page, page_size, project)
40
+ content = await read_note.fn(identifier, page, page_size, project)
41
41
 
42
42
  # Check if this is an error message (note not found)
43
43
  if "# Note Not Found:" in content:
@@ -237,19 +237,24 @@ class SearchRepository:
237
237
 
238
238
  # Handle text search for title and content
239
239
  if search_text:
240
- # Check for explicit boolean operators - only detect them in proper boolean contexts
241
- has_boolean = any(op in f" {search_text} " for op in [" AND ", " OR ", " NOT "])
242
-
243
- if has_boolean:
244
- # If boolean operators are present, use the raw query
245
- # No need to prepare it, FTS5 will understand the operators
246
- params["text"] = search_text
247
- conditions.append("(title MATCH :text OR content_stems MATCH :text)")
240
+ # Skip FTS for wildcard-only queries that would cause "unknown special query" errors
241
+ if search_text.strip() == "*" or search_text.strip() == "":
242
+ # For wildcard searches, don't add any text conditions - return all results
243
+ pass
248
244
  else:
249
- # Standard search with term preparation
250
- processed_text = self._prepare_search_term(search_text.strip())
251
- params["text"] = processed_text
252
- conditions.append("(title MATCH :text OR content_stems MATCH :text)")
245
+ # Check for explicit boolean operators - only detect them in proper boolean contexts
246
+ has_boolean = any(op in f" {search_text} " for op in [" AND ", " OR ", " NOT "])
247
+
248
+ if has_boolean:
249
+ # If boolean operators are present, use the raw query
250
+ # No need to prepare it, FTS5 will understand the operators
251
+ params["text"] = search_text
252
+ conditions.append("(title MATCH :text OR content_stems MATCH :text)")
253
+ else:
254
+ # Standard search with term preparation
255
+ processed_text = self._prepare_search_term(search_text.strip())
256
+ params["text"] = processed_text
257
+ conditions.append("(title MATCH :text OR content_stems MATCH :text)")
253
258
 
254
259
  # Handle title match search
255
260
  if title:
@@ -299,7 +299,20 @@ class EntityService(BaseService[EntityModel]):
299
299
  # Mark as incomplete because we still need to add relations
300
300
  model.checksum = None
301
301
  # Repository will set project_id automatically
302
- return await self.repository.add(model)
302
+ try:
303
+ return await self.repository.add(model)
304
+ except IntegrityError as e:
305
+ # Handle race condition where entity was created by another process
306
+ if "UNIQUE constraint failed: entity.file_path" in str(
307
+ e
308
+ ) or "UNIQUE constraint failed: entity.permalink" in str(e):
309
+ logger.info(
310
+ f"Entity already exists for file_path={file_path} (file_path or permalink conflict), updating instead of creating"
311
+ )
312
+ return await self.update_entity_and_observations(file_path, markdown)
313
+ else:
314
+ # Re-raise if it's a different integrity error
315
+ raise
303
316
 
304
317
  async def update_entity_and_observations(
305
318
  self, file_path: Path, markdown: EntityMarkdown
@@ -209,8 +209,29 @@ class ProjectService:
209
209
  db_projects = await self.repository.get_active_projects()
210
210
  db_projects_by_name = {p.name: p for p in db_projects}
211
211
 
212
- # Get all projects from configuration
213
- config_projects = config_manager.projects
212
+ # Get all projects from configuration and normalize names if needed
213
+ config_projects = config_manager.projects.copy()
214
+ updated_config = {}
215
+ config_updated = False
216
+
217
+ for name, path in config_projects.items():
218
+ # Generate normalized name (what the database expects)
219
+ normalized_name = generate_permalink(name)
220
+
221
+ if normalized_name != name:
222
+ logger.info(f"Normalizing project name in config: '{name}' -> '{normalized_name}'")
223
+ config_updated = True
224
+
225
+ updated_config[normalized_name] = path
226
+
227
+ # Update the configuration if any changes were made
228
+ if config_updated:
229
+ config_manager.config.projects = updated_config
230
+ config_manager.save_config(config_manager.config)
231
+ logger.info("Config updated with normalized project names")
232
+
233
+ # Use the normalized config for further processing
234
+ config_projects = updated_config
214
235
 
215
236
  # Add projects that exist in config but not in DB
216
237
  for name, path in config_projects.items():
@@ -219,7 +240,7 @@ class ProjectService:
219
240
  project_data = {
220
241
  "name": name,
221
242
  "path": path,
222
- "permalink": name.lower().replace(" ", "-"),
243
+ "permalink": generate_permalink(name),
223
244
  "is_active": True,
224
245
  # Don't set is_default here - let the enforcement logic handle it
225
246
  }
@@ -364,18 +364,43 @@ class SyncService:
364
364
  content_type = self.file_service.content_type(path)
365
365
 
366
366
  file_path = Path(path)
367
- entity = await self.entity_repository.add(
368
- Entity(
369
- entity_type="file",
370
- file_path=path,
371
- checksum=checksum,
372
- title=file_path.name,
373
- created_at=created,
374
- updated_at=modified,
375
- content_type=content_type,
367
+ try:
368
+ entity = await self.entity_repository.add(
369
+ Entity(
370
+ entity_type="file",
371
+ file_path=path,
372
+ checksum=checksum,
373
+ title=file_path.name,
374
+ created_at=created,
375
+ updated_at=modified,
376
+ content_type=content_type,
377
+ )
376
378
  )
377
- )
378
- return entity, checksum
379
+ return entity, checksum
380
+ except IntegrityError as e:
381
+ # Handle race condition where entity was created by another process
382
+ if "UNIQUE constraint failed: entity.file_path" in str(e):
383
+ logger.info(
384
+ f"Entity already exists for file_path={path}, updating instead of creating"
385
+ )
386
+ # Treat as update instead of create
387
+ entity = await self.entity_repository.get_by_file_path(path)
388
+ if entity is None: # pragma: no cover
389
+ logger.error(f"Entity not found after constraint violation, path={path}")
390
+ raise ValueError(f"Entity not found after constraint violation: {path}")
391
+
392
+ updated = await self.entity_repository.update(
393
+ entity.id, {"file_path": path, "checksum": checksum}
394
+ )
395
+
396
+ if updated is None: # pragma: no cover
397
+ logger.error(f"Failed to update entity, entity_id={entity.id}, path={path}")
398
+ raise ValueError(f"Failed to update entity with ID {entity.id}")
399
+
400
+ return updated, checksum
401
+ else:
402
+ # Re-raise if it's a different integrity error
403
+ raise
379
404
  else:
380
405
  entity = await self.entity_repository.get_by_file_path(path)
381
406
  if entity is None: # pragma: no cover
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: basic-memory
3
- Version: 0.13.0b5
3
+ Version: 0.13.1
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
@@ -1,4 +1,4 @@
1
- basic_memory/__init__.py,sha256=GahMpH_d-907_9wZslmIx_KTDsdFvbhYBONrRrXphc0,125
1
+ basic_memory/__init__.py,sha256=kYTgbNYjpTOTrVbmkdvP8eII6KD0j3qf2LgF-q01dQQ,178
2
2
  basic_memory/config.py,sha256=lNpbn-b1k9nunQ-htciYQHC8XatRIhc_m6SN2Pbvp-E,11101
3
3
  basic_memory/db.py,sha256=X4-uyEZdJXVLfFDTpcNZxWzawRZXhDdKoEFWAGgE4Lk,6193
4
4
  basic_memory/deps.py,sha256=zXOhqXCoSVIa1iIcO8U6uUiofJn5eT4ycwJkH9I2kX4,12102
@@ -39,10 +39,10 @@ basic_memory/cli/commands/import_claude_conversations.py,sha256=sXnP0hjfwUapwHQD
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
41
  basic_memory/cli/commands/mcp.py,sha256=jmRUv1U5FT3AQ1cDbvTfAUnjhBw6UsNEmIkpbNr-_qQ,3093
42
- basic_memory/cli/commands/project.py,sha256=fOjbUryrS2aZMtgjMRq8Uw-oVyLZua_f3brc_1OA4Vw,12904
42
+ basic_memory/cli/commands/project.py,sha256=YkVYcjxQOVhxIX1M0g_vMaP5dTinYvSnUQIjeOPg8HE,12971
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
- basic_memory/cli/commands/tool.py,sha256=7wte1TqjG__NcC7BB0BRLl8THB3t5eAngud0zVHBQ8k,9506
45
+ basic_memory/cli/commands/tool.py,sha256=my-kALn3khv1W2Avi736NrHsfkpbyP57mDi5LjHwqe0,9540
46
46
  basic_memory/importers/__init__.py,sha256=BTcBW97P3thcsWa5w9tQsvOu8ynHDgw2-8tPgkCZoh8,795
47
47
  basic_memory/importers/base.py,sha256=awwe_U-CfzSINKoM6iro7ru4QqLlsfXzdHztDvebnxM,2531
48
48
  basic_memory/importers/chatgpt_importer.py,sha256=36VAsZarI7XE5r_KxNpWeHM1HPfHj6NfTDuH6ExY4hg,7372
@@ -66,7 +66,7 @@ basic_memory/mcp/supabase_auth_provider.py,sha256=MLHfSHjdx2Q5jr_Ljx0qZBaOwp7CkP
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
- basic_memory/mcp/prompts/recent_activity.py,sha256=Q-KKOt33hWVH4PSPO4AkCpc0y0rFPGFzARLN2MphKuY,3308
69
+ basic_memory/mcp/prompts/recent_activity.py,sha256=0v1c3b2SdDDxXVuF8eOjNooYy04uRYel0pdJ0rnggw4,3311
70
70
  basic_memory/mcp/prompts/search.py,sha256=nb88MZy9tdW_MmCLUVItiukrLdb3xEHWLv0JVLUlc4o,1692
71
71
  basic_memory/mcp/prompts/sync_status.py,sha256=_5EqnCavY9BTsaxX2tPp-AgQZLt4bUrqQ6TwbM0L5w8,4645
72
72
  basic_memory/mcp/prompts/utils.py,sha256=VacrbqwYtySpIlYIrKHo5s6jtoTMscYJqrFRH3zpC6Q,5431
@@ -81,12 +81,12 @@ basic_memory/mcp/tools/list_directory.py,sha256=-FxDsCru5YD02M4qkQDAurEJWyRaC7YI
81
81
  basic_memory/mcp/tools/move_note.py,sha256=esnbddG2OcmIgRNuQwx5OhlwZ1CWcOheg3hUobsEcq0,11320
82
82
  basic_memory/mcp/tools/project_management.py,sha256=XtZTFWi7--ku6yUR_vwHQx2Ka3vz3pCcWMhVa_y4CQs,12162
83
83
  basic_memory/mcp/tools/read_content.py,sha256=4FTw13B8UjVVhR78NJB9HKeJb_nA6-BGT1WdGtekN5Q,8596
84
- basic_memory/mcp/tools/read_note.py,sha256=RHju9Cqf8_-hzCdzMZH40YEln2RUe_EGAFkH7gcxblM,7487
84
+ basic_memory/mcp/tools/read_note.py,sha256=GdsJLkcDrCBnmNeM9BZRx9Xs2LUqH5ty_E471T9Kf1Y,7493
85
85
  basic_memory/mcp/tools/recent_activity.py,sha256=XVjNJAJnmxvzx9_Ls1A-QOd2yTR7pJlSTTuRxSivmN4,4833
86
86
  basic_memory/mcp/tools/search.py,sha256=22sLHed6z53mH9NQqBv37Xi4d6AtOTyrUvKs2Mycijk,11296
87
87
  basic_memory/mcp/tools/sync_status.py,sha256=mt0DdcaAlyiKW4NK4gy6psajSqcez0bOm_4MzG1NOdg,10486
88
88
  basic_memory/mcp/tools/utils.py,sha256=wsfrgiBScacMilODu85AXbUUKA5fJi4_6phDIC9dQRs,19702
89
- basic_memory/mcp/tools/view_note.py,sha256=7DBrlVinopS6wcYhoF1xzov0ObFHC1nxdEmEgFVVO9g,2496
89
+ basic_memory/mcp/tools/view_note.py,sha256=ddNXxyETsdA5SYflIaQVj_Cbd7I7CLVs3atRRDMbGmg,2499
90
90
  basic_memory/mcp/tools/write_note.py,sha256=TW_7-4QfX8GYZ-FU_iSSYAm1lucE7NeOcpZUypRXKOk,5912
91
91
  basic_memory/models/__init__.py,sha256=j0C4dtFi-FOEaQKR8dQWEG-dJtdQ15NBTiJg4nbIXNU,333
92
92
  basic_memory/models/base.py,sha256=4hAXJ8CE1RnjKhb23lPd-QM7G_FXIdTowMJ9bRixspU,225
@@ -100,7 +100,7 @@ basic_memory/repository/project_info_repository.py,sha256=8XLVAYKkBWQ6GbKj1iqA9O
100
100
  basic_memory/repository/project_repository.py,sha256=sgdKxKTSiiOZTzABwUNqli7K5mbXiPiQEAc5r0RD_jQ,3159
101
101
  basic_memory/repository/relation_repository.py,sha256=z7Oo5Zz_J-Bj6RvQDpSWR73ZLk2fxG7e7jrMbeFeJvQ,3179
102
102
  basic_memory/repository/repository.py,sha256=MJb-cb8QZQbL-Grq_iqv4Kq75aX2yQohLIqh5T4fFxw,15224
103
- basic_memory/repository/search_repository.py,sha256=HA8zO9rP1JbNEJEzNfvQVCMLgVahHiMhut8HxQ0Frwo,17549
103
+ basic_memory/repository/search_repository.py,sha256=CdALAsROY6W_rE1UB8Bn55ZdMv4DOmNOtShoXCwPI_Q,17897
104
104
  basic_memory/schemas/__init__.py,sha256=mEgIFcdTeb-v4y0gkOh_pA5zyqGbZk-9XbXqlSi6WMs,1674
105
105
  basic_memory/schemas/base.py,sha256=Fx97DEqzOr7y9zeeseO9qVBYbOft_4OQf9EiVfhOJn4,6738
106
106
  basic_memory/schemas/delete.py,sha256=UAR2JK99WMj3gP-yoGWlHD3eZEkvlTSRf8QoYIE-Wfw,1180
@@ -115,24 +115,24 @@ 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=9X3fjuOe30y9QOBvfWI4wyJhjVHH32jjHf8HWvaU540,29440
118
+ basic_memory/services/entity_service.py,sha256=KemsDkKkA7KItVtfsdAlYaGyOR8ryZQCu_O9GhkJucc,30103
119
119
  basic_memory/services/exceptions.py,sha256=oVjQr50XQqnFq1-MNKBilI2ShtHDxypavyDk1UeyHhw,390
120
120
  basic_memory/services/file_service.py,sha256=jCrmnEkTQ4t9HF7L_M6BL7tdDqjjzty9hpTo9AzwhvM,10059
121
121
  basic_memory/services/initialization.py,sha256=6ZeuTInPksyre4pjmiK_GXi5o_mJk3mfqGGH6apHxko,9271
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=j3744CmOj6iI6ugv4rEVZct3uFDaN-qQYX8isgSJZmw,25978
124
+ basic_memory/services/project_service.py,sha256=nWnrlnjISqtGP6ui1BR8rSTNFzwExW8u7mRYPtWJLok,26856
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
128
128
  basic_memory/sync/__init__.py,sha256=CVHguYH457h2u2xoM8KvOilJC71XJlZ-qUh8lHcjYj4,156
129
129
  basic_memory/sync/background_sync.py,sha256=4CEx8oP6-qD33uCeowhpzhA8wivmWxaCmSBP37h3Fs8,714
130
- basic_memory/sync/sync_service.py,sha256=oqUh5R8ABBgxXxJB9YbNKOziDk03fouUmcLe_LMLcow,21998
130
+ basic_memory/sync/sync_service.py,sha256=AxC5J1YTcPWTmA0HdzvOZBthi4-_LZ44kNF0KQoDRPw,23387
131
131
  basic_memory/sync/watch_service.py,sha256=JAumrHUjV1lF9NtEK32jgg0myWBfLXotNXxONeIV9SM,15316
132
132
  basic_memory/templates/prompts/continue_conversation.hbs,sha256=begMFHOPN3aCm5sHz5PlKMLOfZ8hlpFxFJ-hgy0T9K4,3075
133
133
  basic_memory/templates/prompts/search.hbs,sha256=H1cCIsHKp4VC1GrH2KeUB8pGe5vXFPqb2VPotypmeCA,3098
134
- basic_memory-0.13.0b5.dist-info/METADATA,sha256=m67Zt3zvqV9MK_ycxb8JlpEUJ1gTO9AGQ1Jy5DYsuHc,15471
135
- basic_memory-0.13.0b5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
- basic_memory-0.13.0b5.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
137
- basic_memory-0.13.0b5.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
138
- basic_memory-0.13.0b5.dist-info/RECORD,,
134
+ basic_memory-0.13.1.dist-info/METADATA,sha256=QvMkk2cw4_9jp63Zg4DJw3X20RnS9bCjHoBTyhFlLug,15469
135
+ basic_memory-0.13.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
136
+ basic_memory-0.13.1.dist-info/entry_points.txt,sha256=wvE2mRF6-Pg4weIYcfQ-86NOLZD4WJg7F7TIsRVFLb8,90
137
+ basic_memory-0.13.1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
138
+ basic_memory-0.13.1.dist-info/RECORD,,