kash-shell 0.3.20__tar.gz → 0.3.21__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 (314) hide show
  1. {kash_shell-0.3.20 → kash_shell-0.3.21}/.copier-answers.yml +1 -1
  2. {kash_shell-0.3.20 → kash_shell-0.3.21}/.cursor/rules/general.mdc +18 -13
  3. {kash_shell-0.3.20 → kash_shell-0.3.21}/.cursor/rules/python.mdc +52 -12
  4. {kash_shell-0.3.20 → kash_shell-0.3.21}/.github/workflows/ci.yml +1 -1
  5. {kash_shell-0.3.20 → kash_shell-0.3.21}/.github/workflows/publish.yml +4 -1
  6. {kash_shell-0.3.20 → kash_shell-0.3.21}/Makefile +1 -1
  7. {kash_shell-0.3.20 → kash_shell-0.3.21}/PKG-INFO +3 -1
  8. {kash_shell-0.3.20 → kash_shell-0.3.21}/development.md +1 -1
  9. {kash_shell-0.3.20 → kash_shell-0.3.21}/pyproject.toml +4 -1
  10. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/colors.py +8 -6
  11. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/text_styles.py +2 -0
  12. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b1_kash_overview.md +34 -45
  13. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/action_decorators.py +20 -5
  14. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/llm_transforms.py +1 -1
  15. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/shell_callable_action.py +1 -1
  16. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/llm_completion.py +1 -1
  17. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/actions_model.py +6 -0
  18. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/output/shell_output.py +15 -0
  19. kash_shell-0.3.21/src/kash/utils/api_utils/api_retries.py +305 -0
  20. kash_shell-0.3.21/src/kash/utils/api_utils/cache_requests_limited.py +84 -0
  21. kash_shell-0.3.21/src/kash/utils/api_utils/gather_limited.py +987 -0
  22. kash_shell-0.3.21/src/kash/utils/api_utils/progress_protocol.py +299 -0
  23. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/function_inspect.py +66 -1
  24. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/testing.py +10 -7
  25. kash_shell-0.3.21/src/kash/utils/rich_custom/multitask_status.py +631 -0
  26. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/text_handling/escape_html_tags.py +16 -11
  27. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdown_render.py +1 -0
  28. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/base_styles.css.jinja +26 -20
  29. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/toc_styles.css.jinja +1 -1
  30. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/tooltip_scripts.js.jinja +171 -19
  31. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/tooltip_styles.css.jinja +23 -8
  32. kash_shell-0.3.21/tests/kash/utils/rich_custom/test_multitask_status.py +564 -0
  33. {kash_shell-0.3.20 → kash_shell-0.3.21}/uv.lock +269 -269
  34. {kash_shell-0.3.20 → kash_shell-0.3.21}/.env.template +0 -0
  35. {kash_shell-0.3.20 → kash_shell-0.3.21}/.gitignore +0 -0
  36. {kash_shell-0.3.20 → kash_shell-0.3.21}/LICENSE +0 -0
  37. {kash_shell-0.3.20 → kash_shell-0.3.21}/README.md +0 -0
  38. {kash_shell-0.3.20 → kash_shell-0.3.21}/devtools/generate_readme.xsh +0 -0
  39. {kash_shell-0.3.20 → kash_shell-0.3.21}/devtools/lint.py +0 -0
  40. {kash_shell-0.3.20 → kash_shell-0.3.21}/devtools/profile_main.py +0 -0
  41. {kash_shell-0.3.20 → kash_shell-0.3.21}/installation.md +0 -0
  42. {kash_shell-0.3.20 → kash_shell-0.3.21}/publishing.md +0 -0
  43. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/__init__.py +0 -0
  44. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/__main__.py +0 -0
  45. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/__init__.py +0 -0
  46. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/assistant_chat.py +0 -0
  47. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/chat.py +0 -0
  48. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/format_markdown_template.py +0 -0
  49. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/markdownify_html.py +0 -0
  50. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/minify_html.py +0 -0
  51. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/readability.py +0 -0
  52. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/render_as_html.py +0 -0
  53. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/show_webpage.py +0 -0
  54. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/strip_html.py +0 -0
  55. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/summarize_as_bullets.py +0 -0
  56. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/tabbed_webpage_config.py +0 -0
  57. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/core/tabbed_webpage_generate.py +0 -0
  58. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/meta/write_instructions.py +0 -0
  59. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/actions/meta/write_new_action.py +0 -0
  60. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/__init__.py +0 -0
  61. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/basic_file_commands.py +0 -0
  62. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/browser_commands.py +0 -0
  63. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/debug_commands.py +0 -0
  64. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/diff_commands.py +0 -0
  65. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/files_command.py +0 -0
  66. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/general_commands.py +0 -0
  67. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/logs_commands.py +0 -0
  68. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/model_commands.py +0 -0
  69. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/reformat_command.py +0 -0
  70. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/search_command.py +0 -0
  71. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/base/show_command.py +0 -0
  72. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/extras/parse_uv_lock.py +0 -0
  73. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/extras/utils_commands.py +0 -0
  74. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/help/assistant_commands.py +0 -0
  75. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/help/doc_commands.py +0 -0
  76. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/help/help_commands.py +0 -0
  77. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/help/logo.py +0 -0
  78. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/help/welcome.py +0 -0
  79. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/workspace/selection_commands.py +0 -0
  80. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/commands/workspace/workspace_commands.py +0 -0
  81. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/__init__.py +0 -0
  82. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/capture_output.py +0 -0
  83. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/env_settings.py +0 -0
  84. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/init.py +0 -0
  85. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/lazy_imports.py +0 -0
  86. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/logger.py +0 -0
  87. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/logger_basic.py +0 -0
  88. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/logo.txt +0 -0
  89. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/server_config.py +0 -0
  90. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/settings.py +0 -0
  91. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/setup.py +0 -0
  92. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/config/suppress_warnings.py +0 -0
  93. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/__init__.py +0 -0
  94. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/all_docs.py +0 -0
  95. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/load_actions_info.py +0 -0
  96. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/load_api_docs.py +0 -0
  97. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/load_help_topics.py +0 -0
  98. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/load_source_code.py +0 -0
  99. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/api_docs_template.md +0 -0
  100. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/assistant_instructions_template.md +0 -0
  101. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/readme_template.md +0 -0
  102. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a1_what_is_kash.md +0 -0
  103. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a2_installation.md +0 -0
  104. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a3_getting_started.md +0 -0
  105. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a4_elements.md +0 -0
  106. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a5_tips_for_use_with_other_tools.md +0 -0
  107. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b0_philosophy_of_kash.md +0 -0
  108. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b2_workspace_and_file_formats.md +0 -0
  109. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b3_modern_shell_tool_recommendations.md +0 -0
  110. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b4_faq.md +0 -0
  111. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/warning.md +0 -0
  112. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs/markdown/welcome.md +0 -0
  113. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs_base/docs_base.py +0 -0
  114. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs_base/load_custom_command_info.py +0 -0
  115. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs_base/load_faqs.py +0 -0
  116. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs_base/load_recipe_snippets.py +0 -0
  117. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs_base/recipes/general_system_commands.sh +0 -0
  118. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs_base/recipes/python_dev_commands.sh +0 -0
  119. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/docs_base/recipes/tldr_standard_commands.sh +0 -0
  120. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/embeddings/cosine.py +0 -0
  121. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/embeddings/embeddings.py +0 -0
  122. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/embeddings/text_similarity.py +0 -0
  123. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/__init__.py +0 -0
  124. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/action_exec.py +0 -0
  125. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/action_registry.py +0 -0
  126. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/combiners.py +0 -0
  127. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/command_exec.py +0 -0
  128. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/command_registry.py +0 -0
  129. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/fetch_url_items.py +0 -0
  130. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/history.py +0 -0
  131. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/importing.py +0 -0
  132. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/precondition_checks.py +0 -0
  133. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/precondition_registry.py +0 -0
  134. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/preconditions.py +0 -0
  135. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/resolve_args.py +0 -0
  136. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec/runtime_settings.py +0 -0
  137. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec_model/__init__.py +0 -0
  138. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec_model/args_model.py +0 -0
  139. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec_model/commands_model.py +0 -0
  140. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec_model/script_model.py +0 -0
  141. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/exec_model/shell_model.py +0 -0
  142. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/file_storage/__init__.py +0 -0
  143. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/file_storage/file_store.py +0 -0
  144. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/file_storage/item_file_format.py +0 -0
  145. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/file_storage/metadata_dirs.py +0 -0
  146. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/file_storage/persisted_yaml.py +0 -0
  147. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/file_storage/store_cache_warmer.py +0 -0
  148. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/file_storage/store_filenames.py +0 -0
  149. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/__init__.py +0 -0
  150. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/assistant.py +0 -0
  151. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/assistant_instructions.py +0 -0
  152. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/assistant_output.py +0 -0
  153. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/function_param_info.py +0 -0
  154. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/help_embeddings.py +0 -0
  155. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/help_lookups.py +0 -0
  156. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/help_pages.py +0 -0
  157. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/help_printing.py +0 -0
  158. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/help_types.py +0 -0
  159. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/recommended_commands.py +0 -0
  160. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/help/tldr_help.py +0 -0
  161. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/__init__.py +0 -0
  162. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/clean_headings.py +0 -0
  163. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/custom_sliding_transforms.py +0 -0
  164. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/fuzzy_parsing.py +0 -0
  165. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/init_litellm.py +0 -0
  166. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/llm_api_keys.py +0 -0
  167. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/llm_features.py +0 -0
  168. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/llm_messages.py +0 -0
  169. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/llm_names.py +0 -0
  170. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/llm_utils/llms.py +0 -0
  171. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/local_server/__init__.py +0 -0
  172. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/local_server/local_server.py +0 -0
  173. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/local_server/local_server_commands.py +0 -0
  174. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/local_server/local_server_routes.py +0 -0
  175. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/local_server/local_url_formatters.py +0 -0
  176. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/local_server/port_tools.py +0 -0
  177. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/local_server/rich_html_template.py +0 -0
  178. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/mcp/__init__.py +0 -0
  179. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/mcp/mcp_cli.py +0 -0
  180. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/mcp/mcp_main.py +0 -0
  181. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_commands.py +0 -0
  182. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_routes.py +0 -0
  183. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_sse.py +0 -0
  184. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_stdio.py +0 -0
  185. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/__init__.py +0 -0
  186. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/audio_processing.py +0 -0
  187. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/media_cache.py +0 -0
  188. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/media_services.py +0 -0
  189. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/media_tools.py +0 -0
  190. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/services/local_file_media.py +0 -0
  191. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/timestamp_citations.py +0 -0
  192. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/transcription_deepgram.py +0 -0
  193. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/transcription_format.py +0 -0
  194. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/media_base/transcription_whisper.py +0 -0
  195. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/__init__.py +0 -0
  196. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/assistant_response_model.py +0 -0
  197. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/compound_actions_model.py +0 -0
  198. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/concept_model.py +0 -0
  199. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/exec_model.py +0 -0
  200. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/graph_model.py +0 -0
  201. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/items_model.py +0 -0
  202. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/language_list.py +0 -0
  203. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/llm_actions_model.py +0 -0
  204. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/media_model.py +0 -0
  205. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/operations_model.py +0 -0
  206. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/params_model.py +0 -0
  207. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/paths_model.py +0 -0
  208. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/model/preconditions_model.py +0 -0
  209. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/__init__.py +0 -0
  210. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/completions/completion_scoring.py +0 -0
  211. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/completions/completion_types.py +0 -0
  212. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/completions/shell_completions.py +0 -0
  213. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/file_icons/color_for_format.py +0 -0
  214. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/file_icons/nerd_icons.py +0 -0
  215. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/input/__init__.py +0 -0
  216. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/input/input_prompts.py +0 -0
  217. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/input/inquirer_settings.py +0 -0
  218. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/input/param_inputs.py +0 -0
  219. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/input/shell_confirm.py +0 -0
  220. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/output/__init__.py +0 -0
  221. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/output/kerm_code_utils.py +0 -0
  222. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/output/kerm_codes.py +0 -0
  223. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/output/kmarkdown.py +0 -0
  224. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/output/shell_formatting.py +0 -0
  225. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/shell_main.py +0 -0
  226. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/ui/__init__.py +0 -0
  227. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/ui/shell_results.py +0 -0
  228. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/ui/shell_syntax.py +0 -0
  229. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/utils/exception_printing.py +0 -0
  230. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/utils/native_utils.py +0 -0
  231. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/utils/shell_function_wrapper.py +0 -0
  232. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/shell/version.py +0 -0
  233. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/__init__.py +0 -0
  234. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/__init__.py +0 -0
  235. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/format_utils.py +0 -0
  236. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/import_utils.py +0 -0
  237. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/lazyobject.py +0 -0
  238. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/obj_replace.py +0 -0
  239. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/parse_docstring.py +0 -0
  240. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/parse_key_vals.py +0 -0
  241. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/parse_shell_args.py +0 -0
  242. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/stack_traces.py +0 -0
  243. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/task_stack.py +0 -0
  244. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/type_utils.py +0 -0
  245. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/uniquifier.py +0 -0
  246. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/url.py +0 -0
  247. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/common/url_slice.py +0 -0
  248. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/errors.py +0 -0
  249. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_formats/chat_format.py +0 -0
  250. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/__init__.py +0 -0
  251. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/dir_info.py +0 -0
  252. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_ext.py +0 -0
  253. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_formats.py +0 -0
  254. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_formats_model.py +0 -0
  255. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_sort_filter.py +0 -0
  256. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_walk.py +0 -0
  257. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/filename_parsing.py +0 -0
  258. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/ignore_files.py +0 -0
  259. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/mtime_cache.py +0 -0
  260. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/file_utils/path_utils.py +0 -0
  261. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/lang_utils/__init__.py +0 -0
  262. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/lang_utils/capitalization.py +0 -0
  263. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/rich_custom/__init__.py +0 -0
  264. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/rich_custom/ansi_cell_len.py +0 -0
  265. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_char_transform.py +0 -0
  266. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_indent.py +0 -0
  267. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_markdown_fork.py +0 -0
  268. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/text_handling/doc_normalization.py +0 -0
  269. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdown_utils.py +0 -0
  270. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdownify_utils.py +0 -0
  271. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/utils/text_handling/unified_diffs.py +0 -0
  272. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/canon_url.py +0 -0
  273. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/dir_store.py +0 -0
  274. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/file_cache_utils.py +0 -0
  275. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/file_processing.py +0 -0
  276. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/local_file_cache.py +0 -0
  277. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/web_extract.py +0 -0
  278. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/web_extract_justext.py +0 -0
  279. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/web_extract_readabilipy.py +0 -0
  280. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/web_fetch.py +0 -0
  281. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_content/web_page_model.py +0 -0
  282. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/__init__.py +0 -0
  283. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/simple_webpage.py +0 -0
  284. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/tabbed_webpage.py +0 -0
  285. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/template_render.py +0 -0
  286. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/base_webpage.html.jinja +0 -0
  287. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/toc_scripts.js.jinja +0 -0
  288. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/content_styles.css.jinja +0 -0
  289. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/explain_view.html.jinja +0 -0
  290. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/item_view.html.jinja +0 -0
  291. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/simple_webpage.html.jinja +0 -0
  292. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/web_gen/templates/tabbed_webpage.html.jinja +0 -0
  293. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/workspaces/__init__.py +0 -0
  294. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/workspaces/param_state.py +0 -0
  295. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/workspaces/selections.py +0 -0
  296. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/workspaces/source_items.py +0 -0
  297. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/workspaces/workspace_dirs.py +0 -0
  298. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/workspaces/workspace_output.py +0 -0
  299. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/workspaces/workspace_registry.py +0 -0
  300. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/workspaces/workspaces.py +0 -0
  301. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/command_nl_utils.py +0 -0
  302. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/custom_shell.py +0 -0
  303. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/customize_prompt.py +0 -0
  304. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/load_into_xonsh.py +0 -0
  305. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/shell_load_commands.py +0 -0
  306. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/shell_which.py +0 -0
  307. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_completers.py +0 -0
  308. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_env.py +0 -0
  309. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_keybindings.py +0 -0
  310. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_modern_tools.py +0 -0
  311. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_ranking_completer.py +0 -0
  312. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xontrib/fnm.py +0 -0
  313. {kash_shell-0.3.20 → kash_shell-0.3.21}/src/kash/xontrib/kash_extension.py +0 -0
  314. {kash_shell-0.3.20 → kash_shell-0.3.21}/tests/test_shell.py +0 -0
