kodit 0.2.1__py3-none-any.whl → 0.2.3__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 kodit might be problematic. Click here for more details.

@@ -6,20 +6,23 @@ system, database operations (via SourceRepository), and provides a clean API for
6
6
  source management.
7
7
  """
8
8
 
9
- import mimetypes
10
- import shutil
11
9
  from datetime import datetime
12
- from hashlib import sha256
13
10
  from pathlib import Path
14
11
 
15
- import aiofiles
16
- import git
17
12
  import pydantic
18
13
  import structlog
19
- from tqdm import tqdm
20
- from uritools import isuri, urisplit
21
14
 
22
- from kodit.source.source_models import File, Source
15
+ from kodit.source.git import is_valid_clone_target
16
+ from kodit.source.source_factories import (
17
+ FolderFileMetadataExtractor,
18
+ FolderSourceFactory,
19
+ FolderWorkingCopyProvider,
20
+ GitAuthorExtractor,
21
+ GitFileMetadataExtractor,
22
+ GitSourceFactory,
23
+ GitWorkingCopyProvider,
24
+ NoOpAuthorExtractor,
25
+ )
23
26
  from kodit.source.source_repository import SourceRepository
24
27
 
25
28
 
@@ -62,6 +65,32 @@ class SourceService:
62
65
  self.repository = repository
63
66
  self.log = structlog.get_logger(__name__)
64
67
 
68
+ # Initialize factories
69
+ self._setup_factories()
70
+
71
+ def _setup_factories(self) -> None:
72
+ # Git-specific dependencies
73
+ git_working_copy = GitWorkingCopyProvider(self.clone_dir)
74
+ git_metadata_extractor = GitFileMetadataExtractor()
75
+ git_author_extractor = GitAuthorExtractor(self.repository)
76
+ self.git_factory = GitSourceFactory(
77
+ working_copy=git_working_copy,
78
+ metadata_extractor=git_metadata_extractor,
79
+ author_extractor=git_author_extractor,
80
+ repository=self.repository,
81
+ )
82
+
83
+ # Folder-specific dependencies
84
+ folder_working_copy = FolderWorkingCopyProvider(self.clone_dir)
85
+ folder_metadata_extractor = FolderFileMetadataExtractor()
86
+ no_op_author_extractor = NoOpAuthorExtractor()
87
+ self.folder_factory = FolderSourceFactory(
88
+ working_copy=folder_working_copy,
89
+ metadata_extractor=folder_metadata_extractor,
90
+ author_extractor=no_op_author_extractor,
91
+ repository=self.repository,
92
+ )
93
+
65
94
  async def get(self, source_id: int) -> SourceView:
66
95
  """Get a source by ID.
67
96
 
@@ -83,126 +112,15 @@ class SourceService:
83
112
 
84
113
  async def create(self, uri_or_path_like: str) -> SourceView:
85
114
  """Create a new source from a URI or path."""
86
- if Path(uri_or_path_like).is_dir():
87
- return await self._create_folder_source(Path(uri_or_path_like))
88
- if isuri(uri_or_path_like):
89
- parsed = urisplit(uri_or_path_like)
90
- if parsed.scheme == "file":
91
- return await self._create_folder_source(Path(parsed.path))
92
- if parsed.scheme in ("git", "http", "https") and parsed.path.endswith(
93
- ".git"
94
- ):
95
- return await self._create_git_source(uri_or_path_like)
96
- if not uri_or_path_like.endswith(".git"):
97
- uri_or_path_like = uri_or_path_like.strip("/") + ".git"
98
- return await self._create_git_source(uri_or_path_like)
99
-
100
- msg = f"Unsupported source: {uri_or_path_like}"
101
- raise ValueError(msg)
102
-
103
- async def _create_folder_source(self, directory: Path) -> SourceView:
104
- """Create a folder source.
105
-
106
- Args:
107
- directory: The path to the local directory.
108
-
109
- Raises:
110
- ValueError: If the folder doesn't exist.
111
- SourceAlreadyExistsError: If the folder is already added.
112
-
113
- """
114
- # Resolve the directory to an absolute path
115
- directory = directory.expanduser().resolve()
116
-
117
- source = await self.repository.get_source_by_uri(directory.as_uri())
118
- if source:
119
- self.log.info("Source already exists, reusing...", source_id=source.id)
115
+ # If it's possible to clone it, then do so
116
+ if is_valid_clone_target(uri_or_path_like):
117
+ source = await self.git_factory.create(uri_or_path_like)
118
+ # Otherwise just treat it as a directory
119
+ elif Path(uri_or_path_like).is_dir():
120
+ source = await self.folder_factory.create(uri_or_path_like)
120
121
  else:
