kash-shell 0.3.14__py3-none-any.whl → 0.3.15__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.
@@ -7,6 +7,7 @@ from strif import copyfile_atomic
7
7
 
8
8
  from kash.config.logger import get_logger
9
9
  from kash.exec import kash_command
10
+ from kash.exec.resolve_args import assemble_path_args
10
11
  from kash.exec_model.shell_model import ShellResult
11
12
  from kash.model.paths_model import StorePath
12
13
  from kash.shell.ui.shell_results import shell_print_selection_history
@@ -30,6 +31,7 @@ def select(
30
31
  clear_all: bool = False,
31
32
  clear_future: bool = False,
32
33
  refresh: bool = False,
34
+ no_check: bool = False,
33
35
  ) -> ShellResult:
34
36
  """
35
37
  Set or show the current selection.
@@ -51,6 +53,7 @@ def select(
51
53
  :param clear_all: Clear the full selection history.
52
54
  :param clear_future: Clear all selections from history after the current one.
53
55
  :param refresh: Refresh the current selection to drop any paths that no longer exist.
56
+ :param no_check: Do not check if the paths exist.
54
57
  """
55
58
  ws = current_ws()
56
59
 
@@ -68,6 +71,10 @@ def select(
68
71
  raise InvalidInput("Cannot combine multiple flags")
69
72
  if paths and any(exclusive_flags):
70
73
  raise InvalidInput("Cannot combine paths with other flags")
74
+ if not no_check:
75
+ for path in paths:
76
+ if not Path(ws.base_dir / path).exists():
77
+ raise InvalidInput(f"Path does not exist: {fmt_loc(path)}")
71
78
 
72
79
  if paths:
73
80
  store_paths = [StorePath(path) for path in paths]
@@ -203,3 +210,18 @@ def save(parent: str | None = None, to: str | None = None, no_frontmatter: bool
203
210
  for store_path in store_paths:
204
211
  target_path = target_dir / basename(store_path)
205
212
  copy_file(store_path, target_path)
213
+
214
+
215
+ @kash_command
216
+ def show_parent_dir(*paths: str) -> None:
217
+ """
218
+ Show the parent directory of the first item in the current selection.
219
+ """
220
+ from kash.commands.base.show_command import show
221
+
222
+ input_paths = assemble_path_args(*paths)
223
+ if not input_paths:
224
+ raise InvalidInput("No paths provided")
225
+
226
+ input_path = current_ws().resolve_to_abs_path(input_paths[0])
227
+ show(input_path.parent)
@@ -59,6 +59,7 @@ from kash.utils.errors import InvalidInput
59
59
  from kash.utils.file_formats.chat_format import tail_chat_history
60
60
  from kash.utils.file_utils.dir_info import is_nonempty_dir
61
61
  from kash.utils.file_utils.file_formats_model import Format
62
+ from kash.utils.text_handling.doc_normalization import can_normalize
62
63
  from kash.web_content.file_cache_utils import cache_file
63
64
  from kash.workspaces import (
64
65
  current_ws,
@@ -189,11 +190,13 @@ def cache_content(*urls_or_paths: str, refetch: bool = False) -> None:
189
190
 
190
191
 
191
192
  @kash_command
192
- def download(*urls_or_paths: str, refetch: bool = False) -> ShellResult:
193
+ def download(*urls_or_paths: str, refetch: bool = False, no_format: bool = False) -> ShellResult:
193
194
  """
194
195
  Download a URL or resource. Uses cached content if available, unless `refetch` is true.
195
196
  Inputs can be URLs or paths to URL resources.
196
197
  Creates both resource and document versions for text content.
198
+
199
+ :param no_format: If true, do not also normalize Markdown content.
197
200
  """
198
201
  ws = current_ws()
199
202
  saved_paths = []
@@ -236,11 +239,13 @@ def download(*urls_or_paths: str, refetch: bool = False) -> ShellResult:
236
239
  mime_type=mime_type,
237
240
  original_filename=original_filename,
238
241
  )
242
+ # For initial content, do not format or add frontmatter.
239
243
  store_path = ws.save(resource_item, no_frontmatter=True, no_format=True)
240
244
  saved_paths.append(store_path)
245
+ select(store_path)
241
246
 
242
- # Also create a doc version for text content
243
- if resource_item.format and resource_item.format.supports_frontmatter:
247
+ # Also create a doc version for text content if we want to normalize formatting.
248
+ if resource_item.format and can_normalize(resource_item.format) and not no_format:
244
249
  doc_item = Item.from_external_path(
245
250
  cache_result.content.path,
246
251
  ItemType.doc,
@@ -248,8 +253,10 @@ def download(*urls_or_paths: str, refetch: bool = False) -> ShellResult:
248
253
  mime_type=mime_type,
249
254
  original_filename=original_filename,
250
255
  )
251
- doc_store_path = ws.save(doc_item, no_frontmatter=False, no_format=False)
256
+ # Now use default formatting and frontmatter.
257
+ doc_store_path = ws.save(doc_item)
252
258
  saved_paths.append(doc_store_path)
259
+ select(doc_store_path)
253
260
 
254
261
  print_status(
255
262
  "Downloaded %s %s:\n%s",
@@ -257,7 +264,6 @@ def download(*urls_or_paths: str, refetch: bool = False) -> ShellResult:
257
264
  plural("item", len(saved_paths)),
258
265
  fmt_lines(saved_paths),
259
266
  )
260
- select(*saved_paths)
261
267
 
262
268
  return ShellResult(show_selection=True)
263
269
 
kash/exec/action_exec.py CHANGED
@@ -1,7 +1,8 @@
1
1
  import time
2
2
  from dataclasses import replace
3
+ from pathlib import Path
3
4
 
4
- from prettyfmt import fmt_lines, plural
5
+ from prettyfmt import fmt_lines, fmt_path, plural
5
6
 
6
7
  from kash.config.logger import get_logger
7
8
  from kash.config.text_styles import (
@@ -287,6 +288,14 @@ def save_action_result(
287
288
  Save the result of an action to the workspace. Handles skipping duplicates and
288
289
  archiving old inputs, if appropriate, based on hints in the ActionResult.
289
290
  """
291
+ # If an action returned an external path, we should confirm it exists or it is probably
292
+ # a bug in the action.
293
+ for item in result.items:
294
+ if item.external_path and not Path(item.external_path).exists():
295
+ raise InvalidOutput(
296
+ f"External path returned by action does not exist: {fmt_path(item.external_path)}"
297
+ )
298
+
290
299
  input_items = action_input.items
291
300
 
292
301
  skipped_paths = []
@@ -377,7 +386,11 @@ def run_action_with_caching(
377
386
  # Run it!
378
387
  result = run_action_operation(context, action_input, operation)
379
388
  result_store_paths, archived_store_paths = save_action_result(
380
- ws, result, action_input, as_tmp=settings.tmp_output, no_format=settings.no_format
389
+ ws,
390
+ result,
391
+ action_input,
392
+ as_tmp=settings.tmp_output,
393
+ no_format=settings.no_format,
381
394
  )
382
395
 
383
396
  PrintHooks.before_done_message()
@@ -448,13 +461,19 @@ def run_action_with_shell_context(
448
461
 
449
462
  # As a special case for convenience, if the action expects no args, ignore any pre-selected inputs.
450
463
  if action.expected_args == NO_ARGS and from_selection:
451
- log.message("Not using current selection since action `%s` expects no args.", action_name)
464
+ log.message(
465
+ "Not using current selection since action `%s` expects no args.",
466
+ action_name,
467
+ )
452
468
  args.clear()
453
469
 
454
470
  if args:
455
471
  source_str = "provided args" if provided_args else "selection"
456
472
  log.message(
457
- "Using %s as inputs to action `%s`:\n%s", source_str, action_name, fmt_lines(args)
473
+ "Using %s as inputs to action `%s`:\n%s",
474
+ source_str,
475
+ action_name,
476
+ fmt_lines(args),
458
477
  )
459
478
 
460
479
  # Get items for each input arg.
@@ -16,11 +16,13 @@ def kash_precondition(func: Callable[[Item], bool]) -> Precondition:
16
16
  """
17
17
  Decorator to register a function as a Precondition.
18
18
  The function should return a bool and/or raise `PreconditionFailure`.
19
+ Returns an actual Precondition object, not the function, so that it's possible to
20
+ do precondition algebra, e.g. `is_file & has_body`.
19
21
 
20
22
  Example:
21
- @register_precondition
22
- def is_file(item: Item) -> bool:
23
- return item.is_file()
23
+ @kash_precondition
24
+ def has_body(item: Item) -> bool:
25
+ return item.has_body()
24
26
  """
25
27
  precondition = Precondition(func)
26
28
 
@@ -104,6 +104,11 @@ def has_html_body(item: Item) -> bool:
104
104
  return bool(has_body(item) and item.format and item.format.is_html)
105
105
 
106
106
 
107
+ @kash_precondition
108
+ def has_html_compatible_body(item: Item) -> bool:
109
+ return bool(has_body(item) and item.format and item.format.is_html_compatible)
110
+
111
+
107
112
  @kash_precondition
108
113
  def has_markdown_body(item: Item) -> bool:
109
114
  return bool(has_body(item) and item.format and item.format.is_markdown)
@@ -136,14 +141,14 @@ def is_markdown_with_html(item: Item) -> bool:
136
141
 
137
142
  @kash_precondition
138
143
  def is_markdown_template(item: Item) -> bool:
139
- return is_markdown(item) and contains_curly_vars(item)
144
+ return has_markdown_body(item) and contains_curly_vars(item)
140
145
 
141
146
 
142
147
  @kash_precondition
143
148
  def is_markdown_list(item: Item) -> bool:
144
149
  try:
145
150
  return (
146
- is_markdown(item)
151
+ has_markdown_body(item)
147
152
  and item.body is not None
148
153
  and len(extract_bullet_points(item.body)) >= 2
149
154
  )
kash/exec/resolve_args.py CHANGED
@@ -42,7 +42,7 @@ def resolve_path_arg(path_str: UnresolvedPath) -> Path | StorePath:
42
42
  return path
43
43
  else:
44
44
  try:
45
- store_path = current_ws().resolve_path(path)
45
+ store_path = current_ws().resolve_to_store_path(path)
46
46
  if store_path:
47
47
  return store_path
48
48
  else:
@@ -110,7 +110,7 @@ def resolvable_paths(paths: Sequence[StorePath | Path]) -> list[StorePath]:
110
110
  current workspace.
111
111
  """
112
112
  ws = current_ws()
113
- resolvable = list(filter(None, (ws.resolve_path(p) for p in paths)))
113
+ resolvable = list(filter(None, (ws.resolve_to_store_path(p) for p in paths)))
114
114
  return resolvable
115
115
 
116
116
 
@@ -182,7 +182,7 @@ class FileStore(Workspace):
182
182
  except (FileNotFoundError, InvalidFilename):
183
183
  pass
184
184
 
185
- def resolve_path(self, path: Path | StorePath) -> StorePath | None:
185
+ def resolve_to_store_path(self, path: Path | StorePath) -> StorePath | None:
186
186
  """
187
187
  Return a StorePath if the given path is within the store, otherwise None.
188
188
  If it is already a StorePath, return it unchanged.
@@ -195,6 +195,21 @@ class FileStore(Workspace):
195
195
  else:
196
196
  return None
197
197
 
198
+ def resolve_to_abs_path(self, path: Path | StorePath) -> Path:
199
+ """
200
+ Return an absolute path, resolving any store paths to within the store
201
+ and resolving other paths like regular `Path.resolve()`.
202
+ """
203
+ store_path = self.resolve_to_store_path(path)
204
+ if store_path:
205
+ return self.base_dir / store_path
206
+ elif path.is_absolute():
207
+ return path
208
+ else:
209
+ # Unspecified relative paths resolved to cwd.
210
+ # TODO: Consider if such paths might be store paths.
211
+ return path.resolve()
212
+
198
213
  def exists(self, store_path: StorePath) -> bool:
199
214
  """
200
215
  Check given store path refers to an existing file.
kash/model/items_model.py CHANGED
@@ -628,7 +628,7 @@ class Item:
628
628
  if not display_title and self.store_path:
629
629
  display_title = Path(self.store_path).name
630
630
  if not display_title:
631
- display_title = self.abbrev_title()
631
+ display_title = self.abbrev_title(pull_body_heading=True)
632
632
  return display_title
633
633
 
634
634
  def abbrev_description(self, max_len: int = 1000) -> str:
@@ -143,17 +143,23 @@ class Format(Enum):
143
143
 
144
144
  @property
145
145
  def is_markdown(self) -> bool:
146
- """Is in pure Markdown (no HTML)."""
146
+ """Is this pure Markdown? Does not include Markdown mixed with HTML."""
147
147
  return self in [self.markdown]
148
148
 
149
149
  @property
150
150
  def is_markdown_with_html(self) -> bool:
151
- """Is in Markdown with HTML."""
151
+ """Is this Markdown mixed with HTML?"""
152
152
  return self in [self.md_html]
153
153
 
154
154
  @property
155
155
  def is_html(self) -> bool:
156
- return self in [self.html, self.md_html]
156
+ """Is this format HTML? Does not include Markdown mixed with HTML."""
157
+ return self in [self.html]
158
+
159
+ @property
160
+ def is_html_compatible(self) -> bool:
161
+ """Is this format directly compatible with HTML (any combination of text, markdown, or HTML)?"""
162
+ return self in [self.plaintext, self.markdown, self.md_html, self.html]
157
163
 
158
164
  @property
159
165
  def is_data(self) -> bool:
@@ -9,6 +9,13 @@ from kash.utils.file_utils.file_formats_model import Format, detect_file_format
9
9
  from kash.utils.rich_custom.ansi_cell_len import ansi_cell_len
10
10
 
11
11
 
12
+ def can_normalize(format: Format) -> bool:
13
+ """
14
+ True for Markdown (the only format we currently normalize).
15
+ """
16
+ return format == Format.markdown or format == Format.md_html
17
+
18
+
12
19
  def normalize_formatting(
13
20
  text: str,
14
21
  format: Format | None,
@@ -121,13 +121,17 @@ h1 {
121
121
 
122
122
  h2 {
123
123
  font-size: 1.4rem;
124
- margin-top: 1.5rem;
124
+ margin-top: 2rem;
125
125
  margin-bottom: 1rem;
126
126
  }
127
127
 
128
+ h1 + h2 {
129
+ margin-top: 2rem;
130
+ }
131
+
128
132
  h3 {
129
133
  font-size: 1.03rem;
130
- margin-top: 1.5rem;
134
+ margin-top: 1.6rem;
131
135
  margin-bottom: 0.5rem;
132
136
  }
133
137
 
@@ -340,7 +344,7 @@ tbody tr:nth-child(even) {
340
344
  left: 50%;
341
345
  transform: translateX(-50%);
342
346
  box-sizing: border-box;
343
- margin-bottom: 1rem;
347
+ margin: 2rem 0;
344
348
  background-color: var(--color-bg-solid);
345
349
  }
346
350
  {% endblock table_styles %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.14
3
+ Version: 0.3.15
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>
@@ -33,8 +33,8 @@ kash/commands/help/doc_commands.py,sha256=7lKR7mzue2N7pSkNqblpFJy892fS5N6jWVOHqe
33
33
  kash/commands/help/help_commands.py,sha256=eJTpIhXck123PAUq2k-D3Q6UL6IQ8atOVYurLi2GD0A,4229
34
34
  kash/commands/help/logo.py,sha256=W8SUach9FjoTqpHZwTGS582ry4ZluxbBp86ZCiAtDkY,3505
35
35
  kash/commands/help/welcome.py,sha256=F4QBgj3e1dM9Pf0H4TSzCrkVfXQVKUIl0b6Qmofbdo4,905
36
- kash/commands/workspace/selection_commands.py,sha256=yr0fFPlFIJUPHyFni1byXz8UDvYstIw4oRpOMa8iOBo,7428
37
- kash/commands/workspace/workspace_commands.py,sha256=smPNGmY8y7gcmh0hAFOf4GYYMuNAoqkf3kRMJamYcMQ,24768
36
+ kash/commands/workspace/selection_commands.py,sha256=nZzA-H7Pk8kqSJVRlX7j1m6cZX-e0X8isOryDU41vqU,8156
37
+ kash/commands/workspace/workspace_commands.py,sha256=ZJ3aPsnQ0FOkaA6stpV4YPEOQRCOKTazbMCIQkk9Cmk,25119
38
38
  kash/config/__init__.py,sha256=ytly9Typ1mWV4CXfV9G3CIPtPQ02u2rpZ304L3GlFro,148
39
39
  kash/config/capture_output.py,sha256=ud3uUVNuDicHj3mI_nBUBO-VmOrxtBdA3z-I3D1lSCU,2398
40
40
  kash/config/colors.py,sha256=6lqrB2RQYF2OLw-njfOqVHO9Bwiq7bW6K1ROCOAd1EM,9949
@@ -82,7 +82,7 @@ kash/embeddings/embeddings.py,sha256=v6RmrEHsx5PuE3fPrY15RK4fgW0K_VlNWDTjCVr11zY
82
82
  kash/embeddings/text_similarity.py,sha256=BOo9Vcs5oi2Zs5La56uTkPMHo65XSd4qz_yr6GTfUA4,1924
83
83
  kash/exec/__init__.py,sha256=rdSsKzTaXfSZmD5JvmUSSwmpfvl-moNv9PUgtE_WUpQ,1148
84
84
  kash/exec/action_decorators.py,sha256=VOSCnFiev2_DuFoSk0i_moejwM4wJ1j6QfsQd93uetI,16480
85
- kash/exec/action_exec.py,sha256=wndn9WsH9dGIzRjbiNCLfHHKZPlTzlFp-eogDvqkfbI,18500
85
+ kash/exec/action_exec.py,sha256=UHs-gKbu63d313MwfKsbVoRoTq7LbY8Vs0u_R4QZMh8,19025
86
86
  kash/exec/action_registry.py,sha256=numU9pH_W5RgIrYmfi0iYMYy_kLJl6vup8PMrhxAfdc,2627
87
87
  kash/exec/combiners.py,sha256=AJ6wgPUHsmwanObsUw64B83XzU26yuh5t4l7igLn82I,4291
88
88
  kash/exec/command_exec.py,sha256=zc-gWm7kyB5J5Kp8xhULQ9Jj9AL927KkDPXXk-Yr1Bw,1292
@@ -92,9 +92,9 @@ kash/exec/history.py,sha256=l2XwHGBR1UgTGSFPSBE9mltmxvjR_5qFFO6d-Z008nc,1208
92
92
  kash/exec/importing.py,sha256=xunmBapeUMNc6Zox7y6e_DZkidyWeouiFZpphajwSzc,1843
93
93
  kash/exec/llm_transforms.py,sha256=p_aLp70VoIgheW4v8uoweeuEVWj06AzQekvn_jM3B-g,4378
94
94
  kash/exec/precondition_checks.py,sha256=HymxL7qm4Yz8V76Um5pKdIRnQ2N-p9rpQQi1fI38bNA,2139
95
- kash/exec/precondition_registry.py,sha256=cmp0mUfLS42AbAByDhwGx8GWz9PuZNR7z5rPZW9WQE4,1244
96
- kash/exec/preconditions.py,sha256=kJXJQwqwsGBmzbrYy8s-soJeY8-gXx5ahbBPSqo7UvY,4965
97
- kash/exec/resolve_args.py,sha256=yGU6Jjzn5yyAN9pNZx8Qfc9oBrosFEdazIs5g9pjWTs,4410
95
+ kash/exec/precondition_registry.py,sha256=-vYWN2wduq-hau2aDShQ5tglTF-cHC1vaZqU-peir9A,1384
96
+ kash/exec/preconditions.py,sha256=6bJ76AVFo0TLoykrGBNB0rrpIDWD0umfb3F5sMcmoKo,5131
97
+ kash/exec/resolve_args.py,sha256=gu65epzVrwWHdHA-KwAwYssncJIB84oHOJeoXXrQ2mM,4428
98
98
  kash/exec/runtime_settings.py,sha256=aK6nGbZhKSIDVmV6AqV68hQkiaIGWnCiNzHtwwZ5V0w,3960
99
99
  kash/exec/shell_callable_action.py,sha256=x-Hs4EqpsZfKEcwhWkhc27HCIfoI91b-DrbG40BLxRY,4350
100
100
  kash/exec_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -103,7 +103,7 @@ kash/exec_model/commands_model.py,sha256=iM8QhzA0tAas5OwF5liUfHtm45XIH1LcvCviuh3
103
103
  kash/exec_model/script_model.py,sha256=1VG3LhkTmlKzHOYouZ92ZpOSKSCcsz3-tHNcFMQF788,5031
104
104
  kash/exec_model/shell_model.py,sha256=LUhQivbpXlerM-DUzNY7BtctNBbn08Wto8CSSxQDxRU,568
105
105
  kash/file_storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
- kash/file_storage/file_store.py,sha256=sqhNFZtWDgaJbR8ah-yCYuaVbLKzs7XpAcYRfU9rtss,29425
106
+ kash/file_storage/file_store.py,sha256=c9Vt40JwleHOVqk-2b7yayW80RRiH-AApD-HZ3gdebo,30021
107
107
  kash/file_storage/item_file_format.py,sha256=YAz7VqyfIoiSLQOoFdWsp-FI_2tTLXAPi8V8QXbo5ag,5475
108
108
  kash/file_storage/metadata_dirs.py,sha256=9AqO3S3SSY1dtvP2iLX--E4ui0VIzXttG8R040otfyg,3820
109
109
  kash/file_storage/persisted_yaml.py,sha256=4-4RkFqdlBUkTOwkdA4vRKUywEE9TaDo13OGaDUyU9M,1309
@@ -164,7 +164,7 @@ kash/model/compound_actions_model.py,sha256=HiDK5wwCu3WwZYHATZoLEguiqwR9V6V296wi
164
164
  kash/model/concept_model.py,sha256=we2qOcy9Mv1q7XPfkDLp_CyO_-8DwAUfUYlpgy_jrFs,1011
165
165
  kash/model/exec_model.py,sha256=IlfvtQyoFRRWhWju7vdXp9J-w_NGcGtL5DhDLy9gRd8,2250
166
166
  kash/model/graph_model.py,sha256=jnctrPiBZ0xwAR8D54JMAJPanA1yZdaxSFQoIpe8anA,2662
167
- kash/model/items_model.py,sha256=429FXlEsKxUFCqT_Z5t2zAFcfVEpjOGMdvz7q4hMEtw,34891
167
+ kash/model/items_model.py,sha256=RLbRTo36AZR5QLHotcYo4s6na8u40rcLXA0F6POUHyw,34913
168
168
  kash/model/language_list.py,sha256=I3RIbxTseVmPdhExQimimEv18Gmy2ImMbpXe0-_t1Qw,450
169
169
  kash/model/llm_actions_model.py,sha256=a29uXVNfS2CiqvM7HPdC6H9A23rSQQihAideuBLMH8g,2110
170
170
  kash/model/media_model.py,sha256=64Zic4cRjQpgf_-tOuZlZZe59mz_qu0s6OQSU0YlDUI,3357
@@ -217,7 +217,7 @@ kash/utils/file_utils/__init__.py,sha256=loL_iW0oOZs0mJ5GelBPptBcqzYKSWdsGcHrpRy
217
217
  kash/utils/file_utils/dir_info.py,sha256=HamMr58k_DanTLifj7A2JDxTGWXEZZx2pQuE6Hjcm8g,1856
218
218
  kash/utils/file_utils/file_ext.py,sha256=-H63vlrVI3pfE2Cn_9qF7-QLDaUIu_njc4TieNgAHSY,1860
219
219
  kash/utils/file_utils/file_formats.py,sha256=vnihRFLl85G1uzpqDc_uiGH9SIvbFTYVszz3srdSSz0,4949
220
- kash/utils/file_utils/file_formats_model.py,sha256=0rwWlkgMaZu5Ap7IFPt3poA1owdwFCfgGGtvu__15GY,15099
220
+ kash/utils/file_utils/file_formats_model.py,sha256=M1KTGJdwC91SiQkBbEkext-hjMcjYpSnoNGUIuWiJKo,15448
221
221
  kash/utils/file_utils/file_sort_filter.py,sha256=_k1chT3dJl5lSmKA2PW90KaoG4k4zftGdtwWoNEljP4,7136
222
222
  kash/utils/file_utils/file_walk.py,sha256=cpwVDPuaVm95_ZwFJiAdIuZAGhASI3gJ3ZUsCGP75b8,5527
223
223
  kash/utils/file_utils/filename_parsing.py,sha256=drHrH2B9W_5yAbXURNGJxNqj9GmTe8FayH6Gjw9e4-U,4194
@@ -231,7 +231,7 @@ kash/utils/rich_custom/ansi_cell_len.py,sha256=oQlNrqWB0f6pmigkbRRyeK6oWlGHMPbV_
231
231
  kash/utils/rich_custom/rich_char_transform.py,sha256=3M89tViKM0y31VHsDoHi5eHFWlv5ME7F4p35IdDxnrw,2616
232
232
  kash/utils/rich_custom/rich_indent.py,sha256=nz72yNpUuYjOsaPNVmxM81oEQm-GKEfQkNsuWmv16G0,2286
233
233
  kash/utils/rich_custom/rich_markdown_fork.py,sha256=M_JRaSAyHrSg-wuLv9C9P7SkehSim3lwkqQPuMIFkVw,26551
234
- kash/utils/text_handling/doc_normalization.py,sha256=Lz2wiSXCFGT15S9siNksiiND08uQIj3sgFCYYWkamT8,2786
234
+ kash/utils/text_handling/doc_normalization.py,sha256=C211eSof8PUDVCqQtShuC4AMJpTZeBK8GHlGATp3c9E,2976
235
235
  kash/utils/text_handling/escape_html_tags.py,sha256=7ZNQw3wfGzATVBBKmJMWmBTuznEPGzS6utjrH9HmmlQ,6361
236
236
  kash/utils/text_handling/markdown_render.py,sha256=Ea-QiBND0kp4Dc9rYr8Z3dB_CRpAxneGHBOlTDWsDo0,3751
237
237
  kash/utils/text_handling/markdown_utils.py,sha256=ndEd5ai80ZjSeMR104KLmAj0LOCPZln0ntd9tP5mf-E,9783
@@ -251,7 +251,7 @@ kash/web_gen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
251
251
  kash/web_gen/simple_webpage.py,sha256=c_kLXAsjP9wB9-ppF7MMJMw5VHXzVwkcHymfo5YOfS0,1402
252
252
  kash/web_gen/tabbed_webpage.py,sha256=Q_Htw2QO0O9H3A9OFrWw9GBD73cbwB6hOKF-W6mO6YE,4807
253
253
  kash/web_gen/template_render.py,sha256=aypo6UanouftV4RpxgNm6JdquelI52fV0IlihdA3yjE,1908
254
- kash/web_gen/templates/base_styles.css.jinja,sha256=sPYXVMtK1f-Ndf6zbHv71gdq_lkkOwjf8JNqDc_37go,9176
254
+ kash/web_gen/templates/base_styles.css.jinja,sha256=xrA7567wXHp9oMRqXhiMcEjH_IMeo6Ny1_pThYWpe4o,9202
255
255
  kash/web_gen/templates/base_webpage.html.jinja,sha256=Nvdd8pLSG2OdbrDQRvYcexYIZoMdr1G_7MdUVHNDoA8,7945
256
256
  kash/web_gen/templates/content_styles.css.jinja,sha256=3qcIwIt3DipCDJa9z6oIM_BMxmwoT7E_loTK0F3L9Vo,3629
257
257
  kash/web_gen/templates/explain_view.html.jinja,sha256=DNw5Iw5SrhIUFRGB4qNvfcKXsBHVbEJVURGdhvyC75Q,949
@@ -279,8 +279,8 @@ kash/xonsh_custom/xonsh_modern_tools.py,sha256=mj_b34LZXfE8MJe9EpDmp5JZ0tDM1biYN
279
279
  kash/xonsh_custom/xonsh_ranking_completer.py,sha256=ZRGiAfoEgqgnlq2-ReUVEaX5oOgW1DQ9WxIv2OJLuTo,5620
280
280
  kash/xontrib/fnm.py,sha256=V2tsOdmIDgbFbZSfMLpsvDIwwJJqiYnOkOySD1cXNXw,3700
281
281
  kash/xontrib/kash_extension.py,sha256=JRRJC3cZSMOl4sSWEdKAQ_dVRMubWaOltKr8G0dWt6Y,1876
282
- kash_shell-0.3.14.dist-info/METADATA,sha256=w_L4jxifwPdsDvYqMRJZSbhc3u9bV5mYORRcbXHDj9k,31258
283
- kash_shell-0.3.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
284
- kash_shell-0.3.14.dist-info/entry_points.txt,sha256=SQraWDAo8SqYpthLXThei0mf_hGGyhYBUO-Er_0HcwI,85
285
- kash_shell-0.3.14.dist-info/licenses/LICENSE,sha256=rCh2PsfYeiU6FK_0wb58kHGm_Fj5c43fdcHEexiVzIo,34562
286
- kash_shell-0.3.14.dist-info/RECORD,,
282
+ kash_shell-0.3.15.dist-info/METADATA,sha256=nxMDgU5r65l0fnmvMfJkeIXQeUMxXKdvjk6EFTpgyQY,31258
283
+ kash_shell-0.3.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
284
+ kash_shell-0.3.15.dist-info/entry_points.txt,sha256=SQraWDAo8SqYpthLXThei0mf_hGGyhYBUO-Er_0HcwI,85
285
+ kash_shell-0.3.15.dist-info/licenses/LICENSE,sha256=rCh2PsfYeiU6FK_0wb58kHGm_Fj5c43fdcHEexiVzIo,34562
286
+ kash_shell-0.3.15.dist-info/RECORD,,