@@ -1,5 +1,5 @@
1
1
  # Changes here will be overwritten by Copier. Do not edit manually.
2
- _commit: v0.2.13
2
+ _commit: v0.2.14
3
3
  _src_path: gh:jlevy/simple-modern-uv
4
4
  package_author_email: joshua@cal.berkeley.edu
5
5
  package_author_name: Joshua Levy
@@ -3,11 +3,14 @@ description: General Guidelines
3
3
  globs:
4
4
  alwaysApply: true
5
5
  ---
6
- # General Responses
6
+ # Assistant Rules
7
7
 
8
- Remember you are a senior engineer and have a serious responsibility to be clear,
9
- factual, think step by step and be systematic, express expert opinion, and make use of
10
- the user's attention wisely.
8
+ **Your fundamental responsibility:** Remember you are a senior engineer and have a
9
+ serious responsibility to be clear, factual, think step by step and be systematic,
10
+ express expert opinion, and make use of the user's attention wisely.
11
+
12
+ **Rules must be followed:** It is your responsibility to carefully read these rules as
13
+ well as Python or other language-specific rules included here.
11
14
 
12
15
  Therefore:
13
16
 
@@ -22,8 +25,8 @@ Therefore:
22
25
  it. It's your responsibility to suggest approaches that lead to better, simpler
