kash-shell 0.3.26__tar.gz → 0.3.27__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 (324) hide show
  1. {kash_shell-0.3.26 → kash_shell-0.3.27}/PKG-INFO +2 -2
  2. {kash_shell-0.3.26 → kash_shell-0.3.27}/pyproject.toml +2 -2
  3. kash_shell-0.3.27/src/kash/actions/__init__.py +100 -0
  4. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/minify_html.py +2 -2
  5. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/general_commands.py +4 -2
  6. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/help/welcome.py +1 -1
  7. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/colors.py +2 -0
  8. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/logger.py +4 -0
  9. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/unified_live.py +2 -4
  10. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/mcp/mcp_server_sse.py +0 -5
  11. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/items_model.py +1 -1
  12. kash_shell-0.3.27/src/kash/shell/shell_main.py +133 -0
  13. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/version.py +18 -2
  14. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/base_styles.css.jinja +50 -22
  15. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/base_webpage.html.jinja +32 -0
  16. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/components/toc_styles.css.jinja +11 -2
  17. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/components/tooltip_styles.css.jinja +1 -0
  18. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/custom_shell.py +1 -4
  19. kash_shell-0.3.27/tests/web_gen/test_social_metadata.py +109 -0
  20. {kash_shell-0.3.26 → kash_shell-0.3.27}/uv.lock +277 -243
  21. kash_shell-0.3.26/src/kash/actions/__init__.py +0 -55
  22. kash_shell-0.3.26/src/kash/shell/shell_main.py +0 -75
  23. {kash_shell-0.3.26 → kash_shell-0.3.27}/.copier-answers.yml +0 -0
  24. {kash_shell-0.3.26 → kash_shell-0.3.27}/.cursor/rules/general.mdc +0 -0
  25. {kash_shell-0.3.26 → kash_shell-0.3.27}/.cursor/rules/python.mdc +0 -0
  26. {kash_shell-0.3.26 → kash_shell-0.3.27}/.env.template +0 -0
  27. {kash_shell-0.3.26 → kash_shell-0.3.27}/.github/workflows/ci.yml +0 -0
  28. {kash_shell-0.3.26 → kash_shell-0.3.27}/.github/workflows/publish.yml +0 -0
  29. {kash_shell-0.3.26 → kash_shell-0.3.27}/.gitignore +0 -0
  30. {kash_shell-0.3.26 → kash_shell-0.3.27}/LICENSE +0 -0
  31. {kash_shell-0.3.26 → kash_shell-0.3.27}/Makefile +0 -0
  32. {kash_shell-0.3.26 → kash_shell-0.3.27}/README.md +0 -0
  33. {kash_shell-0.3.26 → kash_shell-0.3.27}/development.md +0 -0
  34. {kash_shell-0.3.26 → kash_shell-0.3.27}/devtools/generate_readme.xsh +0 -0
  35. {kash_shell-0.3.26 → kash_shell-0.3.27}/devtools/lint.py +0 -0
  36. {kash_shell-0.3.26 → kash_shell-0.3.27}/devtools/profile_main.py +0 -0
  37. {kash_shell-0.3.26 → kash_shell-0.3.27}/installation.md +0 -0
  38. {kash_shell-0.3.26 → kash_shell-0.3.27}/publishing.md +0 -0
  39. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/__init__.py +0 -0
  40. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/__main__.py +0 -0
  41. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/assistant_chat.py +0 -0
  42. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/chat.py +0 -0
  43. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/combine_docs.py +0 -0
  44. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/concat_docs.py +0 -0
  45. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/format_markdown_template.py +0 -0
  46. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/markdownify_html.py +0 -0
  47. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/readability.py +0 -0
  48. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/render_as_html.py +0 -0
  49. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/show_webpage.py +0 -0
  50. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/strip_html.py +0 -0
  51. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/summarize_as_bullets.py +0 -0
  52. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/tabbed_webpage_config.py +0 -0
  53. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/core/tabbed_webpage_generate.py +0 -0
  54. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/meta/write_instructions.py +0 -0
  55. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/actions/meta/write_new_action.py +0 -0
  56. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/__init__.py +0 -0
  57. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/basic_file_commands.py +0 -0
  58. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/browser_commands.py +0 -0
  59. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/debug_commands.py +0 -0
  60. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/diff_commands.py +0 -0
  61. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/files_command.py +0 -0
  62. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/logs_commands.py +0 -0
  63. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/model_commands.py +0 -0
  64. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/reformat_command.py +0 -0
  65. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/search_command.py +0 -0
  66. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/base/show_command.py +0 -0
  67. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/extras/parse_uv_lock.py +0 -0
  68. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/extras/utils_commands.py +0 -0
  69. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/help/assistant_commands.py +0 -0
  70. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/help/doc_commands.py +0 -0
  71. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/help/help_commands.py +0 -0
  72. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/help/logo.py +0 -0
  73. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/workspace/selection_commands.py +0 -0
  74. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/commands/workspace/workspace_commands.py +0 -0
  75. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/__init__.py +0 -0
  76. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/capture_output.py +0 -0
  77. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/env_settings.py +0 -0
  78. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/init.py +0 -0
  79. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/lazy_imports.py +0 -0
  80. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/logger_basic.py +0 -0
  81. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/logo.txt +0 -0
  82. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/server_config.py +0 -0
  83. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/settings.py +0 -0
  84. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/setup.py +0 -0
  85. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/suppress_warnings.py +0 -0
  86. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/config/text_styles.py +0 -0
  87. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/__init__.py +0 -0
  88. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/all_docs.py +0 -0
  89. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/load_actions_info.py +0 -0
  90. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/load_api_docs.py +0 -0
  91. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/load_help_topics.py +0 -0
  92. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/load_source_code.py +0 -0
  93. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/api_docs_template.md +0 -0
  94. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/assistant_instructions_template.md +0 -0
  95. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/readme_template.md +0 -0
  96. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/a1_what_is_kash.md +0 -0
  97. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/a2_installation.md +0 -0
  98. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/a3_getting_started.md +0 -0
  99. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/a4_elements.md +0 -0
  100. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/a5_tips_for_use_with_other_tools.md +0 -0
  101. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/b0_philosophy_of_kash.md +0 -0
  102. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/b1_kash_overview.md +0 -0
  103. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/b2_workspace_and_file_formats.md +0 -0
  104. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/b3_modern_shell_tool_recommendations.md +0 -0
  105. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/topics/b4_faq.md +0 -0
  106. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/warning.md +0 -0
  107. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs/markdown/welcome.md +0 -0
  108. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs_base/docs_base.py +0 -0
  109. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs_base/load_custom_command_info.py +0 -0
  110. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs_base/load_faqs.py +0 -0
  111. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs_base/load_recipe_snippets.py +0 -0
  112. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs_base/recipes/general_system_commands.sh +0 -0
  113. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs_base/recipes/python_dev_commands.sh +0 -0
  114. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/docs_base/recipes/tldr_standard_commands.sh +0 -0
  115. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/embeddings/cosine.py +0 -0
  116. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/embeddings/embeddings.py +0 -0
  117. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/embeddings/text_similarity.py +0 -0
  118. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/__init__.py +0 -0
  119. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/action_decorators.py +0 -0
  120. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/action_exec.py +0 -0
  121. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/action_registry.py +0 -0
  122. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/combiners.py +0 -0
  123. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/command_exec.py +0 -0
  124. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/command_registry.py +0 -0
  125. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/fetch_url_items.py +0 -0
  126. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/history.py +0 -0
  127. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/importing.py +0 -0
  128. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/llm_transforms.py +0 -0
  129. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/precondition_checks.py +0 -0
  130. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/precondition_registry.py +0 -0
  131. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/preconditions.py +0 -0
  132. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/resolve_args.py +0 -0
  133. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/runtime_settings.py +0 -0
  134. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec/shell_callable_action.py +0 -0
  135. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec_model/__init__.py +0 -0
  136. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec_model/args_model.py +0 -0
  137. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec_model/commands_model.py +0 -0
  138. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec_model/script_model.py +0 -0
  139. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/exec_model/shell_model.py +0 -0
  140. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/file_storage/__init__.py +0 -0
  141. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/file_storage/file_store.py +0 -0
  142. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/file_storage/item_file_format.py +0 -0
  143. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/file_storage/metadata_dirs.py +0 -0
  144. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/file_storage/persisted_yaml.py +0 -0
  145. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/file_storage/store_cache_warmer.py +0 -0
  146. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/file_storage/store_filenames.py +0 -0
  147. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/__init__.py +0 -0
  148. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/assistant.py +0 -0
  149. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/assistant_instructions.py +0 -0
  150. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/assistant_output.py +0 -0
  151. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/function_param_info.py +0 -0
  152. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/help_embeddings.py +0 -0
  153. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/help_lookups.py +0 -0
  154. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/help_pages.py +0 -0
  155. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/help_printing.py +0 -0
  156. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/help_types.py +0 -0
  157. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/recommended_commands.py +0 -0
  158. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/help/tldr_help.py +0 -0
  159. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/__init__.py +0 -0
  160. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/clean_headings.py +0 -0
  161. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/custom_sliding_transforms.py +0 -0
  162. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/fuzzy_parsing.py +0 -0
  163. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/init_litellm.py +0 -0
  164. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/llm_api_keys.py +0 -0
  165. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/llm_completion.py +0 -0
  166. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/llm_features.py +0 -0
  167. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/llm_messages.py +0 -0
  168. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/llm_names.py +0 -0
  169. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/llm_utils/llms.py +0 -0
  170. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/local_server/__init__.py +0 -0
  171. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/local_server/local_server.py +0 -0
  172. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/local_server/local_server_commands.py +0 -0
  173. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/local_server/local_server_routes.py +0 -0
  174. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/local_server/local_url_formatters.py +0 -0
  175. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/local_server/port_tools.py +0 -0
  176. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/local_server/rich_html_template.py +0 -0
  177. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/mcp/__init__.py +0 -0
  178. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/mcp/mcp_cli.py +0 -0
  179. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/mcp/mcp_main.py +0 -0
  180. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/mcp/mcp_server_commands.py +0 -0
  181. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/mcp/mcp_server_routes.py +0 -0
  182. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/mcp/mcp_server_stdio.py +0 -0
  183. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/__init__.py +0 -0
  184. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/audio_processing.py +0 -0
  185. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/media_cache.py +0 -0
  186. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/media_services.py +0 -0
  187. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/media_tools.py +0 -0
  188. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/services/local_file_media.py +0 -0
  189. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/timestamp_citations.py +0 -0
  190. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/transcription_deepgram.py +0 -0
  191. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/transcription_format.py +0 -0
  192. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/media_base/transcription_whisper.py +0 -0
  193. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/__init__.py +0 -0
  194. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/actions_model.py +0 -0
  195. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/assistant_response_model.py +0 -0
  196. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/compound_actions_model.py +0 -0
  197. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/concept_model.py +0 -0
  198. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/exec_model.py +0 -0
  199. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/graph_model.py +0 -0
  200. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/language_list.py +0 -0
  201. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/llm_actions_model.py +0 -0
  202. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/media_model.py +0 -0
  203. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/operations_model.py +0 -0
  204. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/params_model.py +0 -0
  205. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/paths_model.py +0 -0
  206. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/model/preconditions_model.py +0 -0
  207. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/__init__.py +0 -0
  208. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/completions/completion_scoring.py +0 -0
  209. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/completions/completion_types.py +0 -0
  210. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/completions/shell_completions.py +0 -0
  211. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/file_icons/color_for_format.py +0 -0
  212. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/file_icons/nerd_icons.py +0 -0
  213. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/input/__init__.py +0 -0
  214. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/input/input_prompts.py +0 -0
  215. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/input/inquirer_settings.py +0 -0
  216. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/input/param_inputs.py +0 -0
  217. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/input/shell_confirm.py +0 -0
  218. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/output/__init__.py +0 -0
  219. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/output/kerm_code_utils.py +0 -0
  220. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/output/kerm_codes.py +0 -0
  221. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/output/kmarkdown.py +0 -0
  222. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/output/shell_formatting.py +0 -0
  223. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/output/shell_output.py +0 -0
  224. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/ui/__init__.py +0 -0
  225. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/ui/shell_results.py +0 -0
  226. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/ui/shell_syntax.py +0 -0
  227. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/utils/exception_printing.py +0 -0
  228. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/utils/native_utils.py +0 -0
  229. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/shell/utils/shell_function_wrapper.py +0 -0
  230. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/__init__.py +0 -0
  231. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/api_utils/api_retries.py +0 -0
  232. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/api_utils/cache_requests_limited.py +0 -0
  233. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/api_utils/gather_limited.py +0 -0
  234. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/api_utils/http_utils.py +0 -0
  235. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/api_utils/progress_protocol.py +0 -0
  236. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/__init__.py +0 -0
  237. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/format_utils.py +0 -0
  238. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/function_inspect.py +0 -0
  239. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/import_utils.py +0 -0
  240. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/lazyobject.py +0 -0
  241. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/obj_replace.py +0 -0
  242. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/parse_docstring.py +0 -0
  243. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/parse_key_vals.py +0 -0
  244. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/parse_shell_args.py +0 -0
  245. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/stack_traces.py +0 -0
  246. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/task_stack.py +0 -0
  247. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/testing.py +0 -0
  248. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/type_utils.py +0 -0
  249. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/uniquifier.py +0 -0
  250. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/url.py +0 -0
  251. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/common/url_slice.py +0 -0
  252. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/errors.py +0 -0
  253. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_formats/chat_format.py +0 -0
  254. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/__init__.py +0 -0
  255. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/csv_utils.py +0 -0
  256. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/dir_info.py +0 -0
  257. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/file_ext.py +0 -0
  258. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/file_formats.py +0 -0
  259. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/file_formats_model.py +0 -0
  260. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/file_sort_filter.py +0 -0
  261. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/file_walk.py +0 -0
  262. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/filename_parsing.py +0 -0
  263. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/ignore_files.py +0 -0
  264. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/mtime_cache.py +0 -0
  265. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/file_utils/path_utils.py +0 -0
  266. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/lang_utils/__init__.py +0 -0
  267. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/lang_utils/capitalization.py +0 -0
  268. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/rich_custom/__init__.py +0 -0
  269. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/rich_custom/ansi_cell_len.py +0 -0
  270. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/rich_custom/multitask_status.py +0 -0
  271. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/rich_custom/rich_char_transform.py +0 -0
  272. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/rich_custom/rich_indent.py +0 -0
  273. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/rich_custom/rich_markdown_fork.py +0 -0
  274. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/text_handling/doc_normalization.py +0 -0
  275. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/text_handling/escape_html_tags.py +0 -0
  276. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/text_handling/markdown_render.py +0 -0
  277. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/text_handling/markdown_utils.py +0 -0
  278. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/text_handling/markdownify_utils.py +0 -0
  279. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/utils/text_handling/unified_diffs.py +0 -0
  280. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/canon_url.py +0 -0
  281. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/dir_store.py +0 -0
  282. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/file_cache_utils.py +0 -0
  283. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/file_processing.py +0 -0
  284. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/local_file_cache.py +0 -0
  285. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/web_extract.py +0 -0
  286. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/web_extract_justext.py +0 -0
  287. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/web_extract_readabilipy.py +0 -0
  288. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/web_fetch.py +0 -0
  289. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_content/web_page_model.py +0 -0
  290. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/__init__.py +0 -0
  291. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/simple_webpage.py +0 -0
  292. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/tabbed_webpage.py +0 -0
  293. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/template_render.py +0 -0
  294. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/components/toc_scripts.js.jinja +0 -0
  295. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/components/tooltip_scripts.js.jinja +0 -0
  296. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/content_styles.css.jinja +0 -0
  297. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/explain_view.html.jinja +0 -0
  298. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/item_view.html.jinja +0 -0
  299. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/simple_webpage.html.jinja +0 -0
  300. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/web_gen/templates/tabbed_webpage.html.jinja +0 -0
  301. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/workspaces/__init__.py +0 -0
  302. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/workspaces/param_state.py +0 -0
  303. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/workspaces/selections.py +0 -0
  304. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/workspaces/source_items.py +0 -0
  305. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/workspaces/workspace_dirs.py +0 -0
  306. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/workspaces/workspace_output.py +0 -0
  307. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/workspaces/workspace_registry.py +0 -0
  308. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/workspaces/workspaces.py +0 -0
  309. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/command_nl_utils.py +0 -0
  310. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/customize_prompt.py +0 -0
  311. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/load_into_xonsh.py +0 -0
  312. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/shell_load_commands.py +0 -0
  313. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/shell_which.py +0 -0
  314. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/xonsh_completers.py +0 -0
  315. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/xonsh_env.py +0 -0
  316. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/xonsh_keybindings.py +0 -0
  317. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/xonsh_modern_tools.py +0 -0
  318. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xonsh_custom/xonsh_ranking_completer.py +0 -0
  319. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xontrib/fnm.py +0 -0
  320. {kash_shell-0.3.26 → kash_shell-0.3.27}/src/kash/xontrib/kash_extension.py +0 -0
  321. {kash_shell-0.3.26 → kash_shell-0.3.27}/tests/kash/utils/api_utils/test_gather_limited.py +0 -0
  322. {kash_shell-0.3.26 → kash_shell-0.3.27}/tests/kash/utils/file_utils/test_csv_utils.py +0 -0
  323. {kash_shell-0.3.26 → kash_shell-0.3.27}/tests/kash/utils/rich_custom/test_multitask_status.py +0 -0
  324. {kash_shell-0.3.26 → kash_shell-0.3.27}/tests/test_shell.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.26