121
- # Check if the folder exists
122
- if not directory.exists():
123
- msg = f"Folder does not exist: {directory}"
124
- raise ValueError(msg)
125
-
126
- # Check if the folder is already added
127
- if await self.repository.get_source_by_uri(directory.as_uri()):
128
- msg = f"Directory already added: {directory}"
129
- raise ValueError(msg)
130
-
131
- # Clone into a local directory
132
- clone_path = self.clone_dir / directory.as_posix().replace("/", "_")
133
- clone_path.mkdir(parents=True, exist_ok=True)
134
-
135
- # Copy all files recursively, preserving directory structure, ignoring
136
- # hidden files
137
- shutil.copytree(
138
- directory,
139
- clone_path,
140
- ignore=shutil.ignore_patterns(".*"),
141
- dirs_exist_ok=True,
142
- )
143
-
144
- source = await self.repository.create_source(
145
- Source(uri=directory.as_uri(), cloned_path=str(clone_path)),
146
- )
147
-
148
- # Add all files to the source
149
- # Count total files for progress bar
150
- file_count = sum(1 for _ in clone_path.rglob("*") if _.is_file())
151
-
152
- # Process each file in the source directory
153
- for path in tqdm(clone_path.rglob("*"), total=file_count, leave=False):
154
- await self._process_file(source.id, path.absolute())
155
-
156
- return SourceView(
157
- id=source.id,
158
- uri=source.uri,
159
- cloned_path=Path(source.cloned_path),
160
- created_at=source.created_at,
161
- num_files=await self.repository.num_files_for_source(source.id),
162
- )
163
-
164
- async def _create_git_source(self, uri: str) -> SourceView:
165
- """Create a git source.
166
-
167
- Args:
168
- uri: The URI of the git repository.
169
-
170
- Raises:
171
- ValueError: If the repository cloning fails.
172
-
173
- """
174
- # Check if the repository is already added
175
- source = await self.repository.get_source_by_uri(uri)
176
-
177
- if source:
178
- self.log.info("Source already exists, reusing...", source_id=source.id)
179
- else:
180
- # Create a unique directory name for the clone
181
- clone_path = self.clone_dir / uri.replace("/", "_").replace(":", "_")
182
- clone_path.mkdir(parents=True, exist_ok=True)
183
-
184
- try:
185
- self.log.info("Cloning repository", uri=uri, clone_path=str(clone_path))
186
- git.Repo.clone_from(uri, clone_path)
187
- except git.GitCommandError as e:
188
- if "already exists and is not an empty directory" in str(e):
189
- self.log.info("Repository already exists, reusing...", uri=uri)
190
- else:
191
- msg = f"Failed to clone repository: {e}"
192
- raise ValueError(msg) from e
193
-
194
- source = await self.repository.create_source(
195
- Source(uri=uri, cloned_path=str(clone_path)),
196
- )
197
-
198
- # Add all files to the source
199
- # Count total files for progress bar
200
- file_count = sum(1 for _ in clone_path.rglob("*") if _.is_file())
201
-
202
- # Process each file in the source directory
203
- self.log.info("Inspecting files", source_id=source.id)
204
- for path in tqdm(clone_path.rglob("*"), total=file_count, leave=False):
205
- await self._process_file(source.id, path.absolute())
122
+ msg = f"Unsupported source: {uri_or_path_like}"
123
+ raise ValueError(msg)
206
124
 
207
125
  return SourceView(
208
126
  id=source.id,
@@ -212,34 +130,6 @@ class SourceService:
212
130
  num_files=await self.repository.num_files_for_source(source.id),
213
131
  )
214
132
 
