kash-shell 0.3.21__tar.gz → 0.3.22__tar.gz

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.
Files changed (315) hide show
  1. {kash_shell-0.3.21 → kash_shell-0.3.22}/PKG-INFO +1 -1
  2. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/markdownify_html.py +11 -0
  3. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/tabbed_webpage_generate.py +2 -2
  4. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/help/assistant_commands.py +2 -4
  5. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/help/logo.py +12 -17
  6. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/help/welcome.py +5 -4
  7. kash_shell-0.3.22/src/kash/docs/markdown/warning.md +3 -0
  8. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/welcome.md +2 -1
  9. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/fetch_url_items.py +6 -4
  10. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/preconditions.py +7 -2
  11. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/items_model.py +14 -11
  12. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/output/shell_output.py +8 -4
  13. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/text_handling/markdown_utils.py +158 -1
  14. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/tabbed_webpage.py +2 -2
  15. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/load_into_xonsh.py +0 -3
  16. kash_shell-0.3.21/src/kash/docs/markdown/warning.md +0 -3
  17. {kash_shell-0.3.21 → kash_shell-0.3.22}/.copier-answers.yml +0 -0
  18. {kash_shell-0.3.21 → kash_shell-0.3.22}/.cursor/rules/general.mdc +0 -0
  19. {kash_shell-0.3.21 → kash_shell-0.3.22}/.cursor/rules/python.mdc +0 -0
  20. {kash_shell-0.3.21 → kash_shell-0.3.22}/.env.template +0 -0
  21. {kash_shell-0.3.21 → kash_shell-0.3.22}/.github/workflows/ci.yml +0 -0
  22. {kash_shell-0.3.21 → kash_shell-0.3.22}/.github/workflows/publish.yml +0 -0
  23. {kash_shell-0.3.21 → kash_shell-0.3.22}/.gitignore +0 -0
  24. {kash_shell-0.3.21 → kash_shell-0.3.22}/LICENSE +0 -0
  25. {kash_shell-0.3.21 → kash_shell-0.3.22}/Makefile +0 -0
  26. {kash_shell-0.3.21 → kash_shell-0.3.22}/README.md +0 -0
  27. {kash_shell-0.3.21 → kash_shell-0.3.22}/development.md +0 -0
  28. {kash_shell-0.3.21 → kash_shell-0.3.22}/devtools/generate_readme.xsh +0 -0
  29. {kash_shell-0.3.21 → kash_shell-0.3.22}/devtools/lint.py +0 -0
  30. {kash_shell-0.3.21 → kash_shell-0.3.22}/devtools/profile_main.py +0 -0
  31. {kash_shell-0.3.21 → kash_shell-0.3.22}/installation.md +0 -0
  32. {kash_shell-0.3.21 → kash_shell-0.3.22}/publishing.md +0 -0
  33. {kash_shell-0.3.21 → kash_shell-0.3.22}/pyproject.toml +0 -0
  34. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/__init__.py +0 -0
  35. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/__main__.py +0 -0
  36. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/__init__.py +0 -0
  37. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/assistant_chat.py +0 -0
  38. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/chat.py +0 -0
  39. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/format_markdown_template.py +0 -0
  40. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/minify_html.py +0 -0
  41. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/readability.py +0 -0
  42. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/render_as_html.py +0 -0
  43. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/show_webpage.py +0 -0
  44. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/strip_html.py +0 -0
  45. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/summarize_as_bullets.py +0 -0
  46. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/core/tabbed_webpage_config.py +0 -0
  47. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/meta/write_instructions.py +0 -0
  48. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/actions/meta/write_new_action.py +0 -0
  49. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/__init__.py +0 -0
  50. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/basic_file_commands.py +0 -0
  51. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/browser_commands.py +0 -0
  52. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/debug_commands.py +0 -0
  53. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/diff_commands.py +0 -0
  54. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/files_command.py +0 -0
  55. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/general_commands.py +0 -0
  56. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/logs_commands.py +0 -0
  57. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/model_commands.py +0 -0
  58. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/reformat_command.py +0 -0
  59. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/search_command.py +0 -0
  60. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/base/show_command.py +0 -0
  61. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/extras/parse_uv_lock.py +0 -0
  62. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/extras/utils_commands.py +0 -0
  63. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/help/doc_commands.py +0 -0
  64. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/help/help_commands.py +0 -0
  65. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/workspace/selection_commands.py +0 -0
  66. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/commands/workspace/workspace_commands.py +0 -0
  67. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/__init__.py +0 -0
  68. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/capture_output.py +0 -0
  69. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/colors.py +0 -0
  70. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/env_settings.py +0 -0
  71. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/init.py +0 -0
  72. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/lazy_imports.py +0 -0
  73. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/logger.py +0 -0
  74. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/logger_basic.py +0 -0
  75. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/logo.txt +0 -0
  76. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/server_config.py +0 -0
  77. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/settings.py +0 -0
  78. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/setup.py +0 -0
  79. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/suppress_warnings.py +0 -0
  80. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/config/text_styles.py +0 -0
  81. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/__init__.py +0 -0
  82. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/all_docs.py +0 -0
  83. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/load_actions_info.py +0 -0
  84. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/load_api_docs.py +0 -0
  85. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/load_help_topics.py +0 -0
  86. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/load_source_code.py +0 -0
  87. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/api_docs_template.md +0 -0
  88. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/assistant_instructions_template.md +0 -0
  89. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/readme_template.md +0 -0
  90. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/a1_what_is_kash.md +0 -0
  91. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/a2_installation.md +0 -0
  92. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/a3_getting_started.md +0 -0
  93. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/a4_elements.md +0 -0
  94. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/a5_tips_for_use_with_other_tools.md +0 -0
  95. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/b0_philosophy_of_kash.md +0 -0
  96. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/b1_kash_overview.md +0 -0
  97. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/b2_workspace_and_file_formats.md +0 -0
  98. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/b3_modern_shell_tool_recommendations.md +0 -0
  99. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs/markdown/topics/b4_faq.md +0 -0
  100. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs_base/docs_base.py +0 -0
  101. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs_base/load_custom_command_info.py +0 -0
  102. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs_base/load_faqs.py +0 -0
  103. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs_base/load_recipe_snippets.py +0 -0
  104. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs_base/recipes/general_system_commands.sh +0 -0
  105. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs_base/recipes/python_dev_commands.sh +0 -0
  106. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/docs_base/recipes/tldr_standard_commands.sh +0 -0
  107. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/embeddings/cosine.py +0 -0
  108. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/embeddings/embeddings.py +0 -0
  109. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/embeddings/text_similarity.py +0 -0
  110. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/__init__.py +0 -0
  111. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/action_decorators.py +0 -0
  112. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/action_exec.py +0 -0
  113. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/action_registry.py +0 -0
  114. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/combiners.py +0 -0
  115. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/command_exec.py +0 -0
  116. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/command_registry.py +0 -0
  117. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/history.py +0 -0
  118. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/importing.py +0 -0
  119. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/llm_transforms.py +0 -0
  120. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/precondition_checks.py +0 -0
  121. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/precondition_registry.py +0 -0
  122. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/resolve_args.py +0 -0
  123. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/runtime_settings.py +0 -0
  124. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec/shell_callable_action.py +0 -0
  125. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec_model/__init__.py +0 -0
  126. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec_model/args_model.py +0 -0
  127. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec_model/commands_model.py +0 -0
  128. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec_model/script_model.py +0 -0
  129. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/exec_model/shell_model.py +0 -0
  130. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/file_storage/__init__.py +0 -0
  131. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/file_storage/file_store.py +0 -0
  132. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/file_storage/item_file_format.py +0 -0
  133. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/file_storage/metadata_dirs.py +0 -0
  134. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/file_storage/persisted_yaml.py +0 -0
  135. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/file_storage/store_cache_warmer.py +0 -0
  136. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/file_storage/store_filenames.py +0 -0
  137. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/__init__.py +0 -0
  138. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/assistant.py +0 -0
  139. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/assistant_instructions.py +0 -0
  140. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/assistant_output.py +0 -0
  141. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/function_param_info.py +0 -0
  142. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/help_embeddings.py +0 -0
  143. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/help_lookups.py +0 -0
  144. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/help_pages.py +0 -0
  145. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/help_printing.py +0 -0
  146. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/help_types.py +0 -0
  147. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/recommended_commands.py +0 -0
  148. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/help/tldr_help.py +0 -0
  149. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/__init__.py +0 -0
  150. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/clean_headings.py +0 -0
  151. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/custom_sliding_transforms.py +0 -0
  152. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/fuzzy_parsing.py +0 -0
  153. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/init_litellm.py +0 -0
  154. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/llm_api_keys.py +0 -0
  155. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/llm_completion.py +0 -0
  156. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/llm_features.py +0 -0
  157. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/llm_messages.py +0 -0
  158. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/llm_names.py +0 -0
  159. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/llm_utils/llms.py +0 -0
  160. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/local_server/__init__.py +0 -0
  161. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/local_server/local_server.py +0 -0
  162. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/local_server/local_server_commands.py +0 -0
  163. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/local_server/local_server_routes.py +0 -0
  164. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/local_server/local_url_formatters.py +0 -0
  165. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/local_server/port_tools.py +0 -0
  166. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/local_server/rich_html_template.py +0 -0
  167. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/mcp/__init__.py +0 -0
  168. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/mcp/mcp_cli.py +0 -0
  169. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/mcp/mcp_main.py +0 -0
  170. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/mcp/mcp_server_commands.py +0 -0
  171. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/mcp/mcp_server_routes.py +0 -0
  172. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/mcp/mcp_server_sse.py +0 -0
  173. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/mcp/mcp_server_stdio.py +0 -0
  174. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/__init__.py +0 -0
  175. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/audio_processing.py +0 -0
  176. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/media_cache.py +0 -0
  177. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/media_services.py +0 -0
  178. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/media_tools.py +0 -0
  179. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/services/local_file_media.py +0 -0
  180. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/timestamp_citations.py +0 -0
  181. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/transcription_deepgram.py +0 -0
  182. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/transcription_format.py +0 -0
  183. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/media_base/transcription_whisper.py +0 -0
  184. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/__init__.py +0 -0
  185. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/actions_model.py +0 -0
  186. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/assistant_response_model.py +0 -0
  187. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/compound_actions_model.py +0 -0
  188. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/concept_model.py +0 -0
  189. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/exec_model.py +0 -0
  190. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/graph_model.py +0 -0
  191. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/language_list.py +0 -0
  192. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/llm_actions_model.py +0 -0
  193. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/media_model.py +0 -0
  194. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/operations_model.py +0 -0
  195. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/params_model.py +0 -0
  196. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/paths_model.py +0 -0
  197. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/model/preconditions_model.py +0 -0
  198. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/__init__.py +0 -0
  199. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/completions/completion_scoring.py +0 -0
  200. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/completions/completion_types.py +0 -0
  201. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/completions/shell_completions.py +0 -0
  202. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/file_icons/color_for_format.py +0 -0
  203. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/file_icons/nerd_icons.py +0 -0
  204. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/input/__init__.py +0 -0
  205. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/input/input_prompts.py +0 -0
  206. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/input/inquirer_settings.py +0 -0
  207. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/input/param_inputs.py +0 -0
  208. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/input/shell_confirm.py +0 -0
  209. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/output/__init__.py +0 -0
  210. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/output/kerm_code_utils.py +0 -0
  211. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/output/kerm_codes.py +0 -0
  212. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/output/kmarkdown.py +0 -0
  213. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/output/shell_formatting.py +0 -0
  214. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/shell_main.py +0 -0
  215. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/ui/__init__.py +0 -0
  216. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/ui/shell_results.py +0 -0
  217. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/ui/shell_syntax.py +0 -0
  218. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/utils/exception_printing.py +0 -0
  219. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/utils/native_utils.py +0 -0
  220. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/utils/shell_function_wrapper.py +0 -0
  221. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/shell/version.py +0 -0
  222. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/__init__.py +0 -0
  223. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/api_utils/api_retries.py +0 -0
  224. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/api_utils/cache_requests_limited.py +0 -0
  225. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/api_utils/gather_limited.py +0 -0
  226. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/api_utils/progress_protocol.py +0 -0
  227. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/__init__.py +0 -0
  228. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/format_utils.py +0 -0
  229. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/function_inspect.py +0 -0
  230. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/import_utils.py +0 -0
  231. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/lazyobject.py +0 -0
  232. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/obj_replace.py +0 -0
  233. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/parse_docstring.py +0 -0
  234. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/parse_key_vals.py +0 -0
  235. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/parse_shell_args.py +0 -0
  236. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/stack_traces.py +0 -0
  237. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/task_stack.py +0 -0
  238. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/testing.py +0 -0
  239. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/type_utils.py +0 -0
  240. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/uniquifier.py +0 -0
  241. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/url.py +0 -0
  242. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/common/url_slice.py +0 -0
  243. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/errors.py +0 -0
  244. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_formats/chat_format.py +0 -0
  245. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/__init__.py +0 -0
  246. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/dir_info.py +0 -0
  247. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/file_ext.py +0 -0
  248. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/file_formats.py +0 -0
  249. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/file_formats_model.py +0 -0
  250. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/file_sort_filter.py +0 -0
  251. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/file_walk.py +0 -0
  252. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/filename_parsing.py +0 -0
  253. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/ignore_files.py +0 -0
  254. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/mtime_cache.py +0 -0
  255. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/file_utils/path_utils.py +0 -0
  256. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/lang_utils/__init__.py +0 -0
  257. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/lang_utils/capitalization.py +0 -0
  258. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/rich_custom/__init__.py +0 -0
  259. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/rich_custom/ansi_cell_len.py +0 -0
  260. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/rich_custom/multitask_status.py +0 -0
  261. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/rich_custom/rich_char_transform.py +0 -0
  262. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/rich_custom/rich_indent.py +0 -0
  263. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/rich_custom/rich_markdown_fork.py +0 -0
  264. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/text_handling/doc_normalization.py +0 -0
  265. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/text_handling/escape_html_tags.py +0 -0
  266. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/text_handling/markdown_render.py +0 -0
  267. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/text_handling/markdownify_utils.py +0 -0
  268. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/utils/text_handling/unified_diffs.py +0 -0
  269. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/canon_url.py +0 -0
  270. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/dir_store.py +0 -0
  271. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/file_cache_utils.py +0 -0
  272. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/file_processing.py +0 -0
  273. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/local_file_cache.py +0 -0
  274. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/web_extract.py +0 -0
  275. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/web_extract_justext.py +0 -0
  276. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/web_extract_readabilipy.py +0 -0
  277. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/web_fetch.py +0 -0
  278. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_content/web_page_model.py +0 -0
  279. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/__init__.py +0 -0
  280. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/simple_webpage.py +0 -0
  281. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/template_render.py +0 -0
  282. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/base_styles.css.jinja +0 -0
  283. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/base_webpage.html.jinja +0 -0
  284. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/components/toc_scripts.js.jinja +0 -0
  285. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/components/toc_styles.css.jinja +0 -0
  286. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/components/tooltip_scripts.js.jinja +0 -0
  287. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/components/tooltip_styles.css.jinja +0 -0
  288. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/content_styles.css.jinja +0 -0
  289. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/explain_view.html.jinja +0 -0
  290. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/item_view.html.jinja +0 -0
  291. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/simple_webpage.html.jinja +0 -0
  292. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/web_gen/templates/tabbed_webpage.html.jinja +0 -0
  293. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/workspaces/__init__.py +0 -0
  294. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/workspaces/param_state.py +0 -0
  295. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/workspaces/selections.py +0 -0
  296. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/workspaces/source_items.py +0 -0
  297. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/workspaces/workspace_dirs.py +0 -0
  298. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/workspaces/workspace_output.py +0 -0
  299. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/workspaces/workspace_registry.py +0 -0
  300. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/workspaces/workspaces.py +0 -0
  301. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/command_nl_utils.py +0 -0
  302. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/custom_shell.py +0 -0
  303. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/customize_prompt.py +0 -0
  304. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/shell_load_commands.py +0 -0
  305. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/shell_which.py +0 -0
  306. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/xonsh_completers.py +0 -0
  307. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/xonsh_env.py +0 -0
  308. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/xonsh_keybindings.py +0 -0
  309. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/xonsh_modern_tools.py +0 -0
  310. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xonsh_custom/xonsh_ranking_completer.py +0 -0
  311. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xontrib/fnm.py +0 -0
  312. {kash_shell-0.3.21 → kash_shell-0.3.22}/src/kash/xontrib/kash_extension.py +0 -0
  313. {kash_shell-0.3.21 → kash_shell-0.3.22}/tests/kash/utils/rich_custom/test_multitask_status.py +0 -0
  314. {kash_shell-0.3.21 → kash_shell-0.3.22}/tests/test_shell.py +0 -0
  315. {kash_shell-0.3.21 → kash_shell-0.3.22}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.21