23
26
  solutions.
24
27
 
25
- - Give thoughtful opinions on better/worse approaches, but never say "great idea!"
26
- or "good job" or other non-essential banter or encouragement.
28
+ - Give thoughtful opinions on better/worse approaches, but NEVER say "great idea!"
29
+ or "good job" or other compliments, encouragement, or non-essential banter.
27
30
  Your job is to give expert opinions and to solve problems, not to motivate the user.
28
31
 
29
32
  - Avoid gratuitous enthusiasm or generalizations.
@@ -50,18 +53,20 @@ Therefore:
50
53
  this is meaningless to anyone reading the code later.
51
54
  (Instead, describe in your message to the user any other contextual information.)
52
55
 
53
- - DO NOT use fancy headings like "===== STEP 1: ... =====" in comments
56
+ - DO NOT use fancy or needlessly decorated headings like "===== MIGRATION TOOLS ====="
57
+ in comments
54
58
 
55
- - DO NOT scatter numbered steps in comments.
59
+ - DO NOT number steps in comments.
56
60
  These are hard to maintain if the code changes.
57
- Wrong: "// Step 3: Fetch the data from the cache" Correct: "// Now fetch the data from
58
- the cache"
59
-
60
- ## Using Emojis
61
+ NEVER DO THIS: "// Step 3: Fetch the data from the cache"\
62
+ This is fine: "// Now fetch the data from the cache"
61
63
 