215
- async def _process_file(
216
- self,
217
- source_id: int,
218
- cloned_path: Path,
219
- ) -> None:
220
- """Process a single file for indexing."""
221
- if not cloned_path.is_file():
222
- return
223
-
224
- async with aiofiles.open(cloned_path, "rb") as f:
225
- content = await f.read()
226
- mime_type = mimetypes.guess_type(cloned_path)
227
- sha = sha256(content).hexdigest()
228
-
229
- # Create file record
230
- file = File(
231
- source_id=source_id,
232
- cloned_path=cloned_path.as_posix(),
233
- mime_type=mime_type[0]
234
- if mime_type and mime_type[0]
235
- else "application/octet-stream",
236
- uri=cloned_path.as_uri(),
237
- sha256=sha,
238
- size_bytes=len(content),
239
- )
240
-
241
- await self.repository.create_file(file)
242
-
243
133
  async def list_sources(self) -> list[SourceView]:
244
134
  """List all available sources.
245
135
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kodit
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: Code indexing for better AI code generation
5
5
  Project-URL: Homepage, https://docs.helixml.tech/kodit/
6
6
  Project-URL: Documentation, https://docs.helixml.tech/kodit/
@@ -36,9 +36,10 @@ Requires-Dist: hf-xet>=1.1.2
36
36
  Requires-Dist: httpx-retries>=0.3.2
37
37
  Requires-Dist: httpx>=0.28.1
38
38
  Requires-Dist: openai>=1.82.0
39
- Requires-Dist: posthog>=4.0.1
39
+ Requires-Dist: pathspec>=0.12.1
40
40
  Requires-Dist: pydantic-settings>=2.9.1
41
41
  Requires-Dist: pytable-formatter>=0.1.1
42
+ Requires-Dist: rudder-sdk-python>=2.1.4
42
43
  Requires-Dist: sentence-transformers>=4.1.0
43
44
  Requires-Dist: sqlalchemy[asyncio]>=2.0.40
44
45
  Requires-Dist: structlog>=25.3.0
@@ -93,6 +94,7 @@ code. This index is used to build a snippet library, ready for ingestion into an
93
94
  - Build comprehensive snippet libraries for LLM ingestion
94
95
  - Support for multiple codebase types and languages
95
96
  - Efficient indexing and search capabilities
97
+ - Privacy first: respects .gitignore and .noindex files.
96
98
 
97
99
  ### MCP Server
98
100
 
@@ -1,48 +1,49 @@
1
1
  kodit/.gitignore,sha256=ztkjgRwL9Uud1OEi36hGQeDGk3OLK1NfDEO8YqGYy8o,11
2
2
  kodit/__init__.py,sha256=aEKHYninUq1yh6jaNfvJBYg-6fenpN132nJt1UU6Jxs,59
3
- kodit/_version.py,sha256=UoNvMtd4wCG76RwoSpNCUtaFyTwakGcZolfjXzNVSMY,511
4
- kodit/app.py,sha256=Mr5BFHOHx5zppwjC4XPWVvHjwgl1yrKbUjTWXKubJQM,891
5
- kodit/cli.py,sha256=i7eEt0FdIQGEfXKFte-8fBcZZGE8BPXBp40aGwJDQGI,11323
6
- kodit/config.py,sha256=KAxs6qdIvgRZEGTdDIl30QC0g56U0mdk-W8VlaVzghs,4472
3
+ kodit/_version.py,sha256=wD8hnA5gV5UmPkQnpT3xR6V2csgj9K5NEADogbLK79M,511
4
+ kodit/app.py,sha256=qKBWJ0VNSY_M6G3VFfAQ0133q5bnS99cUFD0p396taw,1032
5
+ kodit/cli.py,sha256=wKFXGUMX-fDLooaK-3po2TBpNNRBwgSD7BRbUddg-_M,11562
6
+ kodit/config.py,sha256=3yh7hfLSILjZK_qJMhcExwRcrWJ0b5Eb1JjjOvMPJZo,4146
7
7
  kodit/database.py,sha256=WB1KpVxUYPgiJGU0gJa2hqytYB8wJEJ5z3WayhWzNMU,2403
8
- kodit/log.py,sha256=HU1OmuxO4FcVw61k4WW7Y4WM7BrDaeplw1PcBHhuIZY,5434
8
+ kodit/log.py,sha256=sHPHYetlMcKTor2VaFLMyao1_fZ_xhuzqXCAt5F5UMU,8575
9
9
  kodit/mcp.py,sha256=QruyPskWB0_x59pkfj5BBeXuR13GMny5TAZEa2j4U9s,5752
10
10
  kodit/middleware.py,sha256=I6FOkqG9-8RH5kR1-0ZoQWfE4qLCB8lZYv8H_OCH29o,2714
11
11
  kodit/bm25/__init__.py,sha256=j8zyriNWhbwE5Lbybzg1hQAhANlU9mKHWw4beeUR6og,19
12
12
  kodit/bm25/keyword_search_factory.py,sha256=rp-wx3DJsc2KlELK1V337EyeYvmwnMQwUqOo1WVPSmg,631
13
13
  kodit/bm25/keyword_search_service.py,sha256=aBbWQKgQmi2re3EIHdXFS00n7Wj3b2D0pZsLZ4qmHfE,754
14
- kodit/bm25/local_bm25.py,sha256=cDx_hT9hXyEWz8LlFGyQs5-0ufK2Y4gArMfZv7-D9zQ,3621
15
- kodit/bm25/vectorchord_bm25.py,sha256=_nGrkUReYLLV-L8RIuIVLwjuhSYZl9T532n5OVf0kWs,6393
14
+ kodit/bm25/local_bm25.py,sha256=nokrd_xAeqXi3m68X5P1R5KBhRRB1E2L_J6Zgm26PCg,3869
15
+ kodit/bm25/vectorchord_bm25.py,sha256=0p_FgliaoevB8GLSmzWnV3zUjdcWgCgOKIpLURr7Qfo,6549
16
16
  kodit/embedding/__init__.py,sha256=h9NXzDA1r-K23nvBajBV-RJzHJN0p3UJ7UQsmdnOoRw,24
17
- kodit/embedding/embedding_factory.py,sha256=UGnFRyyQXazSUOwyW4Hg7Vq2-kfAoDj9lD4CTLu8x04,1630
17
+ kodit/embedding/embedding_factory.py,sha256=-WuXNleQ_mqdw1E4TczjtOawNeaXKAiDPFqN_XX7Mmg,2419
18
18
  kodit/embedding/embedding_models.py,sha256=rN90vSs86dYiqoawcp8E9jtwY31JoJXYfaDlsJK7uqc,656
19
19
  kodit/embedding/embedding_repository.py,sha256=-ux3scpBzel8c0pMH9fNOEsSXFIzl-IfgaWrkTb1szo,6907
20
- kodit/embedding/local_vector_search_service.py,sha256=hkF0qlfzjyGt400qIX9Mr6B7b7i8WvYIYWN2Z2C_pcs,1907
20
+ kodit/embedding/local_vector_search_service.py,sha256=dgMi8hQNUbYEgHnEYmLIpon4yLduoNUpu7k7VP6sOHI,2042
21
21
  kodit/embedding/vector_search_service.py,sha256=pQJ129QjGrAWOXzqkywmgtDRpy8_gtzYgkivyqF9Vrs,1009
22
- kodit/embedding/vectorchord_vector_search_service.py,sha256=63Xf7_nAz3xWOwrmZibw8Q-xoRdCrPDDpdSA_WE7mrc,5131
22
+ kodit/embedding/vectorchord_vector_search_service.py,sha256=TKNR3HgWHwwWtJ1SsvSaj_BXLJ_uw6Bdr_tpaePMeAA,5383
23
23
  kodit/embedding/embedding_provider/__init__.py,sha256=h9NXzDA1r-K23nvBajBV-RJzHJN0p3UJ7UQsmdnOoRw,24
24
- kodit/embedding/embedding_provider/embedding_provider.py,sha256=IC7fZaZ_ze-DxpxKfK44pRDwHWUQhVIqVKKQ3alO5Qc,1882
24
+ kodit/embedding/embedding_provider/embedding_provider.py,sha256=T6AKMWwzEJ1vDe-cEIg-qxdjhUEZ0PKs9YqQMWaLaQ0,1928
25
25
  kodit/embedding/embedding_provider/hash_embedding_provider.py,sha256=nAhlhh8j8PqqCCbhVl26Y8ntFBm2vJBCtB4X04g5Wwg,2638
26
26
  kodit/embedding/embedding_provider/local_embedding_provider.py,sha256=WP8lw6XG7v1_5Mw4_rhIOETooYRsxhkwmFaXCqCouQU,1977
27
- kodit/embedding/embedding_provider/openai_embedding_provider.py,sha256=V_jdUXiaGdslplwxMlfgFc4_hAVS2eaJXMTs2C7RiLI,2666
27
+ kodit/embedding/embedding_provider/openai_embedding_provider.py,sha256=-phz5FKYM_tI3Q4_3SPzjzIOK3k92Uk52TAOTmoVoWI,2722
28
28
  kodit/enrichment/__init__.py,sha256=vBEolHpKaHUhfINX0dSGyAPlvgpLNAer9YzFtdvCB24,18
29
- kodit/enrichment/enrichment_factory.py,sha256=vKjkUTdhj74IW2S4GENDWdWMJx6BwUSZjJGDC0i7DSk,787
29
+ kodit/enrichment/enrichment_factory.py,sha256=AAzvxgjo-FQU5aAm9Zla4DAwUMKGrcw8mQwJsMhIsHY,1566
30
30
  kodit/enrichment/enrichment_service.py,sha256=87Sd3gGbEMJYb_wVrHG8L1yGIZmQNR7foUS4_y94azI,977
31
31
  kodit/enrichment/enrichment_provider/__init__.py,sha256=klf8iuLVWX4iRz-DZQauFFNAoJC5CByczh48TBZPW-o,27
32
32
  kodit/enrichment/enrichment_provider/enrichment_provider.py,sha256=E0H5rq3OENM0yYbA8K_3nSnj5lUHCpoIOqpWLo-2MVU,413
33
- kodit/enrichment/enrichment_provider/local_enrichment_provider.py,sha256=kh_9X9m-WEziRi5TV6QflKXyXQTos9kzpmpGil7pywM,3196
34
- kodit/enrichment/enrichment_provider/openai_enrichment_provider.py,sha256=gYuFTAeIVdQNlCUvNSPgRoiRwCvRD0C8419h8ubyABA,2725
33
+ kodit/enrichment/enrichment_provider/local_enrichment_provider.py,sha256=RqwUD0BnwRQ8zlkFNkaKq8d58r33k2jIdnSdf6zla1w,3325
34
+ kodit/enrichment/enrichment_provider/openai_enrichment_provider.py,sha256=0Yw7h9RXptoI4bKuqJSKIRQXPUUhNV7eACavgoy_T8s,2874
35
35
  kodit/indexing/__init__.py,sha256=cPyi2Iej3G1JFWlWr7X80_UrsMaTu5W5rBwgif1B3xo,75
36
36
  kodit/indexing/fusion.py,sha256=TZb4fPAedXdEUXzwzOofW98QIOymdbclBOP1KOijuEk,1674
37
37
  kodit/indexing/indexing_models.py,sha256=6NX9HVcj6Pu9ePwHC7n-PWSyAgukpJq0nCNmUIigtbo,1282
38
38
  kodit/indexing/indexing_repository.py,sha256=dqOS0pxKM6bUjMXWqYukAK8XdiD36OnskFASgZRXRQM,6955
39
- kodit/indexing/indexing_service.py,sha256=_uhoqBic3_zXNJOsKt_w-TgX5ebf7OBwbqMdO9zectM,10779
39
+ kodit/indexing/indexing_service.py,sha256=3hW7vbFyabLEkLU-PRoGR49yVLewANdOKlye4GhR-tw,11467
40
40
  kodit/migrations/README,sha256=ISVtAOvqvKk_5ThM5ioJE-lMkvf9IbknFUFVU_vPma4,58
41
41
  kodit/migrations/__init__.py,sha256=lP5MuwlyWRMO6UcDWnQcQ3G-GYHcFb6rl9gYPHJ1sjo,40
42
42
  kodit/migrations/env.py,sha256=w1M7OZh-ZeR2dPHS0ByXAUxQjfZQ8xIzMseWuzLDTWw,2469
43
43
  kodit/migrations/script.py.mako,sha256=zWziKtiwYKEWuwPV_HBNHwa9LCT45_bi01-uSNFaOOE,703
44
44
  kodit/migrations/versions/7c3bbc2ab32b_add_embeddings_table.py,sha256=-61qol9PfQKILCDQRA5jEaats9aGZs9Wdtp-j-38SF4,1644
45
45
  kodit/migrations/versions/85155663351e_initial.py,sha256=Cg7zlF871o9ShV5rQMQ1v7hRV7fI59veDY9cjtTrs-8,3306
46
+ kodit/migrations/versions/9e53ea8bb3b0_add_authors.py,sha256=a32Zm8KUQyiiLkjKNPYdaJDgjW6VsV-GhaLnPnK_fpI,3884
46
47
  kodit/migrations/versions/__init__.py,sha256=9-lHzptItTzq_fomdIRBegQNm4Znx6pVjwD4MiqRIdo,36
47
48
  kodit/migrations/versions/c3f5137d30f5_index_all_the_things.py,sha256=rI8LmjF-I2OMxZ2nOIF_NRmqOLXe45hL_iz_nx97DTQ,1680
48
49
  kodit/snippets/__init__.py,sha256=-2coNoCRjTixU9KcP6alpmt7zqf37tCRWH3D7FPJ8dg,48
@@ -55,13 +56,16 @@ kodit/snippets/languages/javascript.scm,sha256=Ini5TsVNmcBKQ8aL46a5Id9ut0g9Udmvm
55
56
  kodit/snippets/languages/python.scm,sha256=ee85R9PBzwye3IMTE7-iVoKWd_ViU3EJISTyrFGrVeo,429
56
57
  kodit/snippets/languages/typescript.scm,sha256=U-ujbbv4tylbUBj9wuhL-e5cW6hmgPCNs4xrIX3r_hE,448
57
58
  kodit/source/__init__.py,sha256=1NTZyPdjThVQpZO1Mp1ColVsS7sqYanOVLqnoqV9Ipo,83
58
- kodit/source/source_models.py,sha256=kcC59XPSDDMth2mOYK3FakqTN0jxKFaTDch0ejyD9Sw,2446
59
- kodit/source/source_repository.py,sha256=0EksMpoLzdkfe8S4eeCm4Sf7TuxsOzOzaF4BBsMYo-4,3163
60
- kodit/source/source_service.py,sha256=dyXWf_t2qGvD9YAY3C5Zcxc63BbyrheL-jgTzXV7gqo,9156
59
+ kodit/source/git.py,sha256=CpNczc06SbxpzfQKq76lZFzuol10ZJvTRSzeXW9DFUs,363
60
+ kodit/source/ignore.py,sha256=W7cuIrYlgfu3S1qyoIepXe8PqYmtFv61Tt5RO8cbZbg,1701
61
+ kodit/source/source_factories.py,sha256=qTjKBKu62vynHUxf3-lgxQCoj1nGn8aI9ExFUWNk5B8,11678
62
+ kodit/source/source_models.py,sha256=XlgrY2dlpJkOFZQjrwMGwebAcwQ4rSfjshvCrHKA18Q,3916
63
+ kodit/source/source_repository.py,sha256=eme0C3pRqwFZ1ZSbqq4Z6SV9CC6AvRmiOjy3eHQoEN0,5443
64
+ kodit/source/source_service.py,sha256=E1KPG7TrorqdreJVHxZPx8CVLncOxGEvZ5uDQ6yZugo,5050
61
65
  kodit/util/__init__.py,sha256=bPu6CtqDWCRGU7VgW2_aiQrCBi8G89FS6k1PjvDajJ0,37
62
66
  kodit/util/spinner.py,sha256=R9bzrHtBiIH6IfLbmsIVHL53s8vg-tqW4lwGGALu4dw,1932
63
- kodit-0.2.1.dist-info/METADATA,sha256=Frs10m-Bc3DzgvxXSA27u0dFXDdV0fR_I4zzyhhPYfY,5768
64
- kodit-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
65
- kodit-0.2.1.dist-info/entry_points.txt,sha256=hoTn-1aKyTItjnY91fnO-rV5uaWQLQ-Vi7V5et2IbHY,40
66
- kodit-0.2.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
67
- kodit-0.2.1.dist-info/RECORD,,
67
+ kodit-0.2.3.dist-info/METADATA,sha256=ccZ0bl5PCGFNC30XSr-4ljL-JrkTgTfYlqZUlUPYba8,5867
68
+ kodit-0.2.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
69
+ kodit-0.2.3.dist-info/entry_points.txt,sha256=hoTn-1aKyTItjnY91fnO-rV5uaWQLQ-Vi7V5et2IbHY,40
70
+ kodit-0.2.3.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
71
+ kodit-0.2.3.dist-info/RECORD,,
File without changes