3
+ Version: 0.3.22
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>
@@ -1,9 +1,12 @@
1
+ from prettyfmt import abbrev_on_words
2
+
1
3
  from kash.config.logger import get_logger
2
4
  from kash.exec import kash_action
3
5
  from kash.exec.preconditions import has_html_body, is_url_resource
4
6
  from kash.exec.runtime_settings import current_runtime_settings
5
7
  from kash.model import Format, Item
6
8
  from kash.model.items_model import ItemType
9
+ from kash.utils.text_handling.markdown_utils import first_heading
7
10
  from kash.utils.text_handling.markdownify_utils import markdownify_custom
8
11
  from kash.web_content.file_cache_utils import get_url_html
9
12
  from kash.web_content.web_extract_readabilipy import extract_text_readabilipy
@@ -25,6 +28,14 @@ def markdownify_html(item: Item) -> Item:
25
28
  assert page_data.clean_html
26
29
  markdown_content = markdownify_custom(page_data.clean_html)
27
30
 
31
+ # Sometimes readability doesn't include the title, in which case we add it.
32
+ first_h1 = first_heading(markdown_content, allowed_tags=("h1",))
33
+ title = page_data.title and abbrev_on_words(page_data.title.strip(), 80)
34
+ if not first_h1 and title:
35
+ log.message(f"No h1 found, inserting h1: {title}")
36
+ # Insert a h1 at the top of the document
37
+ markdown_content = f"# {title}\n\n{markdown_content}"
38
+
28
39
  output_item = item.derived_copy(
29
40
  type=ItemType.doc, format=Format.markdown, body=markdown_content
30
41
  )