62
64
  - DO NOT use emojis or special unicode characters like ① or • or – or — in comments.
63
65
 
64
66
  - Use emojis in output if it enhances the clarity and can be done consistently.
65
67
  You may use ✔︎ and ✘ to indicate success and failure, and ∆ and ‼︎ for user-facing
66
68
  warnings and errors, for example, but be sure to do it consistently.
67
- But but do not use emojis gratuitously as it clutters the output.
69
+ DO NOT use emojis gratuitously in comments or output.
70
+ You may use then ONLY when they have clear meanings (like success or failure).
71
+ Unless the user says otherwise, avoid emojis and Unicode in comments as clutters the
72
+ output with little benefit.
@@ -90,18 +90,27 @@ Always use full type annotations, generics, and other modern practices.
90
90
  - Use strif's `atomic_output_file` context manager when writing files to ensure output
91
91
  files are written atomically.
92
92
 
93
- - Use `uv add` and `uv sync` as needed to add dependencies.
93
+ ## Use Modern Python Practices
94
+
95
+ - ALWAYS use `@override` decorators to override methods from base classes.
96
+ This is a modern Python practice and helps avoid bugs.
94
97
 
95
98
  ## Testing
96
99
 
97
- - Don't write one-off test code in extra files or within `if __name__ == "__main__":`
98
- blocks. Instead, for simple tests, create simple test functions in the original file
99
- below a `## Tests` comment.
100
- This keeps the tests clear and close to the code.
100
+ - For longer tests put them in a file like `tests/test_somename.py` in the `tests/`
101
+ directory (or `tests/module_name/test_somename.py` file for a submodule).
102
+
103
+ - For simple tests, prefer inline functions in the original code file below a `## Tests`
104
+ comment. This keeps the tests easy to maintain and close to the code.
105
+ Inline tests should NOT import pytest or pytest fixtures as we do not want runtime
106
+ dependency on pytest.
101
107
 
102
- - For longer tests `test_somename.py` in the `tests/` directory.
108
+ - DO NOT write one-off test code in extra files that are throwaway.
103
109
 
