kash-shell 0.3.36__py3-none-any.whl → 0.3.37__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.
@@ -1,4 +1,4 @@
1
- from enum import Enum
1
+ from enum import StrEnum
2
2
  from pathlib import Path
3
3
  from urllib.parse import urlencode
4
4
 
@@ -55,7 +55,7 @@ def format_local_url(route_path: str, **params: str | None) -> str:
55
55
  return url
56
56
 
57
57
 
58
- class Route(str, Enum):
58
+ class Route(StrEnum):
59
59
  file_view = "/file/view"
60
60
  item_view = "/item/view"
61
61
  explain = "/explain"
@@ -5,34 +5,28 @@ from pathlib import Path
5
5
  from typing import TYPE_CHECKING
6
6
 
7
7
  from clideps.env_vars.dotenv_utils import load_dotenv_paths
8
- from httpx import Timeout
9
8
 
10
9
  from kash.config.logger import CustomLogger, get_logger
11
10
  from kash.config.settings import global_settings
12
11
  from kash.media_base.transcription_format import SpeakerSegment, format_speaker_segments
13
- from kash.utils.errors import ApiError, ContentError
12
+ from kash.utils.errors import ContentError
14
13
 
15
14
  if TYPE_CHECKING:
16
- from deepgram import PrerecordedResponse
15
+ from deepgram.types.listen_v1accepted_response import ListenV1AcceptedResponse
16
+ from deepgram.types.listen_v1response import ListenV1Response
17
17
 
18
18
  log: CustomLogger = get_logger(__name__)
19
19
 
20
20
 
21
21
  def deepgram_transcribe_raw(
22
22
  audio_file_path: Path, language: str | None = None
23
- ) -> PrerecordedResponse:
23
+ ) -> ListenV1Response | ListenV1AcceptedResponse:
24
24
  """
25
25
  Transcribe an audio file using Deepgram and return the raw response.
26
26
  """
27
27
  # Slow import, do lazily.
28
- from deepgram import (
29
- ClientOptionsFromEnv,
30
- DeepgramClient,
31
- FileSource,
32
- ListenRESTClient,
33
- PrerecordedOptions,
34
- PrerecordedResponse,
35
- )
28
+ from deepgram import DeepgramClient
29
+ from deepgram.core.request_options import RequestOptions
36
30
 
37
31
  size = getsize(audio_file_path)
