basic-memory 0.1.0__py3-none-any.whl → 0.1.2__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.

Files changed (78) hide show
  1. basic_memory/__init__.py +1 -1
  2. basic_memory/alembic/README +1 -0
  3. basic_memory/alembic/env.py +75 -0
  4. basic_memory/alembic/migrations.py +29 -0
  5. basic_memory/alembic/script.py.mako +26 -0
  6. basic_memory/alembic/versions/3dae7c7b1564_initial_schema.py +93 -0
  7. basic_memory/api/__init__.py +2 -1
  8. basic_memory/api/app.py +26 -24
  9. basic_memory/api/routers/knowledge_router.py +28 -26
  10. basic_memory/api/routers/memory_router.py +17 -11
  11. basic_memory/api/routers/search_router.py +6 -12
  12. basic_memory/cli/__init__.py +1 -1
  13. basic_memory/cli/app.py +0 -1
  14. basic_memory/cli/commands/__init__.py +3 -3
  15. basic_memory/cli/commands/db.py +25 -0
  16. basic_memory/cli/commands/import_memory_json.py +35 -31
  17. basic_memory/cli/commands/mcp.py +20 -0
  18. basic_memory/cli/commands/status.py +10 -6
  19. basic_memory/cli/commands/sync.py +5 -56
  20. basic_memory/cli/main.py +5 -39
  21. basic_memory/config.py +3 -3
  22. basic_memory/db.py +19 -21
  23. basic_memory/deps.py +3 -4
  24. basic_memory/file_utils.py +36 -35
  25. basic_memory/markdown/entity_parser.py +13 -30
  26. basic_memory/markdown/markdown_processor.py +7 -7
  27. basic_memory/markdown/plugins.py +109 -123
  28. basic_memory/markdown/schemas.py +7 -8
  29. basic_memory/markdown/utils.py +70 -121
  30. basic_memory/mcp/__init__.py +1 -1
  31. basic_memory/mcp/async_client.py +0 -2
  32. basic_memory/mcp/server.py +3 -27
  33. basic_memory/mcp/tools/__init__.py +5 -3
  34. basic_memory/mcp/tools/knowledge.py +2 -2
  35. basic_memory/mcp/tools/memory.py +8 -4
  36. basic_memory/mcp/tools/search.py +2 -1
  37. basic_memory/mcp/tools/utils.py +1 -1
  38. basic_memory/models/__init__.py +1 -2
  39. basic_memory/models/base.py +3 -3
  40. basic_memory/models/knowledge.py +23 -60
  41. basic_memory/models/search.py +1 -1
  42. basic_memory/repository/__init__.py +5 -3
  43. basic_memory/repository/entity_repository.py +34 -98
  44. basic_memory/repository/relation_repository.py +0 -7
  45. basic_memory/repository/repository.py +2 -39
  46. basic_memory/repository/search_repository.py +21 -24
  47. basic_memory/schemas/__init__.py +4 -4
  48. basic_memory/schemas/base.py +21 -62
  49. basic_memory/schemas/delete.py +2 -3
  50. basic_memory/schemas/discovery.py +4 -1
  51. basic_memory/schemas/memory.py +12 -13
  52. basic_memory/schemas/request.py +4 -23
  53. basic_memory/schemas/response.py +10 -9
  54. basic_memory/schemas/search.py +4 -7
  55. basic_memory/services/__init__.py +2 -7
  56. basic_memory/services/context_service.py +116 -110
  57. basic_memory/services/entity_service.py +25 -62
  58. basic_memory/services/exceptions.py +1 -0
  59. basic_memory/services/file_service.py +73 -109
  60. basic_memory/services/link_resolver.py +9 -9
  61. basic_memory/services/search_service.py +22 -15
  62. basic_memory/services/service.py +3 -24
  63. basic_memory/sync/__init__.py +2 -2
  64. basic_memory/sync/file_change_scanner.py +3 -7
  65. basic_memory/sync/sync_service.py +38 -38
  66. basic_memory/sync/utils.py +6 -38
  67. basic_memory/sync/watch_service.py +26 -5
  68. basic_memory/utils.py +42 -33
  69. {basic_memory-0.1.0.dist-info → basic_memory-0.1.2.dist-info}/METADATA +2 -7
  70. basic_memory-0.1.2.dist-info/RECORD +78 -0
  71. basic_memory/cli/commands/init.py +0 -38
  72. basic_memory/mcp/main.py +0 -21
  73. basic_memory/mcp/tools/ai_edit.py +0 -84
  74. basic_memory/services/database_service.py +0 -158
  75. basic_memory-0.1.0.dist-info/RECORD +0 -75
  76. {basic_memory-0.1.0.dist-info → basic_memory-0.1.2.dist-info}/WHEEL +0 -0
  77. {basic_memory-0.1.0.dist-info → basic_memory-0.1.2.dist-info}/entry_points.txt +0 -0
  78. {basic_memory-0.1.0.dist-info → basic_memory-0.1.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,84 +0,0 @@
1
- """Tool for AI-assisted file editing."""
2
-
3
- from pathlib import Path
4
- from typing import List, Dict, Any
5
-
6
- from basic_memory.mcp.server import mcp
7
-
8
-
9
- def _detect_indent(text: str, match_pos: int) -> int:
10
- """Get indentation level at a position in text."""
11
- # Find start of line containing the match
12
- line_start = text.rfind("\n", 0, match_pos)
13
- if line_start < 0:
14
- line_start = 0
15
- else:
16
- line_start += 1 # Skip newline char
17
-
18
- # Count leading spaces
19
- pos = line_start
20
- while pos < len(text) and text[pos].isspace():
21
- pos += 1
22
- return pos - line_start
23
-
24
-
25
- def _apply_indent(text: str, spaces: int) -> str:
26
- """Apply indentation to text."""
27
- prefix = " " * spaces
28
- return "\n".join(prefix + line if line.strip() else line for line in text.split("\n"))
29
-
30
-
31
- @mcp.tool()
32
- async def ai_edit(path: str, edits: List[Dict[str, Any]]) -> bool:
33
- """AI-assisted file editing tool.
34
-
35
- Args:
36
- path: Path to file to edit
37
- edits: List of edits to apply. Each edit is a dict with:
38
- oldText: Text to replace
39
- newText: New content
40
- options: Optional dict with:
41
- indent: Number of spaces to indent
42
- preserveIndentation: Keep existing indent (default: true)
43
-
44
- Returns:
45
- bool: True if edits were applied successfully
46
- """
47
- try:
48
- # Read file
49
- content = Path(path).read_text()
50
- original = content
51
- success = True
52
-
53
- # Apply each edit
54
- for edit in edits:
55
- old_text = edit["oldText"]
56
- new_text = edit["newText"]
57
- options = edit.get("options", {})
58
-
59
- # Find text to replace
60
- match_pos = content.find(old_text)
61
- if match_pos < 0:
62
- success = False
63
- continue
64
-
65
- # Handle indentation
66
- if not options.get("preserveIndentation", True):
67
- # Use existing indentation
68
- indent = _detect_indent(content, match_pos)
69
- new_text = _apply_indent(new_text, indent)
70
- elif "indent" in options:
71
- # Use specified indentation
72
- new_text = _apply_indent(new_text, options["indent"])
73
-
74
- # Apply the edit
75
- content = content.replace(old_text, new_text)
76
-
77
- # Write back if changed
78
- if content != original:
79
- Path(path).write_text(content)
80
- return success
81
-
82
- except Exception as e:
83
- print(f"Error applying edits: {e}")
84
- return False
@@ -1,158 +0,0 @@
1
- """Service for managing database lifecycle and schema validation."""
2
-
3
- from datetime import datetime
4
- from pathlib import Path
5
- from typing import Optional, Tuple, List
6
-
7
- from alembic.runtime.migration import MigrationContext
8
- from alembic.autogenerate import compare_metadata
9
- from loguru import logger
10
- from sqlalchemy import MetaData
11
- from sqlalchemy.ext.asyncio import AsyncSession
12
-
13
- from basic_memory import db
14
- from basic_memory.config import ProjectConfig
15
- from basic_memory.models import Base
16
-
17
-
18
- async def check_schema_matches_models(session: AsyncSession) -> Tuple[bool, List[str]]:
19
- """Check if database schema matches SQLAlchemy models.
20
-
21
- Returns:
22
- tuple[bool, list[str]]: (matches, list of differences)
23
- """
24
- # Get current DB schema via migration context
25
- conn = await session.connection()
26
-
27
- def _compare_schemas(connection):
28
- context = MigrationContext.configure(connection)
29
- return compare_metadata(context, Base.metadata)
30
-
31
- # Run comparison in sync context
32
- differences = await conn.run_sync(_compare_schemas)
33
-
34
- if not differences:
35
- return True, []
36
-
37
- # Format differences into readable messages
38
- diff_messages = []
39
- for diff in differences:
40
- if diff[0] == 'add_table':
41
- diff_messages.append(f"Missing table: {diff[1].name}")
42
- elif diff[0] == 'remove_table':
43
- diff_messages.append(f"Extra table: {diff[1].name}")
44
- elif diff[0] == 'add_column':
45
- diff_messages.append(f"Missing column: {diff[3]} in table {diff[2]}")
46
- elif diff[0] == 'remove_column':
47
- diff_messages.append(f"Extra column: {diff[3]} in table {diff[2]}")
48
- elif diff[0] == 'modify_type':
49
- diff_messages.append(f"Column type mismatch: {diff[3]} in table {diff[2]}")
50
-
51
- return False, diff_messages
52
-
53
-
54
- class DatabaseService:
55
- """Manages database lifecycle including schema validation and backups."""
56
-
57
- def __init__(
58
- self,
59
- config: ProjectConfig,
60
- db_type: db.DatabaseType = db.DatabaseType.FILESYSTEM,
61
- ):
62
- self.config = config
63
- self.db_path = Path(config.database_path)
64
- self.db_type = db_type
65
-
66
- async def create_backup(self) -> Optional[Path]:
67
- """Create backup of existing database file.
68
-
69
- Returns:
70
- Optional[Path]: Path to backup file if created, None if no DB exists
71
- """
72
- if self.db_type == db.DatabaseType.MEMORY:
73
- return None # Skip backups for in-memory DB
74
-
75
- if not self.db_path.exists():
76
- return None
77
-
78
- # Create backup with timestamp
79
- timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
80
- backup_path = self.db_path.with_suffix(f".{timestamp}.backup")
81
-
82
- try:
83
- self.db_path.rename(backup_path)
84
- logger.info(f"Created database backup: {backup_path}")
85
-
86
- # make a new empty file
87
- self.db_path.touch()
88
- return backup_path
89
- except Exception as e:
90
- logger.error(f"Failed to create database backup: {e}")
91
- return None
92
-
93
- async def initialize_db(self):
94
- """Initialize database with current schema."""
95
- logger.info("Initializing database...")
96
-
97
- if self.db_type == db.DatabaseType.FILESYSTEM:
98
- await self.create_backup()
99
-
100
- # Drop existing tables if any
101
- await db.drop_db()
102
-
103
- # Create tables with current schema
104
- await db.get_or_create_db(
105
- db_path=self.db_path,
106
- db_type=self.db_type
107
- )
108
-
109
- logger.info("Database initialized with current schema")
110
-
111
- async def check_db(self) -> bool:
112
- """Check database state and rebuild if schema doesn't match models.
113
-
114
- Returns:
115
- bool: True if DB is ready for use, False if initialization failed
116
- """
117
- try:
118
- _, session_maker = await db.get_or_create_db(
119
- db_path=self.db_path,
120
- db_type=self.db_type
121
- )
122
- async with db.scoped_session(session_maker) as db_session:
123
- # Check actual schema matches
124
- matches, differences = await check_schema_matches_models(db_session)
125
- if not matches:
126
- logger.warning("Database schema does not match models:")
127
- for diff in differences:
128
- logger.warning(f" {diff}")
129
- logger.info("Rebuilding database to match current models...")
130
- await self.initialize_db()
131
- return True
132
-
133
- logger.info("Database schema matches models")
134
- return True
135
-
136
- except Exception as e:
137
- logger.error(f"Database initialization failed: {e}")
138
- return False
139
-
140
- async def cleanup_backups(self, keep_count: int = 5):
141
- """Clean up old database backups, keeping the N most recent."""
142
- if self.db_type == db.DatabaseType.MEMORY:
143
- return # Skip cleanup for in-memory DB
144
-
145
- backup_pattern = "*.backup" # Use relative pattern
146
- backups = sorted(
147
- self.db_path.parent.glob(backup_pattern),
148
- key=lambda p: p.stat().st_mtime,
149
- reverse=True,
150
- )
151
-
152
- # Remove old backups
153
- for backup in backups[keep_count:]:
154
- try:
155
- backup.unlink()
156
- logger.debug(f"Removed old backup: {backup}")
157
- except Exception as e:
158
- logger.error(f"Failed to remove backup {backup}: {e}")
@@ -1,75 +0,0 @@
1
- basic_memory/__init__.py,sha256=5AdJrNglWu8gvlZPWZDKmrYbpOaJJ7KcdBfSQxBl3A8,121
2
- basic_memory/config.py,sha256=bmNBTbbl8YhEsHOI0fnC7EfxIuyKB25LhtNuXzFlXnY,1671
3
- basic_memory/db.py,sha256=JA51udB4wg6HePJB1mnOqxaQCCoQAFVWf9gSSpZo9TY,4433
4
- basic_memory/deps.py,sha256=YeDwqEmqUTPOc-JdItE1NEj3iunB2j6thYotweHXq98,5316
5
- basic_memory/file_utils.py,sha256=-B-ixIGo4kf27nXE7mlyO5SljK-BhXvSN9rsXfJu0HQ,5814
6
- basic_memory/utils.py,sha256=FCXR_jQxr8qBtHSHkWoESEvSVwPiWjn5xfAPmyqYW0g,2321
7
- basic_memory/api/__init__.py,sha256=2y71HVPvGBIjx2tTd6nsSGeAFuFEyNn2MZ9IcqIs1hY,70
8
- basic_memory/api/app.py,sha256=RcljMzKZIETofuybHDCmQizFcXddDiLSxOPm3ggWF1Q,1755
9
- basic_memory/api/routers/__init__.py,sha256=iviQ1QVYobC8huUuyRhEjcA0BDjrOUm1lXHXhJkxP9A,239
10
- basic_memory/api/routers/knowledge_router.py,sha256=9t-ogIL8HVtGi6_eM-OAM8yY5VZZK-goSKSqbG9GLvI,5756
11
- basic_memory/api/routers/memory_router.py,sha256=YVM_2B1-1N-8ytmW9NcMwR5ee8ykM935s6psO-5uLuo,4231
12
- basic_memory/api/routers/resource_router.py,sha256=_Gp5HSJr-L-GUkQKbEP2bAZvCY8Smd-sBNWpGyqXS4c,1056
13
- basic_memory/api/routers/search_router.py,sha256=eKUibpJGuniLgTxXI_C28CjMrSNoXIrEwrlTBTkf1y4,1168
14
- basic_memory/cli/__init__.py,sha256=Hs6p69LnxlgO41EYFY0zMDCsbB3QxvPH9duNZz0hROs,32
15
- basic_memory/cli/app.py,sha256=gevKtdiAIlsJCbvegd1Pt7NID96Bq7yM1Hv2irHS0tY,35
16
- basic_memory/cli/main.py,sha256=lLX_K5stSd96HKUbNk24BQ__nq7TPQI7IUqeFnwHVzE,1139
17
- basic_memory/cli/commands/__init__.py,sha256=HAYxxI1wPPX6QfwuuLMmh_9wmND_U6-_tGtxcSIsF24,147
18
- basic_memory/cli/commands/import_memory_json.py,sha256=jpGJpEx8QuARi3ZurH4bvDSF-c3c_hTktNLps-0YsSo,5207
19
- basic_memory/cli/commands/init.py,sha256=5UmOasPd_65Evcw8QYWNZcrViBhWhrlFWCXOHtlrA1E,1189
20
- basic_memory/cli/commands/status.py,sha256=Dqp8mGR7vFpB-bVkIBRKvWeIkfDN7KyYaAKdtoAEYY4,5691
21
- basic_memory/cli/commands/sync.py,sha256=ycyD9yuZdKrtSd6L6sPQU1N3ang9FDIt5w-BHpqoD-c,8482
22
- basic_memory/markdown/__init__.py,sha256=DdzioCWtDnKaq05BHYLgL_78FawEHLpLXnp-kPSVfIc,501
23
- basic_memory/markdown/entity_parser.py,sha256=EBpBrmspZ7VbWdrro4K2fp5lCxMe-HKCcW5T3MoFB7s,4439
24
- basic_memory/markdown/markdown_processor.py,sha256=7XUagES8n4gRW8xt9KC7XTyO1spFNzal8kKWGiQvyMU,4985
25
- basic_memory/markdown/plugins.py,sha256=lc2C3kFsQdyw83j-T6ovT6489jr8QuUQ9Invqgj0Of0,7601
26
- basic_memory/markdown/schemas.py,sha256=fUNzaf2YNhDJlG_PmHdwmU0H_S_uf332jcuU9raGaXs,1839
27
- basic_memory/markdown/utils.py,sha256=jNSjpeDD2mBccbV3w5WXv6fzuiAKurU2jvT_vFOYbys,5234
28
- basic_memory/mcp/__init__.py,sha256=UioEZETQ-1lEfbqi1XirraBaiHdMHDX6JBpRZbAXTYY,34
29
- basic_memory/mcp/async_client.py,sha256=J4eSKs4VMef1AoWBHOwvzjS6kzfNntjg6cPxPpw56RQ,238
30
- basic_memory/mcp/main.py,sha256=X27Y4DvoLDkhnIy6wixdrtM_Jo0ShPqhMEBpmnTxPmM,503
31
- basic_memory/mcp/server.py,sha256=nSCgu7SCTMviZDi02FOD6PEsZumg1ZtTwvmpwIuxeXg,926
32
- basic_memory/mcp/tools/__init__.py,sha256=j3XpNTu-f0IeOFfo6ZNNtl728fzNwsN4w_kZQiMIE4U,820
33
- basic_memory/mcp/tools/ai_edit.py,sha256=0a6GTqJZdDyYhfecT23pP1VPPvk5bfPRX8bCFN_SKoE,2531
34
- basic_memory/mcp/tools/knowledge.py,sha256=OX-4Sz7Ox1so4USwuhf1iAL-I6bzzPgE5U0hajs-5Cc,2010
35
- basic_memory/mcp/tools/memory.py,sha256=OTKwcOZiGPRDceyNsadvcqqY5Azpb0C1MjvzZatKt3s,5252
36
- basic_memory/mcp/tools/notes.py,sha256=4GKnhDK53UkeZtpZENQ9id9XdemKxLzGwMQJeuX-Kok,3772
37
- basic_memory/mcp/tools/search.py,sha256=ViYLp-yGTxOEJli3PyE_JiBP3JXQ0fs-XLS09Sl7hoc,1103
38
- basic_memory/mcp/tools/utils.py,sha256=9sOE_zW-kr7zbwRRlLAhR5cCmcGfuewNsUtiInXULnk,4857
39
- basic_memory/models/__init__.py,sha256=VA_RP2xVrghTkOtILKvRDkn8EoP6UfjhnP8UgqupSkk,355
40
- basic_memory/models/base.py,sha256=SnOpuFxcw7QoLxXpmZ1NUoj1jEJKCXEWQqTIrXjJ3Z4,286
41
- basic_memory/models/knowledge.py,sha256=F2vfKalqfqumUlASN22QnPzaOym5MahzZ3sAACE3y9Y,6792
42
- basic_memory/models/search.py,sha256=iO1sgBiS1aVCts2EGfjys0i09-1_snxXs2pZNfK6Ojw,1163
43
- basic_memory/repository/__init__.py,sha256=Q1T0Qn1AcyUWLpPrFcfdEa3A1xUkAzt63tgv5U59DpI,241
44
- basic_memory/repository/entity_repository.py,sha256=Nn_ZS4K2cakMD_LVGJfGqQ-0SZ2W-dI_W8wfj-LM-ZQ,6008
45
- basic_memory/repository/observation_repository.py,sha256=BOcy4wARqCXu-thYyt7mPxt2A2C8TW0le3s_X9wrK6I,1701
46
- basic_memory/repository/relation_repository.py,sha256=mHZj3Uhapm9OG7NyTldIspJ7BdNKXKKjJD1lextQKGk,3234
47
- basic_memory/repository/repository.py,sha256=UCMy7VXjtkxkKCI3ZuQm4_RFRKJT0NBDhEvt_ueqjzc,12945
48
- basic_memory/repository/search_repository.py,sha256=V49xaEVGBTbZ-Tf1y8NaflQGAOQMupANtJ-RFFYou2w,9368
49
- basic_memory/schemas/__init__.py,sha256=m1Pou5ue1BNmHBm13WPBf3BJKKPsLaIYVnnGmgs2iwo,1618
50
- basic_memory/schemas/base.py,sha256=4O_uxXX_JDpMqPNk7jXduA3Ut3Uz1wjmrf27JlkI-e8,6694
51
- basic_memory/schemas/delete.py,sha256=_tSyTHAujVxkSUy5Cu3s6yHw-n3JmokjeMR6gZqJhG4,1198
52
- basic_memory/schemas/discovery.py,sha256=KtumdsujakYrl2rpX3bgIN-sK3826Cy_58nhq3vnl78,872
53
- basic_memory/schemas/memory.py,sha256=TPT1Lhsxk6Y1tuisx6XidcC2We_DdZxaNrvF2fidvNw,2909
54
- basic_memory/schemas/request.py,sha256=Cpz0cR5P-QdR9PAUapGfAxXhdooeVCH6X2G7MoOWMvw,2006
55
- basic_memory/schemas/response.py,sha256=7oWk3GDS626pdgN2MF__tp9c7WU-_9K7hs1F2quB65Y,6226
56
- basic_memory/schemas/search.py,sha256=7xlUc0HE13-v7iKy3eFs0IKasGbXVxCaq8GZ8qiUBTQ,3395
57
- basic_memory/services/__init__.py,sha256=5yx4U7iCi5gLjHxmkjeQ9JJoftWqy6P2gX2uV3ouMd0,279
58
- basic_memory/services/context_service.py,sha256=9DWryOhHfowelk4JVNIAlOycjblocTw38FSEP2kDkGI,8095
59
- basic_memory/services/database_service.py,sha256=qDeL2VL_bUExI30KS4xawKt3vS110QmcEbZav1gyOUE,5574
60
- basic_memory/services/entity_service.py,sha256=Lh63SEt-PCwGgazMx-KIVz-oEsNqX1JC7ktWZtvrVWw,12594
61
- basic_memory/services/exceptions.py,sha256=Z9cizi05f7QBY4HX6c0ywfzKk0_sie3283CP7gzy-dY,287
62
- basic_memory/services/file_service.py,sha256=oiS33BhD5zs7YgF6vMAgAvBBkHiLbUJ6g2cvN2JwymA,7166
63
- basic_memory/services/link_resolver.py,sha256=0OiWN8_m2niVBi5oUNss5nRFqIUTa1Qe1LmH8-oY64Y,4492
64
- basic_memory/services/search_service.py,sha256=yLXYs-PNimELM_5E44O25-fbD4PDzISsAwCm2dNPyQI,7842
65
- basic_memory/services/service.py,sha256=oHsHKMTC2ojRsxeNdnC4nA5YdTL72VYjDzWI_dbmzyA,1134
66
- basic_memory/sync/__init__.py,sha256=5BzfbvY-DKi-gswcjNzVqtNj4I0yXZ82CaupFiPihws,138
67
- basic_memory/sync/file_change_scanner.py,sha256=x2xFaxCzPy5seNLqK-TcN106U2--UKvAR7qoBeq8M84,5919
68
- basic_memory/sync/sync_service.py,sha256=fNBQtJwhLEdFcTTnSpLVnV-QWppETwXzhlsAMqODdnY,7026
69
- basic_memory/sync/utils.py,sha256=6P5-dvR5X-lA-BE3IZOzoC54uyiq9c_p9figRKaPq5E,2453
70
- basic_memory/sync/watch_service.py,sha256=HIronKujbBTbbosz0HAqLBLkP5IK3zH6gQKoTCrrA9o,6744
71
- basic_memory-0.1.0.dist-info/METADATA,sha256=j9Y6XhZAMMQZ-DehSV4Im7wuTfu4uOHKTWTaBnLDExw,7771
72
- basic_memory-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
73
- basic_memory-0.1.0.dist-info/entry_points.txt,sha256=IDQa_VmVTzmvMrpnjhEfM0S3F--XsVGEj3MpdJfuo-Q,59
74
- basic_memory-0.1.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
75
- basic_memory-0.1.0.dist-info/RECORD,,