104
- - Then you can run such tests with `uv run python -s src/.../path/to/test`
110
+ - DO NOT put `if __name__ == "__main__":` just for quick testing.
111
+ Instead use the inline function tests and run them with `uv run pytest`.
112
+
113
+ - You can run such individual tests with `uv run pytest -s src/.../path/to/test`
105
114
 
106
115
  - Don't add docs to assertions unless it's not obvious what they're checking - the
107
116
  assertion appears in the stack trace.
@@ -109,16 +118,19 @@ Always use full type annotations, generics, and other modern practices.
109
118
  x is 5`. That is redundant.
110
119
  Just write `assert x == 5`.
111
120
 
121
+ - DO NOT write trivial or obvious tests that are evident directly from code, such as
122
+ assertions that confirm the value of a constant setting.
123
+
112
124
  - NEVER write `assert False`. If a test reaches an unexpected branch and must fail
113
125
  explicitly, `raise AssertionError("Explanation")` instead.
114
126
  This is best typical best practice in Python since assertions can be removed with
115
127
  optimization.
116
128
 
117
- - Don't use pytest fixtures like parameterized tests or expected exception decorators
129
+ - DO NOT use pytest fixtures like parameterized tests or expected exception decorators
118
130
  unless absolutely necessary in more complex tests.
119
- It is often far simpler to use simple assertions and put the checks inside the test.
120
- This is preferable because then we want simple tests in original source files but
121
- don't want pytest dependencies at runtime.
131
+ It is typically simpler to use simple assertions and put the checks inside the test.
132
+ This is also preferable because then simple tests have no explicit pytest dependencies
133
+ and can be placed in code anywhere.
122
134
 
123
135
  ## Types and Type Annotations
124
136
 
@@ -150,7 +162,7 @@ Always use full type annotations, generics, and other modern practices.
150
162
  binary = "binary"
151
163
  ```
152
164
 
153
- ## Guidelines for Formatting Literal strings
165
+ ## Guidelines for Literal Strings
154
166
 
155
167
  - For multi-line strings NEVER put multi-line strings flush against the left margin.
156
168
  ALWAYS use a `dedent()` function to make it more readable.