@@ -1,6 +1,6 @@
1
1
  from kash.config.logger import get_logger
2
2
  from kash.exec import kash_action
3
- from kash.exec.preconditions import is_config
3
+ from kash.exec.preconditions import is_data
4
4
  from kash.model import ONE_ARG, ActionInput, ActionResult, FileExt, Format, Item, ItemType, Param
5
5
  from kash.web_gen import tabbed_webpage
6
6
 
@@ -9,7 +9,7 @@ log = get_logger(__name__)
9
9
 
10
10
  @kash_action(
11
11
  expected_args=ONE_ARG,
12
- precondition=is_config,
12
+ precondition=is_data,
13
13
  params=(Param("add_title", "Add a title to the page body.", type=bool),),
14
14
  )
15
15
  def tabbed_webpage_generate(input: ActionInput, add_title: bool = False) -> ActionResult:
@@ -1,8 +1,6 @@
1
- from rich import get_console
2
-
3
1
  from kash.commands.base.basic_file_commands import trash
4
2
  from kash.commands.workspace.selection_commands import select
5
- from kash.config.logger import get_logger
3
+ from kash.config.logger import get_console, get_logger
6
4
  from kash.config.text_styles import PROMPT_ASSIST, SPINNER
7
5
  from kash.docs.all_docs import DocSelection