3
+ Version: 0.3.27
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>
@@ -41,7 +41,6 @@ Requires-Dist: litellm>=1.63.11
41
41
  Requires-Dist: markdownify>=0.13.1
42
42
  Requires-Dist: mcp-proxy>=0.5.0
43
43
  Requires-Dist: mcp>=1.6.0
44
- Requires-Dist: minify-tw-html>=0.1.3
45
44
  Requires-Dist: openai>=1.66.3
46
45
  Requires-Dist: pandas>=2.2.3
47
46
  Requires-Dist: patch-ng>=1.18.1
@@ -70,6 +69,7 @@ Requires-Dist: tenacity>=9.0.0
70
69
  Requires-Dist: thefuzz>=0.22.1
71
70
  Requires-Dist: tiktoken>=0.9.0
72
71
  Requires-Dist: tldr>=3.3.0
72
+ Requires-Dist: tminify>=0.1.6
73
73
  Requires-Dist: typing-extensions>=4.12.2
74
74
  Requires-Dist: uvicorn>=0.34.0
75
75
  Requires-Dist: xonsh>=0.19.3
@@ -49,7 +49,7 @@ dependencies = [
49
49
  "frontmatter-format>=0.2.1",
50
50
  "chopdiff>=0.2.3",
51
51
  "clideps>=0.1.4",
52
- "minify-tw-html>=0.1.3",
52
+ "tminify>=0.1.6",
53
53
  # Shell and file essentials:
54
54
  # python-magic is most current and works with libmagic on macOS and Linux.
55
55
  # on Windows, python-magic-bin seems like the best option.
@@ -129,7 +129,7 @@ kash-mcp = "kash.mcp.mcp_cli:main"
129
129
  [tool.uv.sources]
130
130
  # For local development:
131
131
  # clideps = { path = "../clideps", editable = true }
132
- # minify-tw-html = { path = "../../github/minify-tw-html", editable = true }
132
+ # tminify = { path = "../../github/tminify", editable = true }
133
133
 
134
134
  # ---- Build system ----
135
135
 
@@ -0,0 +1,100 @@
1
+ from dataclasses import dataclass
2
+ from importlib import metadata
3
+ from pathlib import Path
4
+
5
+ from strif import AtomicVar
6
+
7
+ from kash.config.logger import get_logger
8
+ from kash.config.settings import APP_NAME
9
+ from kash.exec import import_and_register
10
+ from kash.utils.common.import_utils import import_namespace_modules
11
+
12
+ log = get_logger(__name__)
13
+
14
+ import_and_register(__package__, Path(__file__).parent, ["core", "meta"])
15
+
16
+
17
+ @dataclass(frozen=True)
18
+ class Kit:
19
+ module_name: str
20
+ distribution_name: str
21
+ full_module_name: str
22
+ path: Path | None
23
+ version: str | None = None
24
+
25
+
26
+ _kits: AtomicVar[dict[str, Kit]] = AtomicVar(initial_value={})
27
+
28
+
29
+ def get_loaded_kits() -> dict[str, Kit]:
30
+ """
31
+ Get all kits (modules within `kash.kits`) that have been loaded.
32
+ """
33
+ return _kits.copy()
34
+
35
+
36
+ def get_kit_distribution_name(module_name: str) -> str | None:
37
+ """
38
+ Guess the distribution name for a kit module using naming conventions.
39
+ Assumes kits follow patterns like:
40
+ - kash.kits.example_kit -> kash-example-kit
41
+ """
42
+ if not module_name.startswith("kash.kits."):
43
+ return None
44
+
45
+ kit_name = module_name.removeprefix("kash.kits.")
46
+
47
+ # Try common naming patterns
48
+ candidates = [
49
+ f"kash-{kit_name}",
50
+ f"kash-{kit_name.replace('_', '-')}",
51
+ ]
52
+
53
+ for candidate in candidates:
54
+ try:
55
+ metadata.version(candidate)
56
+ return candidate
57
+ except metadata.PackageNotFoundError:
58
+ continue
59
+
60
+ return None
61
+
62
+
63
+ def get_distribution_version(module_name: str) -> str | None:
64
+ """
65
+ Get the version of a module that can be used with `metadata.version()`.
66
+ """
67
+ try:
68
+ dist_name = get_kit_distribution_name(module_name)
69
+ return metadata.version(dist_name) if dist_name else None
70
+ except Exception:
71
+ return None
72
+
73
+
74
+ def load_kits() -> dict[str, Kit]:
75
+ """
76
+ Import all kits (modules within `kash.kits`) by inspecting the namespace.
77
+ """
78
+ kits_namespace = f"{APP_NAME}.kits"
79
+ new_kits = {}
80
+ try:
81
+ imported = import_namespace_modules(kits_namespace)
82
+ for module_name, module in imported.items():
83
+ dist_name = get_kit_distribution_name(module.__name__) or module.__name__
84
+
85
+ new_kits[module_name] = Kit(
86
+ module_name=module_name,
87
+ distribution_name=dist_name,
88
+ full_module_name=module.__name__,
89
+ path=Path(module.__file__) if module.__file__ else None,
90
+ version=metadata.version(dist_name),
91
+ )
92
+ except ImportError:
93
+ log.info("No kits found in namespace `%s`", kits_namespace)
94
+
95
+ _kits.update(lambda kits: {**kits, **new_kits})
96
+
97
+ return new_kits
98
+
99
+
100
+ load_kits()
@@ -22,7 +22,7 @@ def minify_html(item: Item) -> Item:
22
22
  The terser minification seems a bit slower but more robust than
23
23
  [minify-html](https://github.com/wilsonzlin/minify-html).
24
24
  """
25
- from minify_tw_html import minify_tw_html
25
+ from tminify.main import tminify
26
26
 
27
27
  if not item.store_path:
28
28
  raise InvalidInput(f"Missing store path: {item}")
@@ -33,7 +33,7 @@ def minify_html(item: Item) -> Item:
33
33
  output_item = item.derived_copy(format=Format.html, body=None)
34
34
  output_path = ws.target_path_for(output_item)
35
35
 
36
- minify_tw_html(input_path, output_path)
36
+ tminify(input_path, output_path)
37
37
 
38
38
  output_item.body = output_path.read_text()
39
39
  output_item.external_path = str(output_path) # Indicate item is already saved.
@@ -39,7 +39,7 @@ def version() -> None:
39
39
  """
40
40
  Show the version of kash.
41
41
  """
42
- cprint(get_full_version_name())
42
+ cprint(get_full_version_name(with_kits=True))
43
43
 
44
44
 
45
45
  @kash_command
@@ -205,7 +205,9 @@ def kits() -> None:
205
205
  cprint("Currently imported kits:")
206
206
  for kit in get_loaded_kits().values():
207
207
  cprint(
208
- format_name_and_value(f"{kit.name} kit", str(kit.path or ""), text_wrap=Wrap.NONE)
208
+ format_name_and_value(
209
+ f"{kit.distribution_name} kit", str(kit.path or ""), text_wrap=Wrap.NONE
210
+ )
209
211
  )
210
212
 
211
213
 
@@ -31,4 +31,4 @@ def welcome() -> None:
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())
34
+ cprint("%s", get_full_version_name(with_kits=True))
@@ -145,6 +145,7 @@ web_light_translucent = SimpleNamespace(
145
145
  text=hsl_to_hex("hsl(188, 39%, 11%)"),
146
146
  code=hsl_to_hex("hsl(44, 38%, 23%)"),
147
147
  border=hsl_to_hex("hsl(188, 8%, 50%)"),
148
+ border_hairline=hsl_to_hex("hsl(188, 2%, 34%)"),
148
149
  border_hint=hsl_to_hex("hsla(188, 8%, 72%, 0.3)"),
149
150
  border_accent=hsl_to_hex("hsla(305, 18%, 65%, 0.85)"),
150
151
  hover=hsl_to_hex("hsl(188, 12%, 84%)"),
@@ -180,6 +181,7 @@ web_dark_translucent = SimpleNamespace(
180
181
  text=hsl_to_hex("hsl(188, 10%, 90%)"),
181
182
  code=hsl_to_hex("hsl(44, 38%, 72%)"),
182
183
  border=hsl_to_hex("hsl(188, 8%, 25%)"),
184
+ border_hairline=hsl_to_hex("hsl(188, 2%, 80%)"),
183
185
  border_hint=hsl_to_hex("hsla(188, 8%, 35%, 0.3)"),
184
186
  border_accent=hsl_to_hex("hsla(305, 30%, 55%, 0.85)"),
185
187
  hover=hsl_to_hex("hsl(188, 12%, 35%)"),
@@ -170,6 +170,7 @@ def reset_rich_logging(
170
170
  the `.log` extension. If `log_path` is provided, it will be used to infer
171
171
  the log root and name.
172
172
  """
173
+ _init_rich_logging()
173
174
  if log_path:
174
175
  if not log_path.parent.exists():
175
176
  log_path.parent.mkdir(parents=True, exist_ok=True)
@@ -206,6 +207,9 @@ def reload_rich_logging_setup():
206
207
 
207
208
  @cache
208
209
  def _init_rich_logging():
210
+ """
211
+ One-time idempotent setup of rich logging.
212
+ """
209
213
  rich.reconfigure(theme=get_theme(), highlighter=get_highlighter())
210
214
 
211
215
  logging.setLoggerClass(CustomLogger)
@@ -2,20 +2,18 @@ from __future__ import annotations
2
2
 
3
3
  import atexit
4
4
  import threading
5
- import time
6
5
  from collections.abc import Generator
7
6
  from contextlib import contextmanager
8
7
  from dataclasses import dataclass, field
9
8
 
10
- from rich.console import Console, RenderableType
9
+ from rich.console import Console, Group, RenderableType
11
10
  from rich.live import Live
12
11
  from rich.spinner import Spinner
13
12
  from rich.text import Text
14
- from rich.console import Group
15
13
  from strif import AtomicVar
16
14
 
17
15
  from kash.config.logger import get_console
18
- from kash.config.text_styles import SPINNER, COLOR_SPINNER
16
+ from kash.config.text_styles import COLOR_SPINNER, SPINNER
19
17
 
20
18
 
21
19
  @dataclass
@@ -8,7 +8,6 @@ from typing import TYPE_CHECKING
8
8
 
9
9
  from mcp.server.sse import SseServerTransport
10
10
  from prettyfmt import fmt_path
11
- from sse_starlette.sse import AppStatus
12
11
  from starlette.applications import Starlette
13
12
  from starlette.routing import Mount, Route
14
13
 
@@ -72,10 +71,6 @@ class MCPServerSSE:
72
71
  def _setup_server(self):
73
72
  import uvicorn
74
73
 
75
- # Reset AppStatus.should_exit_event to None to ensure it's created
76
- # in the correct event loop when needed.
77
- AppStatus.should_exit_event = None
78
-
79
74
  port = global_settings().mcp_server_port
80
75
 
81
76
  # Check if the port is available.
@@ -263,7 +263,7 @@ class Item:
263
263
  thumbnail_url: Url | None = None
264
264
 
265
265
  # Optional additional metadata.
266
- extra: dict | None = None
266
+ extra: dict[str, Any] | None = None
267
267
 
268
268
  # Optional execution context. Useful for letting functions that take only an Item
269
269
  # arg get access to context.
@@ -0,0 +1,133 @@
1
+ """
2
+ Welcome to Kash! This command is the main way to run the kash shell.
3
+
4
+ Usually this is used to start the kash interactively but you can also pass a single
5
+ command to run non-interactively.
6
+
7
+ Run `kash manual` for general help. Run `kash self_check` to check the kash environment.
8
+ Run `kash --help` for this page.
9
+
10
+ More information at: github.com/jlevy/kash
11
+ """
12
+
13
+ import argparse
14
+ import threading
15
+
16
+ from strif import quote_if_needed
17
+
18
+ from kash.config.logger import get_console, get_logger
19
+ from kash.config.setup import kash_setup
20
+ from kash.shell.version import get_full_version_name, get_version
21
+
22
+ kash_setup(rich_logging=True) # Set up logging first.
23
+
24
+ log = get_logger(__name__)
25
+
26
+
27
+ __version__ = get_version()
28
+
29
+
30
+ # No longer using, but keeping for reference.
31
+ def run_plain_xonsh():
32
+ """
33
+ The standard way to run kash is now via the customized shell.
34
+ But we can also run a regular xonsh shell and have it load kash commands via the
35
+ xontrib only (in ~/.xonshrc), but the full customizations of prompts, tab
36
+ completion, etc are not available.
37
+ """
38
+ import xonsh.main
39
+
40
+ from kash.xonsh_custom.custom_shell import install_to_xonshrc
41
+
42
+ install_to_xonshrc()
43
+ xonsh.main.main()
44
+
45
+
46
+ # Event to monitor loading.
47
+ shell_ready_event = threading.Event()
48
+
49
+ imports_done_event = threading.Event()
50
+
51
+
52
+ def run_shell(single_command: str | None = None):
53
+ """
54
+ Run the kash shell interactively or non-interactively with a single command.
55
+ """
56
+ from kash.xonsh_custom.custom_shell import start_shell
57
+
58
+ start_shell(single_command, shell_ready_event)
59
+
60
+
61
+ def build_parser() -> argparse.ArgumentParser:
62
+ from clideps.utils.readable_argparse import ReadableColorFormatter
63
+
64
+ parser = argparse.ArgumentParser(description=__doc__, formatter_class=ReadableColorFormatter)
65
+
66
+ # Don't call get_full_version_name() here, as it's slow.
67
+ parser.add_argument("--version", action="store_true", help="show version and exit")
68
+
69
+ return parser
70
+
71
+
72
+ def _import_packages():
73
+ try:
74
+ # Slowest packages:
75
+ import uvicorn.protocols # noqa: F401
76
+ import uvicorn.protocols.http.h11_impl # noqa: F401
77
+ import uvicorn.protocols.websockets.websockets_impl # noqa: F401
78
+ import xonsh.completers.init # noqa: F401
79
+ import xonsh.pyghooks # noqa: F401
80
+
81
+ import kash.actions # noqa: F401
82
+ import kash.local_server # noqa: F401
83
+ import kash.local_server.local_server # noqa: F401
84
+ import kash.mcp.mcp_server_sse # noqa: F401
85
+ except ImportError as e:
86
+ log.warning(f"Error pre-importing packages: {e}")
87
+
88
+ imports_done_event.set()
89
+
90
+
91
+ def import_with_status_if_slow(min_time: float = 1.0):
92
+ """
93
+ Not required, but imports can be remarkably slow the first time, so this shows a status message.
94
+ """
95
+
96
+ # Start imports in background thread
97
+ import_thread = threading.Thread(target=_import_packages, daemon=True)
98
+ import_thread.start()
99
+
100
+ # Wait for imports to complete, with a short timeout
101
+ if not imports_done_event.wait(timeout=min_time):
102
+ # If imports aren't done quickly, show status message
103
+ if get_console().is_terminal:
104
+ with get_console().status(
105
+ "Importing packages (this is a bit slow the first time) …", spinner="line"
106
+ ):
107
+ import_thread.join()
108
+ else:
109
+ import_thread.join()
110
+
111
+
112
+ def main():
113
+ parser = build_parser()
114
+
115
+ args, unknown = parser.parse_known_args()
116
+
117
+ if args.version:
118
+ print(get_full_version_name(with_kits=True))
119
+ return
120
+
121
+ # Join remaining arguments to pass as a single command to kash.
122
+ # Use Python-style quoting only if needed for xonsh.
123
+ single_command = None
124
+ if unknown:
125
+ single_command = " ".join(quote_if_needed(arg) for arg in unknown)
126
+
127
+ import_with_status_if_slow()
128
+
129
+ run_shell(single_command)
130
+
131
+
132
+ if __name__ == "__main__":
133
+ main()
@@ -28,8 +28,24 @@ def get_version_tag():
28
28
  return f"v{get_version()}"
29
29
 
30
30
 
31
- def get_full_version_name():
32
- return f"{PACKAGE_NAME} {get_version_tag()}"
31
+ def get_full_version_name(with_kits: bool = False):
32
+ """
33
+ Get the full version name, including the version number and any loaded kits.
34
+
35
+ If `with_kits` is True, will also import `kash.kits` packages and get those versions,
36
+ but be careful as this can be much slower due to imports!
37
+ """
38
+
39
+ version_items = [f"{PACKAGE_NAME} {get_version_tag()}"]
40
+ if with_kits:
41
+ from kash.actions import get_loaded_kits
42
+
43
+ kits = get_loaded_kits()
44
+ for kit in kits.values():
45
+ if kit.version:
46
+ version_items.append(f"{kit.distribution_name} v{kit.version}")
47
+
48
+ return ", ".join(version_items)
33
49
 
34
50
 
35
51
  if __name__ == "__main__":
@@ -22,15 +22,19 @@
22
22
  --font-size-large: 1.2rem;
23
23
  --font-size-normal: 1rem;
24
24
  --font-size-small: 0.95rem;
25
- --font-size-smaller: 0.85rem;
25
+ --font-size-smaller: 0.9rem;
26
+ --font-size-tiny: 0.85rem;
26
27
  --font-size-mono: 0.82rem;
27
28
  --font-size-mono-small: 0.75rem;
28
29
  --font-size-mono-tiny: 0.7rem;
29
30
 
31
+ --line-height-normal: 1.5;
32
+ --line-height-tight: 1.2;
33
+
30
34
  /* Both Source Sans 3 and PT Serif have small caps, so we use this instead of text-transform. */
31
35
  --caps-transform: none;
32
36
  --caps-caps-variant: all-small-caps;
33
- --caps-spacing: 0.025em;
37
+ --caps-spacing: 0.021em;
34
38
  /* Compensate for small caps (Source Sans small caps are quite small) */
35
39
  --caps-heading-size-multiplier: 1.42;
36
40
  --caps-heading-line-height: calc(1.2 / var(--caps-heading-size-multiplier));
@@ -107,7 +111,7 @@ html {
107
111
  body {
108
112
  font-family: var(--font-serif);
109
113
  color: var(--color-text);
110
- line-height: 1.5;
114
+ line-height: var(--line-height-normal);
111
115
  padding: 0; /* No padding so we can have full width elements. */
112
116
  margin: auto;
113
117
  background-color: var(--color-bg);
@@ -142,7 +146,7 @@ a:hover {
142
146
  }
143
147
 
144
148
  h1, h2, h3, h4, h5, h6 {
145
- line-height: 1.2;
149
+ line-height: var(--line-height-tight);
146
150
  }
147
151
 
148
152
  h1 {
@@ -196,7 +200,7 @@ h4+p, h5+p, h6+p {
196
200
  ul {
197
201
  list-style-type: none;
198
202
  margin-left: 1.8rem;
199
- margin-bottom: 1rem;
203
+ margin-bottom: 0.7rem;
200
204
  padding-left: 0;
201
205
  }
202
206
 
@@ -207,6 +211,7 @@ li {
207
211
  }
208
212
 
209
213
  li > p {
214
+ /* No extra padding for paragraphs inside list items. */
210
215
  margin-bottom: 0;
211
216
  }
212
217
 
@@ -229,10 +234,9 @@ ol > li {
229
234
  }
230
235
 
231
236
  blockquote {
232
- border-left: 2px solid var(--color-primary);
237
+ {# border-left: 1px solid var(--color-border-hairline); #}
233
238
  padding-left: 1rem;
234
- margin-left: 0;
235
- margin-right: 0;
239
+ margin: 1.5rem 4rem 1.5rem 1rem;
236
240
  }
237
241
 
238
242
  /* Inline code styling */
@@ -240,7 +244,6 @@ code {
240
244
  font-family: var(--font-mono);
241
245
  font-size: var(--font-size-mono);
242
246
  letter-spacing: -0.025em;
243
-
244
247
  transition: color 0.4s ease-in-out;
245
248
  }
246
249
  /* For code inside pre we style the pre tag */
@@ -619,12 +622,14 @@ sup {
619
622
 
620
623
  @media print {
621
624
  sup {
622
- font-size: 70% !important;
625
+ /* Using small-caps so this is a bit larger */
626
+ font-size: 110% !important;
623
627
  }
624
628
 
625
629
  /* Don't use stylized footnotes in print. */
626
630
  .footnote-ref a, .footnote {
627
631
  font-family: var(--font-serif);
632
+ font-variant-caps: all-small-caps !important;
628
633
  font-feature-settings: normal !important;
629
634
  background-color: transparent !important;
630
635
  color: var(--color-text) !important;
@@ -675,9 +680,9 @@ sup {
675
680
 
676
681
  @bottom-right {
677
682
  content: counter(page);
678
- font-family: var(--font-sans) !important;
683
+ font-family: var(--font-serif) !important;
679
684
  font-size: var(--font-size-small);
680
- color: var(--color-tertiary) !important;
685
+ color: var(--color-text) !important;
681
686
  margin: 0 0 0.2in 0 !important;
682
687
  }
683
688
  }
@@ -688,13 +693,25 @@ sup {
688
693
  --font-size-small: 1.0rem;
689
694
  --font-size-smaller: 0.9rem;
690
695
  --font-size-mono: 0.9rem;
696
+
697
+ /* Tighter line height for print readability */
698
+ --line-height-normal: 1.4;
699
+ --line-height-tight: 1.15;
691
700
  }
692
701
 
693
- body {
702
+ body {
694
703
  /* Remove body margin since @page handles it */
695
704
  margin: 0;
696
- /* Ensure good line height for print */
697
- line-height: 1.6;
705
+ }
706
+
707
+ /* Reduce spacing between block elements to match tighter line height */
708
+ p {
709
+ margin-top: 0.65rem;
710
+ margin-bottom: 0.65rem;
711
+ }
712
+
713
+ li {
714
+ margin-top: 0.6rem;
698
715
  }
699
716
 
700
717
  /* Enable hyphenation and justification for main text content only */
@@ -703,8 +720,6 @@ sup {
703
720
  text-align: justify;
704
721
  }
705
722
 
706
-
707
-
708
723
  .long-text {
709
724
  /* Remove shadows and borders that don't work well in print */
710
725
  box-shadow: none !important;
@@ -713,6 +728,15 @@ sup {
713
728
  padding: 0;
714
729
  }
715
730
 
731
+ /* Slightly darker sans-serif headings look better in print. */
732
+ .long-text h3 {
733
+ font-weight: 580;
734
+ }
735
+
736
+ .long-text h4 {
737
+ font-weight: 580;
738
+ }
739
+
716
740
  /* Ensure tables don't break layout in print */
717
741
  .table-container {
718
742
  position: static;
@@ -733,6 +757,15 @@ sup {
733
757
  pre {
734
758
  white-space: pre-wrap;
735
759
  word-wrap: break-word;
760
+ background-color: transparent !important;
761
+ border: none !important;
762
+ font-weight: normal !important;
763
+ }
764
+
765
+ code {
766
+ background-color: transparent !important;
767
+ border: none !important;
768
+ font-weight: normal !important;
736
769
  }
737
770
 
738
771
  /* Hide interactive elements that don't work in print */
@@ -760,11 +793,6 @@ sup {
760
793
  widows: 3; /* Minimum lines at top of page */
761
794
  }
762
795
 
763
- /* Keep list items together when reasonable */
764
- li {
765
- break-inside: avoid-page;
766
- page-break-inside: avoid; /* Fallback for older browsers */
767
- }
768
796
 
769
797
  /* Hide doc metadata details in print (for now) */
770
798
  details.metadata {
@@ -10,6 +10,38 @@
10
10
 
11
11
  {% block title %}<title>{{ title }}</title>{% endblock title %}
12
12
 
13
+ {% block social_meta %}
14
+ {% if social_meta %}
15
+ <!-- Open Graph meta tags -->
16
+ <meta property="og:title" content="{{ social_meta.title or title }}" />
17
+ {% if social_meta.description %}
18
+ <meta property="og:description" content="{{ social_meta.description }}" />
19
+ {% endif %}
20
+ {% if social_meta.image %}
21
+ <meta property="og:image" content="{{ social_meta.image }}" />
22
+ {% endif %}
23
+ {% if social_meta.url %}
24
+ <meta property="og:url" content="{{ social_meta.url }}" />
25
+ {% endif %}
26
+ <meta property="og:type" content="{{ social_meta.type or 'website' }}" />
27
+ {% if social_meta.site_name %}
28
+ <meta property="og:site_name" content="{{ social_meta.site_name }}" />
29
+ {% endif %}
30
+ <!-- Twitter Card meta tags -->
31
+ <meta name="twitter:card" content="summary_large_image" />
32
+ <meta name="twitter:title" content="{{ social_meta.title or title }}" />
33
+ {% if social_meta.description %}
34
+ <meta name="twitter:description" content="{{ social_meta.description }}" />
35
+ {% endif %}
36
+ {% if social_meta.image %}
37
+ <meta name="twitter:image" content="{{ social_meta.image }}" />
38
+ {% endif %}
39
+ {% if social_meta.twitter_handle %}
40
+ <meta name="twitter:site" content="@{{ social_meta.twitter_handle }}" />
41
+ {% endif %}
42
+ {% endif %}
43
+ {% endblock social_meta %}
44
+
13
45
  {% block dark_mode_script %}
14
46
  <script>
15
47
  // Set theme before body renders to prevent flash of unstyled content