@@ -166,6 +178,22 @@ Always use full type annotations, generics, and other modern practices.
166
178
  """).strip()
167
179
  ```
168
180
 
181
+ ## Guidelines for Comments
182
+
183
+ - Comments should be EXPLANATORY: Explain *WHY* something is done a certain way and not
184
+ just *what* is done.
185
+
186
+ - Comments should be CONCISE: Remove all extraneous words.
187
+
188
+ - DO NOT use comments to state obvious things or repeat what is evident from the code.
189
+ Here is an example of a comment that SHOULD BE REMOVED because it simply repeats the
190
+ code, which is distracting and adds no value:
191
+ ```python
192
+ if self.failed == 0:
193
+ # All successful
194
+ return "All tasks finished successfully"
195
+ ```
196
+
169
197
  ## Guidelines for Docstrings
170
198
 
171
199
  - Here is an example of the correct style for docstrings:
@@ -233,3 +261,15 @@ Always use full type annotations, generics, and other modern practices.
233
261
  return self.paragraph.reassemble()
234
262
  ```
235
263
  In general, the user can just call the enclosed objects methods, reducing code bloat.
264
+
265
+ - If a function does not use a parameter, but it should still be present, you can use `#
266
+ pyright: ignore[reportUnusedParameter]` in a comment to suppress the linter warning.
267
+
268
+ ## Guidelines for Backward Compatibility
269
+
270
+ - When changing code in a library or general function, if a change to an API or library
271
+ will break backward compatibility, MENTION THIS to the user.
272
+
273
+ - DO NOT implement additional code for backward compatiblity (such as extra methods or
274
+ variable aliases or comments about backward compatibility) UNLESS the user has
275
+ confirmed that it is necessary.
@@ -56,7 +56,7 @@ jobs:
56
56
  # python-version: ${{ matrix.python-version }}
57
57
 
58
58
  - name: Install all dependencies
59
- run: uv sync --all-extras --dev
59
+ run: uv sync --all-extras
60
60
 
61
61
  - name: Run linting
62
62
  run: uv run python devtools/lint.py
@@ -33,7 +33,7 @@ jobs:
33
33
  run: uv python install
34
34
 
35
35
  - name: Install all dependencies
36
- run: uv sync --all-extras --dev
36
+ run: uv sync --all-extras
37
37
 
38
38
  - name: Run tests
39
39
  run: uv run pytest
@@ -45,3 +45,6 @@ jobs:
45
45
 
46
46
  - name: Publish to PyPI
47
47
  run: uv publish --trusted-publishing always
48
+ # Although uv is newer and faster, the "official" publishing option is the one from PyPA,
49
+ # which uses twine. If desired, replace `uv publish` with:
50
+ # uses: pypa/gh-action-pypi-publish@release/v1
@@ -9,7 +9,7 @@
9
9
  default: agent-rules install lint test
10
10
 
11
11
  install:
12
- uv sync --all-extras --dev
12
+ uv sync --all-extras
13
13
 
14
14
  lint:
15
15
  uv run python devtools/lint.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.20
3
+ Version: 0.3.21
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>
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
17
  Classifier: Typing :: Typed
18
18
  Requires-Python: <4.0,>=3.11
19
+ Requires-Dist: aiolimiter>=1.2.1
19
20
  Requires-Dist: anyio>=4.8.0
20
21
  Requires-Dist: audioop-lts>=0.2.1; python_version >= '3.13'
21
22
  Requires-Dist: cachetools>=5.5.2
@@ -50,6 +51,7 @@ Requires-Dist: pydantic>=2.10.6
50
51
  Requires-Dist: pydub>=0.25.1
51
52
  Requires-Dist: pygments>=2.19.1
52
53
  Requires-Dist: pyperclip>=1.9.0
54
+ Requires-Dist: pyrate-limiter>=3.7.0
53
55
  Requires-Dist: python-dotenv>=1.0.1
54
56
  Requires-Dist: python-magic-bin>=0.4.14; platform_system == 'Windows'
55
57
  Requires-Dist: python-magic>=0.4.27; platform_system == 'Linux' or platform_system == 'Darwin'
@@ -17,7 +17,7 @@ The `Makefile` simply offers shortcuts to `uv` commands for developer convenienc
17
17
 
18
18
  ```shell
19
19
  # First, install all dependencies and set up your virtual environment.
20
- # This simply runs `uv sync --all-extras --dev` to install all packages,
20
+ # This simply runs `uv sync --all-extras` to install all packages,
21
21
  # including dev dependencies and optional dependencies.
22
22
  make install
23
23
 
@@ -77,10 +77,12 @@ dependencies = [
77
77
  "pathspec>=0.12.1",
78
78
  "patch-ng>=1.18.1",
79
79
  "inquirerpy>=0.3.4",
80
- # LLM essentials:
80
+ # LLM and API essentials:
81
81
  "tiktoken>=0.9.0",
82
82
  "openai>=1.66.3",
83
83
  "litellm>=1.63.11",
84
+ "pyrate-limiter>=3.7.0",
85
+ "aiolimiter>=1.2.1",
84
86
  # Basic text handling and web scraping:
85
87
  "readabilipy>=0.3.0",
86
88
  "markdownify>=0.13.1",
@@ -223,6 +225,7 @@ reportMissingParameterType = false
223
225
  reportUnannotatedClassAttribute = false
224
226
  reportUninitializedInstanceVariable = false
225
227
  reportCallInDefaultInitializer = false
228
+ reportUntypedBaseClass = false
226
229
  # Make ignoring easier:
227
230
  reportIgnoreCommentWithoutRule = false
228
231
  reportUnnecessaryTypeIgnoreComment = false
@@ -139,14 +139,15 @@ web_light_translucent = SimpleNamespace(
139
139
  bg_header=hsl_to_hex("hsla(188, 42%, 70%, 0.2)"),
140
140
  bg_alt=hsl_to_hex("hsla(39, 24%, 90%, 0.3)"),
141
141
  bg_alt_solid=hsl_to_hex("hsla(39, 24%, 97%, 1)"),
142
- bg_selected=hsl_to_hex("hsla(188, 44%, 94%, 0.95)"),
142
+ bg_meta_solid=hsl_to_hex("hsla(39, 24%, 94%, 1)"),
143
+ bg_selected=hsl_to_hex("hsla(188, 21%, 94%, 0.9)"),
143
144
  text=hsl_to_hex("hsl(188, 39%, 11%)"),
144
145
  code=hsl_to_hex("hsl(44, 38%, 23%)"),
145
146
  border=hsl_to_hex("hsl(188, 8%, 50%)"),
146
147
  border_hint=hsl_to_hex("hsla(188, 8%, 72%, 0.3)"),
147
148
  border_accent=hsl_to_hex("hsla(305, 18%, 65%, 0.85)"),
148
149
  hover=hsl_to_hex("hsl(188, 12%, 84%)"),
149
- hover_bg=hsl_to_hex("hsla(188, 44%, 94%, 1)"),
150
+ hover_bg=hsl_to_hex("hsla(188, 18%, 97%, 1)"),
150
151
  hint=hsl_to_hex("hsl(188, 11%, 65%)"),
151
152
  hint_strong=hsl_to_hex("hsl(188, 11%, 46%)"),
152
153
  hint_gentle=hsl_to_hex("hsla(188, 11%, 65%, 0.2)"),
@@ -165,14 +166,15 @@ web_light_translucent = SimpleNamespace(
165
166
  web_dark_translucent = SimpleNamespace(
166
167
  primary=hsl_to_hex("hsl(188, 40%, 62%)"),
167
168
  primary_light=hsl_to_hex("hsl(188, 50%, 72%)"),
168
- secondary=hsl_to_hex("hsl(188, 12%, 65%)"),
169
- tertiary=hsl_to_hex("hsl(188, 7%, 40%)"),
169
+ secondary=hsl_to_hex("hsl(188, 12%, 70%)"),
170
+ tertiary=hsl_to_hex("hsl(188, 7%, 45%)"),
170
171
  bg=hsl_to_hex("hsla(220, 14%, 7%, 0.95)"),
171
172
  bg_solid=hsl_to_hex("hsl(220, 14%, 7%)"),
172
173
  bg_header=hsl_to_hex("hsla(188, 42%, 20%, 0.3)"),
173
174
  bg_alt=hsl_to_hex("hsla(220, 14%, 12%, 0.5)"),
174
- bg_alt_solid=hsl_to_hex("hsl(220, 14%, 12%)"),
175
- bg_selected=hsl_to_hex("hsla(188, 12%, 50%, 0.95)"),
175
+ bg_alt_solid=hsl_to_hex("hsl(220, 15%, 16%)"),
176
+ bg_meta_solid=hsl_to_hex("hsl(220, 14%, 25%)"),
177
+ bg_selected=hsl_to_hex("hsla(188, 13%, 33%, 0.95)"),
176
178
  text=hsl_to_hex("hsl(188, 10%, 90%)"),
177
179
  code=hsl_to_hex("hsl(44, 38%, 72%)"),
178
180
  border=hsl_to_hex("hsl(188, 8%, 25%)"),
@@ -277,6 +277,8 @@ EMOJI_HELP = "?"
277
277
 
278
278
  EMOJI_ACTION = "⛭"
279
279
 
280
+ EMOJI_TASK = "⚒"
281
+
280
282
  EMOJI_COMMAND = "⧁" # More ideas: ⦿⧁⧀⦿⦾⟐⦊⟡
281
283
 
282
284
  EMOJI_SHELL = "⦊"
@@ -165,48 +165,37 @@ works on readable text such as Markdown.
165
165
  This catches errors and allows you to find actions that might apply to a given selected
166
166
  set of items using `suggest_actions`.
167
167
 
168
- ### Programmatic Use
169
-
170
- Since commands and actions are really just Python functions.
171
-
172
- ### Useful Features
173
-
174
- Kash makes a few kinds of messy text manipulations easier:
175
-
176
- - Reusable LLM actions: A common kind of action is to invoke an LLM (like GPT-4o or o1)
177
- on a text item, with a given system and user prompt template.
178
- New LLM actions can be added with a few lines of Python by subclassing an action base
179
- class, typically `Action`, `CachedItemAction` (for any action that doesn't need to be
180
- rerun if it has the same single output), `CachedLLMAction` (if it also is performing
181
- an LLM-based transform), or `ChunkedLLMAction` (if it will be processing a document
182
- broken into <div class="chunk"> elements).
183
-
184
- - Sliding window transformations: LLMs can have trouble processing large inputs, not
185
- just because of context window and because they may make more mistakes when making
186
- lots of changes at once.
187
- Kash supports running actions in a sliding window across the document, then stitching
188
- the results back together when done.
189
-
190
- - Checking and enforcing changes: LLMs do not reliably do what they are asked to do.
191
- So a key part of making them useful is to save outputs at each step of the way and
192
- have a way to review their outputs or provide guardrails on what they can do with
193
- content.
194
-
195
- - Fine-grainded diffs with word tokens: Documents can be represented at the word level,
196
- using “word tokens” to represent words and normalized whitespace (word, sentence, and
197
- paragraph breaks, but not line breaks).
198
- This allows diffs of similar documents regardless of formatting.
199
- For example, it is possible to ask an LLM only to add paragraph breaks, then drop any
200
- other changes it makes to other words.
201
- You can use this intelligent matching of words to “backfill” specific content from one
202
- doc into an edited document, such as pulling timestamps from a full transcript back
203
- into an edited transcript or summary.
204
-
205
- - Paragraph and sentence operations: A lot of operations within actions should be done
206
- in chunks at the paragraph or sentence level.
207
- Kash offers simple tools to subdivide documents into paragraphs and sentences and
208
- these can be used together with sliding windows to process large documents.
209
-
210
- In addition, there are built-in kash commands that are part of the kash tool itself.
211
- These allow you to list items in the workspace, see or change the current selection,
212
- archive items, view logs, etc.
168
+ ### Programmatic Usage
169
+
170
+ Kash can be used entirely programmatically, so that actions are called just like
171
+ functions from Python, but the additional functionality of the items model, saving files
172
+ to a workspace, and so on, are all automatic.
173
+
174
+ This means you can use Kash to build your own CLI apps much more quickly.
175
+
176
+ For an example of this, see [textpress](https://github.com/jlevy/textpress), which wraps
177
+ quite a few kash actions to allow clean publishing of docx or PDF files on
178
+ [textpress.md](https://textpress.md/).
179
+
180
+ ### Utilities and Supporting Libraries
181
+
182
+ Kash includes a number of utility libraries to help with common tasks, either in the
183
+ base `kash-shell` package or or smaller dependencies:
184
+
185
+ - See [frontmatter-format](https://github.com/jlevy/frontmatter-format) for the spec and
186
+ implementation we use of frontmatter YAML format.
187
+
188
+ - See
189
+ [utils/file_utils](https://github.com/jlevy/kash/tree/main/src/kash/utils/file_utils)
190
+ for file format detection, conversion, filename handling, etc.
191
+
192
+ - See [chopdiff](https://github.com/jlevy/chopdiff) for a simple text doc data model
193
+ that includes sentences and paragraphs and fairly advanced diffing, filtered diffing,
194
+ and windowed transformations of text via LLM calls.
195
+
196
+ - See [clideps](https://github.com/jlevy/clideps) for utilities for helping with dot-env
197
+ files, API key setup, and dependency checks.
198
+
199
+ - See [utils/common](https://github.com/jlevy/kash/tree/main/src/kash/utils/common) the
200
+ rest of [utils/](https://github.com/jlevy/kash/tree/main/src/kash/utils) for a variety
201
+ of other general utilities.
@@ -105,7 +105,10 @@ def kash_action_class(cls: type[A]) -> type[A]:
105
105
 
106
106
 
107
107
  def _register_dynamic_action(
108
- action_cls: type[A], action_name: str, action_description: str, source_path: Path | None
108
+ action_cls: type[A],
109
+ action_name: str,
110
+ action_description: str,
111
+ source_path: Path | None,
109
112
  ) -> type[A]:
110
113
  # Set class fields for name and description for convenience.
111
114
  action_cls.name = action_name
@@ -206,6 +209,7 @@ def kash_action(
206
209
  run_per_item: bool | None = None,
207
210
  uses_selection: bool = True,
208
211
  interactive_input: bool = False,
212
+ live_output: bool = False,
209
213
  mcp_tool: bool = False,
210
214
  title_template: TitleTemplate = TitleTemplate("{title}"),
211
215
  llm_options: LLMOptions = LLMOptions(),
@@ -235,13 +239,17 @@ def kash_action(
235
239
  def decorator(orig_func: AF) -> AF:
236
240
  if hasattr(orig_func, "__action_class__"):
237
241
  log.warning(
238
- "Function `%s` is already decorated with `@kash_action`", orig_func.__name__
242
+ "Function `%s` is already decorated with `@kash_action`",
243
+ orig_func.__name__,
239
244
  )
240
245
  return orig_func
241
246
 
242
247
  # Inspect and sanity check the formal params.
243
248
  func_params = inspect_function_params(orig_func)
244
- if len(func_params) == 0 or func_params[0].effective_type not in (ActionInput, Item):
249
+ if len(func_params) == 0 or func_params[0].effective_type not in (
250
+ ActionInput,
251
+ Item,
252
+ ):
245
253
  raise InvalidDefinition(
246
254
  f"Decorator `@kash_action` requires exactly one positional parameter, "
247
255
  f"`input` of type `ActionInput` or `Item` on function `{orig_func.__name__}` but "
@@ -311,6 +319,7 @@ def kash_action(
311
319
  self.uses_selection = uses_selection
312
320
  self.output_type = output_type
313
321
  self.interactive_input = interactive_input
322
+ self.live_output = live_output
314
323
  self.mcp_tool = mcp_tool
315
324
  self.title_template = title_template
316
325
  self.llm_options = llm_options
@@ -332,8 +341,14 @@ def kash_action(
332
341
  kw_args[fp.name] = self.get_param(fp.name)
333
342
 
334
343
  if self.params:
335
- log.info("Action function param declarations:\n%s", fmt_lines(self.params))
336
- log.info("Action function param values:\n%s", self.param_value_summary_str())
344
+ log.info(
345
+ "Action function param declarations:\n%s",
346
+ fmt_lines(self.params),
347
+ )
348
+ log.info(
349
+ "Action function param values:\n%s",
350
+ self.param_value_summary_str(),
351
+ )
337
352
  else:
338
353
  log.info("Action function has no declared params")
339
354
 
@@ -68,7 +68,7 @@ def llm_transform_str(options: LLMOptions, input_str: str, check_no_results: boo
68
68
  diff_filter=options.diff_filter,
69
69
  ).reassemble()
70
70
  else:
71
- log.message(
71
+ log.info(
72
72
  "Running simple LLM transform action %s with model %s",
73
73
  options.op_name,
74
74
  options.model.litellm_name,
@@ -56,7 +56,7 @@ class ShellCallableAction:
56
56
 
57
57
  log.info("Action shell args: %s", shell_args)
58
58
  explicit_values = RawParamValues(shell_args.options)
59
- if not action.interactive_input:
59
+ if not action.interactive_input and not action.live_output:
60
60
  with get_console().status(f"Running action {action.name}…", spinner=SPINNER):
61
61
  result = run_action_with_shell_context(
62
62
  action_cls,
@@ -173,7 +173,7 @@ def llm_template_completion(
173
173
  )
174
174
 
175
175
  if check_no_results and is_no_results(result.content):
176
- log.message("No results for LLM transform, will ignore: %r", result.content)
176
+ log.info("No results for LLM transform, will ignore: %r", result.content)
177
177
  result.content = ""
178
178
 
179
179
  return result
@@ -270,6 +270,12 @@ class Action(ABC):
270
270
  Does this action ask for input interactively?
271
271
  """