8
6
  from kash.exec import kash_command
@@ -45,7 +43,7 @@ def assist(
45
43
  help()
46
44
  return
47
45
 
48
- with get_console().status("Thinking…", spinner=SPINNER):
46
+ with get_console().status("Thinking…", spinner=SPINNER): # noqa: F821
49
47
  shell_context_assistance(input, model=model, assistance_type=type)
50
48
 
51
49
 
@@ -2,7 +2,8 @@ import re
2
2
  from pathlib import Path
3
3
 
4
4
  from rich.box import SQUARE
5
- from rich.console import Group
5
+ from rich.console import Group, RenderableType
6
+ from rich.padding import Padding
6
7
  from rich.panel import Panel
7
8
  from rich.text import Text
8
9
 
@@ -62,7 +63,13 @@ def color_logo() -> Group:
62
63
  )
63
64
 
64
65
 
65
- def branded_box(content: Group | None, version: str | None = None) -> Panel:
66
+ def simple_box(content: RenderableType) -> Panel:
67
+ return Panel(
68
+ content, border_style=COLOR_HINT, padding=(0, 1), width=CONSOLE_WRAP_WIDTH, box=SQUARE
69
+ )
70
+
71
+
72
+ def logo_box(content: Group | None = None) -> Padding:
66
73
  panel_width = CONSOLE_WRAP_WIDTH