38
32
  log.info(
@@ -40,21 +34,19 @@ def deepgram_transcribe_raw(
40
34
  )
41
35
 
42
36
  load_dotenv_paths(True, True, global_settings().system_config_dir)
43
- deepgram = DeepgramClient("", ClientOptionsFromEnv())
37
+ deepgram = DeepgramClient()
44
38
 
45
39
  with open(audio_file_path, "rb") as audio_file:
46
40
  buffer_data = audio_file.read()
47
41
 
48
- payload: FileSource = {
49
- "buffer": buffer_data,
50
- }
51
-
52
- options = PrerecordedOptions(model="nova-2", smart_format=True, diarize=True, language=language)
53
- client: ListenRESTClient = deepgram.listen.rest.v("1") # pyright: ignore
54
-
55
- response = client.transcribe_file(payload, options, timeout=Timeout(500))
56
- if not isinstance(response, PrerecordedResponse):
57
- raise ApiError("Deepgram returned an unexpected response type")
42
+ response = deepgram.listen.v1.media.transcribe_file(
43
+ request=buffer_data,
44
+ model="nova-2",
45
+ smart_format=True,
46
+ diarize=True,
47
+ language=language,
48
+ request_options=RequestOptions(timeout_in_seconds=500),
49
+ )
58
50
 
59
51
  return response
60
52
 
@@ -64,7 +56,9 @@ def deepgram_transcribe_audio(audio_file_path: Path, language: str | None = None
64
56
 
65
57
  log.save_object("Deepgram response", None, response)
66
58
 
67
- diarized_segments = _deepgram_diarized_segments(response)
59
+ # Convert Pydantic model to dict for processing.
60
+ response_dict = response.model_dump()
61
+ diarized_segments = _deepgram_diarized_segments(response_dict)
68
62
  log.debug("Diarized response: %s", diarized_segments)
69
63
 
70
64
  if not diarized_segments:
@@ -1,11 +1,11 @@
1
- from enum import Enum
1
+ from enum import StrEnum
2
2
 
3
3
  from pydantic import BaseModel
4
4
 
5
5
  from kash.exec_model.commands_model import CommentedCommand
6
6
 
7
7
 
8
- class Confidence(str, Enum):
8
+ class Confidence(StrEnum):
9
9
  """
10
10
  How confident the assistant is that the answer is correct.
11
11
  """
@@ -17,7 +17,7 @@
17
17
 
18
18
  import os
19
19
  from dataclasses import dataclass
20
- from enum import Enum
20
+ from enum import StrEnum
21
21
 
22
22
  NBSP = "\u00a0"
23
23
 
@@ -35,7 +35,7 @@ class Icon:
35
35
 
36
36
 
37
37
  # fmt: off
38
- class Icons(str, Enum):
38
+ class Icons(StrEnum):
39
39
  ARCHIVE = '\uf410' # 
40
40
  AUDIO = "\uf001" # 
41
41
  BINARY = "\ueae8" # 
@@ -67,7 +67,7 @@ https://www.ethanheilman.com/x/28/index.html
67
67
  # files, so that legacy shell commands automatically have tooltips with info
68
68
  # about files).
69
69
 
70
- from enum import Enum
70
+ from enum import StrEnum
71
71
  from html import escape
72
72
  from typing import Annotated, Literal, Self, TypeAlias
73
73
  from urllib.parse import parse_qs, quote, urlencode, urlparse
@@ -91,7 +91,7 @@ KUI_SCHEME = f"{KUI_PROTOCOL}//"
91
91
  """The Kerm code URI scheme for embedding UI elements into links."""
92
92
 
93
93
 
94
- class UIActionType(str, Enum):
94
+ class UIActionType(StrEnum):
95
95
  paste_text = "paste_text"
96
96
  """Default action for pasting text into the terminal. If value is omitted, paste the link text."""
97
97
 
@@ -120,7 +120,7 @@ class UIAction(BaseModel):
120
120
  return self.model_dump_json()
121
121
 
122
122
 
123
- class DisplayStyle(str, Enum):
123
+ class DisplayStyle(StrEnum):
124
124
  """
125
125
  Style for text.
126
126
  """
@@ -157,14 +157,14 @@ class DisplayHints(BaseModel):
157
157
  dimensions: Dimensions | None = Field(default=None, description="Dimensions.")
158
158
 
159
159
 
160
- class UIRole(str, Enum):
160
+ class UIRole(StrEnum):
161
161
  tooltip = "tooltip"
162
162
  popover = "popover"
163
163
  output = "output"
164
164
  input = "input"
165
165
 
166
166
 
167
- class UIElementType(str, Enum):
167
+ class UIElementType(StrEnum):
168
168
  text_tooltip = "text_tooltip"
169
169
  link_tooltip = "link_tooltip"
170
170
  iframe_tooltip = "iframe_tooltip"
@@ -32,13 +32,11 @@ class CachingSession(requests.Session):
32
32
  ):
33
33
  super().__init__()
34
34
  self._limiter: Limiter | None = None
35
+ self._max_wait_secs = max_wait_secs
35
36
  if limit and limit_interval_secs:
36
37
  rate = Rate(limit, Duration.SECOND * limit_interval_secs)
37
38
  bucket = InMemoryBucket([rate])
38
- # Explicitly set raise_when_fail=False and max_delay to enable blocking.
39
- self._limiter = Limiter(
40
- bucket, raise_when_fail=False, max_delay=Duration.SECOND * max_wait_secs
41
- )
39
+ self._limiter = Limiter(bucket)
42
40
  log.info(
43
41
  "CachingSession: rate limiting requests with limit=%d, interval=%d, max_wait=%d",
44
42
  limit,
@@ -56,9 +54,11 @@ class CachingSession(requests.Session):
56
54
 
57
55
  def save(path: Path):
58
56
  if self._limiter:
59
- acquired = self._limiter.try_acquire("caching_session_get")
57
+ acquired = self._limiter.try_acquire(
58
+ "caching_session_get", blocking=True, timeout=self._max_wait_secs
59
+ )
60
60
  if not acquired:
61
- # Generally shouldn't happen.
61
+ # Generally shouldn't happen with blocking=True and reasonable timeout.
62
62
  raise RuntimeError("Rate limiter failed to acquire after maximum delay")
63
63
 
64
64
  response = super(CachingSession, self).get(url, **kwargs)
@@ -94,7 +94,7 @@ content: |
94
94
  from __future__ import annotations
95
95
 
96
96
  from dataclasses import field
97
- from enum import Enum
97
+ from enum import Enum, StrEnum
98
98
  from io import StringIO
99
99
  from pathlib import Path
100
100
  from textwrap import dedent
@@ -106,7 +106,7 @@ from pydantic.dataclasses import dataclass
106
106
  from sidematter_format import to_json_string
107
107
 
108
108
 
109
- class ChatRole(str, Enum):
109
+ class ChatRole(StrEnum):
110
110
  """
111
111
  The role of a message in a chat. Represents the "role" in LLM APIs but note we slightly
112
112
  abuse this term to also represent other types of messages, such as commands issued
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from datetime import UTC, datetime
4
- from enum import Enum
4
+ from enum import StrEnum
5
5
  from pathlib import Path
6
6
  from typing import TYPE_CHECKING
7
7
 
@@ -20,7 +20,7 @@ if TYPE_CHECKING:
20
20
  log = get_logger(__name__)
21
21
 
22
22
 
23
- class SortOption(str, Enum):
23
+ class SortOption(StrEnum):
24
24
  filename = "filename"
25
25
  size = "size"
26
26
  accessed = "accessed"
@@ -28,13 +28,13 @@ class SortOption(str, Enum):
28
28
  modified = "modified"
29
29
 
30
30
 
31
- class GroupByOption(str, Enum):
31
+ class GroupByOption(StrEnum):
32
32
  flat = "flat"
33
33
  parent = "parent"
34
34
  suffix = "suffix"
35
35
 
36
36
 
37
- class FileType(str, Enum):
37
+ class FileType(StrEnum):
38
38
  file = "file"
39
39
  dir = "dir"
40
40
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.36
3
+ Version: 0.3.37
4
4
  Summary: The knowledge agent shell (core)
5
5
  Project-URL: Repository, https://github.com/jlevy/kash-shell
6
6
  Author-email: Joshua Levy <joshua@cal.berkeley.edu>
@@ -142,7 +142,7 @@ kash/llm_utils/llms.py,sha256=sGDrTnYAqjg_keKhXa7JR3HHkp5Klt-OhO3t9YjuhVQ,4036
142
142
  kash/local_server/__init__.py,sha256=AyNpvCOJlQF6A4DnlYKRMbbfRNzdizEA-ytp-F2SLZU,162
143
143
  kash/local_server/local_server.py,sha256=EugjL30VM0pWdZDsiQxU-o6EdEa082qlGd_7RHvI5tk,5863
144
144
  kash/local_server/local_server_commands.py,sha256=T5wN-Xty3IbwbyeJxTULPB2NqssWLJcuV8IoqMu9bus,1668
145
- kash/local_server/local_server_routes.py,sha256=JlIVsrbsU0yiwv7vAoD9BctqiBI0w6u8Ld3BYY4jmo8,10530
145
+ kash/local_server/local_server_routes.py,sha256=Qx9I2GLoACLYhTlT8-SxbnFe-SKqfhWB6wDMDSEQD2s,10531
146
146
  kash/local_server/local_url_formatters.py,sha256=SqHjGMEufvm43n34SCa_8Asdwm7utx91Wwymj15TuSY,5327
147
147
  kash/local_server/port_tools.py,sha256=oFfOvO6keqS5GowTpVg2FTu5KqkPHBq-dWAEomUIgGo,2008
148
148
  kash/local_server/rich_html_template.py,sha256=O9CnkMYkWuMvKJkqD0P8jaZqfUe6hMP4LXFvcLpwN8Q,196
@@ -159,13 +159,13 @@ kash/media_base/media_cache.py,sha256=wNguo9nNnCRmr7GERrzDOj83xCYife7EnVvC2tlNtr
159
159
  kash/media_base/media_services.py,sha256=kmAjLIrG62twI8GCowSeR1yfpVWf1KfAhPbuxPiaQAA,5475
160
160
  kash/media_base/media_tools.py,sha256=enzSebW41vDBGWUwkEn5udhRHmSBvH01MAt5rY1s388,1466
161
161
  kash/media_base/timestamp_citations.py,sha256=IHTvlZD3lIfe8T2uHFitgom82WahdHBeKqyc2OjUi9g,2368
162
- kash/media_base/transcription_deepgram.py,sha256=yuwqgTPY-d7XnLMTuNDX0PLBxazqOy8osDXEscNOrGo,5308
162
+ kash/media_base/transcription_deepgram.py,sha256=IXuGB8yRc4EMANCObxfedrAHktE1hVJGna-ZUkFCnf0,5191
163
163
  kash/media_base/transcription_format.py,sha256=rOVPTpwvW22c27BRwYF-Tc_xzqK_wOtUZpOPlvkHiDY,2344
164
164
  kash/media_base/transcription_whisper.py,sha256=GqvroW9kBAH4-gcbYkMgNCfs2MpMIgm1ip3NMWtJ0IE,1169
165
165
  kash/media_base/services/local_file_media.py,sha256=_NV-T90rShJ8ucUjQXMPCKKJ50GSFE9PyyVzhXp5z9w,5624
166
166
  kash/model/__init__.py,sha256=kFfBKb5N70NWYUfpRRxn_Sb9p_vXlB6BBaTCqWmSReo,2978
167
167
  kash/model/actions_model.py,sha256=I87Gb2nU6xelEuM8WFuuHWDqczjnlbpBYkw6wWIYkbo,23825
168
- kash/model/assistant_response_model.py,sha256=6eDfC27nyuBDFjv5nCYMa_Qb2mPbKwDzZy7uLOIyskI,2653
168
+ kash/model/assistant_response_model.py,sha256=tS0PmVxhdRXpBM-qNUGB4opyXUf5R4Z_4750w6mYCbA,2654
169
169
  kash/model/compound_actions_model.py,sha256=oYEtVKtQv-mA1abZkK7PvaM9xazVBUuk1z0geKBulak,6965
170
170
  kash/model/concept_model.py,sha256=we2qOcy9Mv1q7XPfkDLp_CyO_-8DwAUfUYlpgy_jrFs,1011
171
171
  kash/model/exec_model.py,sha256=3Su3NEmEtDoSuQSxvg75FYY_EdClSM5pwQK1i7_S88A,3131
@@ -185,7 +185,7 @@ kash/shell/completions/completion_scoring.py,sha256=-svesm2cR1AA86jYcxlynXCBZON2
185
185
  kash/shell/completions/completion_types.py,sha256=FocRXd6Df3Df0nL2Y1GevMx3FsljJwbQdVgWsIngpaQ,4793
186
186
  kash/shell/completions/shell_completions.py,sha256=A0WWrm2lEwguasDMnDuaI8xGny9MhwGfNvCY3rHNUnw,8844
187
187
  kash/shell/file_icons/color_for_format.py,sha256=bFuE1lwiyUkgWB3Gk3jrch-9EIQz9thILQiX_a5dGb8,2034
188
- kash/shell/file_icons/nerd_icons.py,sha256=qF1Awc5cWIwaOWo7k_nmG9_A6XXwdNNcaluUUlde3KM,36046
188
+ kash/shell/file_icons/nerd_icons.py,sha256=fxqICNUFXMy9miZxpr3dXAIEfQ-zUMweP3Ph3YjSR7Y,36047
189
189
  kash/shell/input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
190
190
  kash/shell/input/input_prompts.py,sha256=LkF7Q7HygBOVT1XzvC0dY7gfCVV0pedfwI5nlX-I6YA,3820
191
191
  kash/shell/input/inquirer_settings.py,sha256=2zOtgE2DJNzl4vEiEb_Dt8SUeM1YWjeXhCRaAPOCScM,1645
@@ -193,7 +193,7 @@ kash/shell/input/param_inputs.py,sha256=FiGClMtMe0pv0y_45qJ9PKF61vn8SOPiNeh5yvH0
193
193
  kash/shell/input/shell_confirm.py,sha256=A17HTxx_DPnis2503Q_LOEW8P9yIWvaj1zHVz4LSz_Q,1070
194
194
  kash/shell/output/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
195
195
  kash/shell/output/kerm_code_utils.py,sha256=92A4AV-IFKKZMWLNZnd_zksNFMBgE_VNXySyn0Kn6Zk,1673
196
- kash/shell/output/kerm_codes.py,sha256=KLVdTM_dL_NeYmGbllzsQoW4IHXJjEsgqqIp1s7P1yI,18877
196
+ kash/shell/output/kerm_codes.py,sha256=1ofHqH74XlUOH91_eLmn2PLx-yyd8usnbSKuJDczWqQ,18872
197
197
  kash/shell/output/kmarkdown.py,sha256=RRB5b0Ip0KZ71vnJKFfvxerYkeDFTCVTlHqHfmMy80Y,3675
198
198
  kash/shell/output/shell_formatting.py,sha256=oxmAeJ2j0ANYSUsL15CUv--KcGlQ6Wa_rywXSDlsZM4,3331
199
199
  kash/shell/output/shell_output.py,sha256=yG-4YjQUkPQZASMRGcfVRUadOcRO6hm-eaAC74jms6c,11812
@@ -206,7 +206,7 @@ kash/shell/utils/shell_function_wrapper.py,sha256=fgUuVhocYMKLkGJJQJOER5nFMAvM0Z
206
206
  kash/utils/__init__.py,sha256=4Jl_AtgRADdGORimWhYZwbSfQSpQ6SiexNIZzmbcngI,111
207
207
  kash/utils/errors.py,sha256=2lPL0fxI8pPOiDvjl0j-rvwY8uhmWetsrYYIc2-x1WY,3906
208
208
  kash/utils/api_utils/api_retries.py,sha256=TtgxLxoMnXIzYMKbMUzsnVcPf-aKFm3cJ95zOcSeae8,21844
209
- kash/utils/api_utils/cache_requests_limited.py,sha256=TA5buZ9Dgbj4I1zHhwerTXre018i0TCACGsezsjX9Uc,3140
209
+ kash/utils/api_utils/cache_requests_limited.py,sha256=4beytcBbZYuCXbT1QK8LaD98GBLnT3mcvjhFkNN0YII,3127
210
210
  kash/utils/api_utils/gather_limited.py,sha256=6K0Z3u_NeX9wBfFFk21wUQeSimaDIm53AHlGYRLD6LQ,33018
211
211
  kash/utils/api_utils/http_utils.py,sha256=Ou6QNiba5w7n71cgNmV168OFTLmMDNxWW5MM-XkFEME,1461
212
212
  kash/utils/api_utils/multitask_gather.py,sha256=LAylwWZ2APbv-O_l0kLwBfP762D0qswMBV8ID4eCOA0,4446
@@ -228,14 +228,14 @@ kash/utils/common/type_utils.py,sha256=SJirXhPilQom_-OKkFToDLm_82ZwpjcNjRy8U1HaQ
228
228
  kash/utils/common/uniquifier.py,sha256=75OY4KIVF8u1eoO0FCPbEGTyVpPOtM-0ctoG_s_jahM,3082
229
229
  kash/utils/common/url.py,sha256=u4qT0sWYsuEYazFCr3IIpmrR6nXyATH-_6GHM2xF5E0,9689
230
230
  kash/utils/common/url_slice.py,sha256=QJb_qJp-hd5lFrxpw7P009yeMTJWDMfF11KRKEo7mIA,10963
231
- kash/utils/file_formats/chat_format.py,sha256=XQpyUyq3jBKqM1f1eRZmg5hPBWZIobHNusQPFctFbRQ,11901
231
+ kash/utils/file_formats/chat_format.py,sha256=MY2Gz09p8c_-MxS8l2WkGAOP8os9Sw8c_ZcKrpqEzN4,11908
232
232
  kash/utils/file_utils/__init__.py,sha256=loL_iW0oOZs0mJ5GelBPptBcqzYKSWdsGcHrpRyxitQ,43
233
233
  kash/utils/file_utils/csv_utils.py,sha256=ZqchXD4y0buWtgnEsR_UeHyWBHM1wEJl5u-IxQvFa3s,4064
234
234
  kash/utils/file_utils/dir_info.py,sha256=HamMr58k_DanTLifj7A2JDxTGWXEZZx2pQuE6Hjcm8g,1856
235
235
  kash/utils/file_utils/file_ext.py,sha256=U0fG3rowgtc56fNhhCK8P1UCYFbCNoa87pv7mGiEQgA,1876
236
236
  kash/utils/file_utils/file_formats.py,sha256=4bq0-ZomFidL2GJBFyszGPurNQeTMOdLaXlGgrXznhA,4973
237
237
  kash/utils/file_utils/file_formats_model.py,sha256=WqtAb10_vBuWeP2cUHzUHNjNmLx5GdqPjsnuqziB6Zg,15970
238
- kash/utils/file_utils/file_sort_filter.py,sha256=_k1chT3dJl5lSmKA2PW90KaoG4k4zftGdtwWoNEljP4,7136
238
+ kash/utils/file_utils/file_sort_filter.py,sha256=Y-0Yw9-CaG0LMIaVo9dSTI-eLlvIzmnU0MoeJwMJBs0,7133
239
239
  kash/utils/file_utils/file_walk.py,sha256=cpwVDPuaVm95_ZwFJiAdIuZAGhASI3gJ3ZUsCGP75b8,5527
240
240
  kash/utils/file_utils/filename_parsing.py,sha256=drHrH2B9W_5yAbXURNGJxNqj9GmTe8FayH6Gjw9e4-U,4194
241
241
  kash/utils/file_utils/ignore_files.py,sha256=QJ0SFeGdxSCaf4v45qQE_BMsMT5nOgomma0TuJRibp8,3546
@@ -305,8 +305,8 @@ kash/xonsh_custom/xonsh_modern_tools.py,sha256=mj_b34LZXfE8MJe9EpDmp5JZ0tDM1biYN
305
305
  kash/xonsh_custom/xonsh_ranking_completer.py,sha256=ZRGiAfoEgqgnlq2-ReUVEaX5oOgW1DQ9WxIv2OJLuTo,5620
306
306
  kash/xontrib/fnm.py,sha256=V2tsOdmIDgbFbZSfMLpsvDIwwJJqiYnOkOySD1cXNXw,3700
307
307
  kash/xontrib/kash_extension.py,sha256=FLIMlgR3C_6A1fwKE-Ul0nmmpJSszVPbAriinUyQ8Zg,1896
308
- kash_shell-0.3.36.dist-info/METADATA,sha256=LK3nnR0TWHtw_F8qG9WSihteRlQZXggGY8f-DwtUjBQ,33581
309
- kash_shell-0.3.36.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
310
- kash_shell-0.3.36.dist-info/entry_points.txt,sha256=SQraWDAo8SqYpthLXThei0mf_hGGyhYBUO-Er_0HcwI,85
311
- kash_shell-0.3.36.dist-info/licenses/LICENSE,sha256=rCh2PsfYeiU6FK_0wb58kHGm_Fj5c43fdcHEexiVzIo,34562
312
- kash_shell-0.3.36.dist-info/RECORD,,
308
+ kash_shell-0.3.37.dist-info/METADATA,sha256=Nl6PtqxydXQXFJu9v7IKaioebse690jbQ68AB4myiXQ,33581
309
+ kash_shell-0.3.37.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
310
+ kash_shell-0.3.37.dist-info/entry_points.txt,sha256=SQraWDAo8SqYpthLXThei0mf_hGGyhYBUO-Er_0HcwI,85
311
+ kash_shell-0.3.37.dist-info/licenses/LICENSE,sha256=rCh2PsfYeiU6FK_0wb58kHGm_Fj5c43fdcHEexiVzIo,34562
312
+ kash_shell-0.3.37.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any