272
272
 
273
+ live_output: bool = False
274
+ """
275
+ Does this action have live output (e.g., progress bars, spinners)?
276
+ If True, the shell should not show its own status spinner.
277
+ """
278
+
273
279
  mcp_tool: bool = False
274
280
  """
275
281
  If True, this action is published as an MCP tool.
@@ -28,6 +28,7 @@ from kash.config.text_styles import (
28
28
  STYLE_HINT,
29
29
  )
30
30
  from kash.shell.output.kmarkdown import KMarkdown
31
+ from kash.utils.rich_custom.multitask_status import MultiTaskStatus, StatusSettings
31
32
  from kash.utils.rich_custom.rich_indent import Indent
32
33
  from kash.utils.rich_custom.rich_markdown_fork import Markdown
33
34
 
@@ -80,6 +81,20 @@ def console_pager(use_pager: bool = True):
80
81
  PrintHooks.after_pager()
81
82
 
82
83
 
84
+ def multitask_status(
85
+ settings: StatusSettings | None = None, *, auto_summary: bool = True
86
+ ) -> MultiTaskStatus:
87
+ """
88
+ Create a `MultiTaskStatus` context manager for displaying multiple task progress
89
+ using the global shell console.
90
+ """
91
+ return MultiTaskStatus(
92
+ console=get_console(),
93
+ settings=settings,
94
+ auto_summary=auto_summary,
95
+ )
96
+
97
+
83
98
  null_style = rich.style.Style.null()
84
99
 
85
100