67
74
 
68
75
  logo_lines = LOGO_LARGE.split("\n")
@@ -70,29 +77,17 @@ def branded_box(content: Group | None, version: str | None = None) -> Panel:
70
77
  tagline_offset = (panel_width - 4 - len(TAGLINE_STYLED)) // 2
71
78
 
72
79
  colored_lines = [logo_colorize_line(line, " ", rest_offset) for line in logo_lines]
73
- header = None
74
- if version:
75
- footer = Text(version, style=COLOR_HINT, justify="right")
76
- else:
77
- footer = None
78
80
 
79
81
  body = ["", content] if content else []
80
82
 
81
- return Panel(
83
+ return Padding(
82
84
  Group(
83
85
  Text.assemble(" " * tagline_offset, LOGO_SPACER),
84
86
  *colored_lines,
85
87
  Text.assemble(" " * tagline_offset, TAGLINE_STYLED),
86
88
  *body,
87
89
  ),
88
- title=header,
89
- title_align="center",
90
- subtitle=footer,
91
- subtitle_align="right",
92
- border_style=COLOR_HINT,
93
- padding=(0, 1),
94
- width=panel_width,
95
- box=SQUARE,
90
+ pad=(1, 1),
96
91
  )
97
92
 
98
93
 
@@ -101,7 +96,7 @@ def kash_logo(box: bool = False, svg_out: str | None = None, html_out: str | Non
101
96
  """
102
97
  Show the kash logo.
103
98
  """
104
- logo = branded_box(None) if box else color_logo()
99
+ logo = logo_box(None) if box else color_logo()
105
100
 
106
101
  cprint(logo)
107
102
 
@@ -2,7 +2,7 @@ from rich.box import SQUARE
2
2
  from rich.console import Group
3
3
  from rich.panel import Panel
4
4
 
5
- from kash.commands.help.logo import branded_box
5
+ from kash.commands.help.logo import logo_box, simple_box
6
6
  from kash.config.text_styles import (
7
7
  COLOR_HINT,
8
8
  )
@@ -20,14 +20,15 @@ def welcome() -> None:
20
20
  """
21
21
 
22
22
  help_topics = all_docs.help_topics
23
- version = get_full_version_name()
23
+
24
24
  # Create header with logo and right-justified version
25
25
 
26
26
  PrintHooks.before_welcome()
27
+ cprint(logo_box())
27
28
  cprint(
28
- branded_box(
29
+ simple_box(
29
30
  Group(Markdown(help_topics.welcome)),
30
- version,
31
31
  )
32
32
  )
33
33
  cprint(Panel(Markdown(help_topics.warning), box=SQUARE, border_style=COLOR_HINT))
34
+ cprint("%s", get_full_version_name())
@@ -0,0 +1,3 @@
1
+ **Important:** This is a shell.
2
+ Commands can be destructive.
3
+ Review commands carefully!
@@ -1,5 +1,6 @@
1
- **Welcome to kash!** Use `help` for the manual and full list of available commands.
1
+ **Welcome to Kash!**
2
2
 
3
+ Use `help` for the manual and full list of available commands.
3
4
  Press **tab** for contextual autocomplete of commands, questions, actions, and files.
4
5
  You may simply ask a question and the kash assistant will help you.
5
6
  Press **space** (or type **?**), then write your question or request.
@@ -48,9 +48,10 @@ def fetch_url_item_content(item: Item, *, save_content: bool = True, refetch: bo
48
48
  from kash.workspaces import current_ws
49
49
 
50
50
  ws = current_ws()
51
- if not refetch and item.title and item.description:
51
+ if not refetch and item.title and item.description and item.body:
52
52
  log.message(
53
- "Already have title and description, will not fetch metadata: %s", item.fmt_loc()
53
+ "Already have title, description, and body, will not fetch: %s",
54
+ item.fmt_loc(),
54
55
  )
55
56
  return item
56
57
 
@@ -100,10 +101,11 @@ def fetch_url_item_content(item: Item, *, save_content: bool = True, refetch: bo
100
101
  # Now save the updated URL item and also the content item if we have one.
101
102
  ws.save(url_item)
102
103
  assert url_item.store_path
103
- log.debug("Saved URL item: %s", url_item.fmt_loc())
104
104
  if content_item:
105
105
  ws.save(content_item)
106
106
  assert content_item.store_path
107
- log.debug("Saved content item: %s", content_item.fmt_loc())
107
+ log.info("Saved content item: %s", content_item.fmt_loc())
108
+ else:
109
+ log.info("Saved URL item: %s", url_item.fmt_loc())
108
110
 
109
111
  return content_item or url_item
@@ -48,8 +48,13 @@ def is_concept(item: Item) -> bool:
48
48
 
49
49
 
50
50
  @kash_precondition
51
- def is_config(item: Item) -> bool:
52
- return item.type == ItemType.config
51
+ def is_data(item: Item) -> bool:
52
+ return item.type == ItemType.data
53
+
54
+
55
+ @kash_precondition
56
+ def is_table(item: Item) -> bool:
57
+ return item.type == ItemType.table
53
58
 
54
59
 
55
60
  @kash_precondition
@@ -55,7 +55,8 @@ class ItemType(Enum):
55
55
  concept = "concept"
56
56
  resource = "resource"
57
57
  asset = "asset"
58
- config = "config"
58
+ data = "data"
59
+ table = "table"
59
60
  export = "export"
60
61
  chat = "chat"
61
62
  extension = "extension"
@@ -86,7 +87,9 @@ class ItemType(Enum):
86
87
  Format.diff: ItemType.doc,
87
88
  Format.python: ItemType.extension,
88
89
  Format.json: ItemType.doc,
89
- Format.csv: ItemType.doc,
90
+ Format.csv: ItemType.table,
91
+ Format.xlsx: ItemType.table,
92
+ Format.npz: ItemType.table,
90
93
  Format.log: ItemType.log,
91
94
  Format.pdf: ItemType.resource,
92
95
  Format.jpeg: ItemType.asset,
@@ -646,7 +649,7 @@ class Item:
646
649
  body_text = abbrev_str(self.body_text(), max_len)
647
650
 
648
651
  # Just for aesthetics, especially for titles of chat files.
649
- if self.type in [ItemType.chat, ItemType.config] or self.format == Format.yaml:
652
+ if self.type in [ItemType.chat, ItemType.data] or self.format == Format.yaml:
650
653
  try:
651
654
  yaml_obj = list(new_yaml().load_all(self.body_text()))
652
655
  if len(yaml_obj) > 0:
@@ -663,16 +666,16 @@ class Item:
663
666
  """
664
667
  return bool(self.body and self.body.strip())
665
668
 
666
- def read_as_config(self) -> Any:
669
+ def read_as_data(self) -> Any:
667
670
  """
668
- If it is a config Item, return the parsed YAML.
671
+ If it is a data Item, return the parsed YAML.
669
672
  """
670
- if not self.type == ItemType.config:
671
- raise FileFormatError(f"Item is not a config: {self}")
673
+ if not self.type == ItemType.data:
674
+ raise FileFormatError(f"Item is not a data item: {self}")
672
675
  if not self.body:
673
- raise FileFormatError(f"Config item has no body: {self}")
676
+ raise FileFormatError(f"Data item has no body: {self}")
674
677
  if self.format != Format.yaml:
675
- raise FileFormatError(f"Config item is not YAML: {self.format}: {self}")
678
+ raise FileFormatError(f"Data item is not YAML: {self.format}: {self}")
676
679
  return from_yaml_string(self.body)
677
680
 
678
681
  def get_filename(self) -> str | None:
@@ -709,8 +712,8 @@ class Item:
709
712
  elif self.type == ItemType.script:
710
713
  # Same for kash/xonsh scripts.
711
714
  return f"{self.type.value}.{FileExt.xsh.value}"
712
- elif self.type == ItemType.export:
713
- # For exports, skip the item type to keep it maximally compatible for external tools.
715
+ elif self.type in [ItemType.export, ItemType.data, ItemType.table]:
716
+ # For exports, data, and tables, skip the item type to keep it maximally compatible for external tools.
714
717
  return f"{self.get_file_ext().value}"
715
718
  else:
716
719
  return f"{self.type.value}.{self.get_file_ext().value}"
@@ -4,7 +4,7 @@ Output to the shell UI. These are for user interaction, not logging.
4
4
 
5
5
  import contextvars
6
6
  from collections.abc import Callable
7
- from contextlib import contextmanager
7
+ from contextlib import contextmanager, nullcontext
8
8
  from enum import Enum, auto
9
9
 
10
10
  import rich
@@ -82,12 +82,16 @@ def console_pager(use_pager: bool = True):
82
82
 
83
83
 
84
84
  def multitask_status(
85
- settings: StatusSettings | None = None, *, auto_summary: bool = True
86
- ) -> MultiTaskStatus:
85
+ settings: StatusSettings | None = None, *, auto_summary: bool = True, enabled: bool = True
86
+ ) -> MultiTaskStatus | nullcontext:
87
87
  """
88
88
  Create a `MultiTaskStatus` context manager for displaying multiple task progress
89
- using the global shell console.
89
+ using the global shell console. If disabled, returns a null context, so it's convenient
90
+ to disable status display.
90
91
  """
92
+ if not enabled:
93
+ return nullcontext()
94
+
91
95
  return MultiTaskStatus(
92
96
  console=get_console(),
93
97
  settings=settings,
@@ -6,7 +6,7 @@ from typing import Any, TypeAlias
6
6
  import marko
7
7
  import regex
8
8
  from marko.block import Heading, ListItem
9
- from marko.inline import Link
9
+ from marko.inline import AutoLink, Link
10
10
 
11
11
  from kash.utils.common.url import Url
12
12
 
@@ -64,6 +64,9 @@ def _tree_links(element, include_internal=False):
64
64
  case Link():
65
65
  if include_internal or not element.dest.startswith("#"):
66
66
  links.append(element.dest)
67
+ case AutoLink():
68
+ if include_internal or not element.dest.startswith("#"):
69
+ links.append(element.dest)
67
70
  case _:
68
71
  if hasattr(element, "children"):
69
72
  for child in element.children:
@@ -710,3 +713,157 @@ def test_markdown_utils_exceptions() -> None:
710
713
  result_with_internal = extract_links(content, include_internal=True)
711
714
  assert "https://example.com" in result_with_internal
712
715
  assert "#section" in result_with_internal
716
+
717
+
718
+ def test_extract_links_comprehensive() -> None:
719
+ """Test extract_links with various link formats including bare links and footnotes."""
720
+
721
+ # Test regular markdown links
722
+ regular_links = "Check out [this link](https://example.com) and [another](https://test.com)"
723
+ result = extract_links(regular_links)
724
+ assert "https://example.com" in result
725
+ assert "https://test.com" in result
726
+ assert len(result) == 2
727
+
728
+ # Test bare/autolinks in angle brackets
729
+ bare_links = "Visit <https://google.com> and also <https://github.com>"
730
+ result_bare = extract_links(bare_links)
731
+ assert "https://google.com" in result_bare
732
+ assert "https://github.com" in result_bare
733
+ assert len(result_bare) == 2
734
+
735
+ # Test autolinks without brackets (expected to not work with standard markdown)
736
+ auto_links = "Visit https://stackoverflow.com or http://reddit.com"
737
+ result_auto = extract_links(auto_links)
738
+ assert (
739
+ result_auto == []
740
+ ) # Plain URLs without brackets aren't parsed as links in standard markdown
741
+
742
+ # Test GFM footnotes (the original issue)
743
+ footnote_content = """
744
+ [^109]: What Is The Future Of Ketamine Therapy For Mental Health Treatment?
745
+ - The Ko-Op, accessed June 28, 2025,
746
+ <https://psychedelictherapists.co/blog/the-future-of-ketamine-assisted-psychotherapy/>
747
+ """
748
+ result_footnote = extract_links(footnote_content)
749
+ assert (
750
+ "https://psychedelictherapists.co/blog/the-future-of-ketamine-assisted-psychotherapy/"
751
+ in result_footnote
752
+ )
753
+ assert len(result_footnote) == 1
754
+
755
+ # Test mixed content with all types (excluding reference-style which has parsing conflicts with footnotes)
756
+ mixed_content = """
757
+ # Header
758
+
759
+ Regular link: [Example](https://example.com)
760
+ Bare link: <https://bare-link.com>
761
+ Auto link: https://auto-link.com
762
+
763
+ [^1]: Footnote with [regular link](https://footnote-regular.com)
764
+ [^2]: Footnote with bare link <https://footnote-bare.com>
765
+ """
766
+ result_mixed = extract_links(mixed_content)
767
+ expected_links = [
768
+ "https://example.com", # Regular link
769
+ "https://bare-link.com", # Bare link
770
+ "https://footnote-regular.com", # Link in footnote
771
+ "https://footnote-bare.com", # Bare link in footnote
772
+ ]
773
+ for link in expected_links:
774
+ assert link in result_mixed, f"Missing expected link: {link}"
775
+ # Should not include plain auto link (https://auto-link.com) as it's not in angle brackets
776
+ assert "https://auto-link.com" not in result_mixed
777
+ assert len(result_mixed) == len(expected_links)
778
+
779
+
780
+ def test_extract_bare_links() -> None:
781
+ """Test extraction of bare links in angle brackets."""
782
+ content = "Visit <https://example.com> and <https://github.com/user/repo> for more info"
783
+ result = extract_links(content)
784
+ assert "https://example.com" in result
785
+ assert "https://github.com/user/repo" in result
786
+ assert len(result) == 2
787
+
788
+
789
+ def test_extract_footnote_links() -> None:
790
+ """Test extraction of links within footnotes."""
791
+ content = dedent("""
792
+ Main text with reference[^1].
793
+
794
+ [^1]: This footnote has a [regular link](https://example.com) and <https://bare-link.com>
795
+ """)
796
+ result = extract_links(content)
797
+ assert "https://example.com" in result
798
+ assert "https://bare-link.com" in result
799
+ assert len(result) == 2
800
+
801
+
802
+ def test_extract_reference_style_links() -> None:
803
+ """Test extraction of reference-style links."""
804
+ content = dedent("""
805
+ Check out [this article][ref1] and [this other one][ref2].
806
+
807
+ [ref1]: https://example.com/article1
808
+ [ref2]: https://example.com/article2
809
+ """)
810
+ result = extract_links(content)
811
+ assert "https://example.com/article1" in result
812
+ assert "https://example.com/article2" in result
813
+ assert len(result) == 2
814
+
815
+
816
+ def test_extract_links_with_internal_fragments() -> None:
817
+ """Test that internal fragment links are excluded by default but included when requested."""
818
+ content = dedent("""
819
+ See [this section](#introduction) and [external link](https://example.com).
820
+ Also check [another section](#conclusion) here.
821
+ """)
822
+
823
+ # Default behavior: exclude internal links
824
+ result = extract_links(content)
825
+ assert "https://example.com" in result
826
+ assert "#introduction" not in result
827
+ assert "#conclusion" not in result
828
+ assert len(result) == 1
829
+
830
+ # Include internal links
831
+ result_with_internal = extract_links(content, include_internal=True)
832
+ assert "https://example.com" in result_with_internal
833
+ assert "#introduction" in result_with_internal
834
+ assert "#conclusion" in result_with_internal
835
+ assert len(result_with_internal) == 3
836
+
837
+
838
+ def test_extract_links_mixed_real_world() -> None:
839
+ """Test with a realistic mixed document containing various link types."""
840
+ content = dedent("""
841
+ # Research Article
842
+
843
+ This study examines ketamine therapy[^109] and references multiple sources.
844
+
845
+ ## Methods
846
+
847
+ We reviewed literature from [PubMed](https://pubmed.ncbi.nlm.nih.gov)
848
+ and other databases <https://scholar.google.com>.
849
+
850
+ For protocol details, see [our methodology][methodology].
851
+
852
+ [methodology]: https://research.example.com/protocol
853
+
854
+ [^109]: What Is The Future Of Ketamine Therapy For Mental Health Treatment?
855
+ - The Ko-Op, accessed June 28, 2025,
856
+ <https://psychedelictherapists.co/blog/the-future-of-ketamine-assisted-psychotherapy/>
857
+ """)
858
+
859
+ result = extract_links(content)
860
+ expected_links = [
861
+ "https://pubmed.ncbi.nlm.nih.gov",
862
+ "https://scholar.google.com",
863
+ "https://research.example.com/protocol",
864
+ "https://psychedelictherapists.co/blog/the-future-of-ketamine-assisted-psychotherapy/",
865
+ ]
866
+
867
+ for link in expected_links:
868
+ assert link in result, f"Missing expected link: {link}"
869
+ assert len(result) == len(expected_links)
@@ -82,7 +82,7 @@ def tabbed_webpage_config(
82
82
 
83
83
  config_item = Item(
84
84
  title=f"{title} (config)",
85
- type=ItemType.config,
85
+ type=ItemType.data,
86
86
  format=Format.yaml,
87
87
  body=to_yaml_string(asdict(config)),
88
88
  )
@@ -108,7 +108,7 @@ def tabbed_webpage_generate(
108
108
  """
109
109
  Generate a web page using the supplied config.
110
110
  """
111
- config = config_item.read_as_config()
111
+ config = config_item.read_as_data()
112
112
  tabbed_webpage = as_dataclass(config, TabbedWebpage) # Checks the format.
113
113
 
114
114
  _load_tab_content(tabbed_webpage)
@@ -15,7 +15,6 @@ from kash.config.settings import RECOMMENDED_PKGS, check_kerm_code_support
15
15
  from kash.config.text_styles import LOGO_NAME, STYLE_HINT
16
16
  from kash.mcp.mcp_server_commands import start_mcp_server
17
17
  from kash.shell.output.shell_output import PrintHooks, cprint
18
- from kash.shell.version import get_version_tag
19
18
  from kash.workspaces import current_ws
20
19
  from kash.xonsh_custom.customize_prompt import get_prompt_info, kash_xonsh_prompt
21
20
  from kash.xonsh_custom.shell_load_commands import (
@@ -109,5 +108,3 @@ def load_into_xonsh():
109
108
 
110
109
  else:
111
110
  reload_shell_commands_and_actions()
112
-
113
- log.info("kash %s loaded", get_version_tag())
@@ -1,3 +0,0 @@
1
- **Important:** *Kash will not execute commands without confirmation.
2
- But this is a shell so commands can be destructive or dangerous.
3
- Review commands carefully!*
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes