kash-shell 0.3.18__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 (315) hide show
  1. {kash_shell-0.3.18 → kash_shell-0.3.21}/.copier-answers.yml +1 -1
  2. {kash_shell-0.3.18 → kash_shell-0.3.21}/.cursor/rules/general.mdc +18 -13
  3. {kash_shell-0.3.18 → kash_shell-0.3.21}/.cursor/rules/python.mdc +68 -23
  4. {kash_shell-0.3.18 → kash_shell-0.3.21}/.github/workflows/ci.yml +2 -2
  5. {kash_shell-0.3.18 → kash_shell-0.3.21}/.github/workflows/publish.yml +7 -4
  6. {kash_shell-0.3.18 → kash_shell-0.3.21}/Makefile +5 -2
  7. {kash_shell-0.3.18 → kash_shell-0.3.21}/PKG-INFO +4 -2
  8. {kash_shell-0.3.18 → kash_shell-0.3.21}/README.md +1 -1
  9. {kash_shell-0.3.18 → kash_shell-0.3.21}/development.md +13 -2
  10. {kash_shell-0.3.18 → kash_shell-0.3.21}/pyproject.toml +4 -1
  11. kash_shell-0.3.18/src/kash/actions/core/markdownify.py → kash_shell-0.3.21/src/kash/actions/core/markdownify_html.py +3 -6
  12. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/workspace/workspace_commands.py +10 -88
  13. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/colors.py +8 -6
  14. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/text_styles.py +2 -0
  15. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a1_what_is_kash.md +1 -1
  16. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b1_kash_overview.md +34 -45
  17. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/__init__.py +3 -0
  18. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/action_decorators.py +20 -5
  19. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/action_exec.py +2 -2
  20. kash_shell-0.3.18/src/kash/exec/fetch_url_metadata.py → kash_shell-0.3.21/src/kash/exec/fetch_url_items.py +42 -14
  21. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/llm_transforms.py +1 -1
  22. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/shell_callable_action.py +1 -1
  23. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/file_store.py +7 -1
  24. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/store_filenames.py +4 -0
  25. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/function_param_info.py +1 -1
  26. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_pages.py +1 -1
  27. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_printing.py +1 -1
  28. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_completion.py +1 -1
  29. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/actions_model.py +6 -0
  30. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/items_model.py +18 -3
  31. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/shell_output.py +15 -0
  32. kash_shell-0.3.21/src/kash/utils/api_utils/api_retries.py +305 -0
  33. kash_shell-0.3.21/src/kash/utils/api_utils/cache_requests_limited.py +84 -0
  34. kash_shell-0.3.21/src/kash/utils/api_utils/gather_limited.py +987 -0
  35. kash_shell-0.3.21/src/kash/utils/api_utils/progress_protocol.py +299 -0
  36. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/function_inspect.py +66 -1
  37. kash_shell-0.3.21/src/kash/utils/common/parse_docstring.py +347 -0
  38. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/testing.py +10 -7
  39. kash_shell-0.3.21/src/kash/utils/rich_custom/multitask_status.py +631 -0
  40. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/escape_html_tags.py +16 -11
  41. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdown_render.py +1 -0
  42. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_extract.py +34 -15
  43. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_page_model.py +10 -1
  44. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/base_styles.css.jinja +26 -20
  45. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/toc_styles.css.jinja +1 -1
  46. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/tooltip_scripts.js.jinja +171 -19
  47. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/tooltip_styles.css.jinja +23 -8
  48. kash_shell-0.3.21/tests/kash/utils/rich_custom/test_multitask_status.py +564 -0
  49. {kash_shell-0.3.18 → kash_shell-0.3.21}/uv.lock +269 -269
  50. kash_shell-0.3.18/src/kash/help/docstring_utils.py +0 -111
  51. {kash_shell-0.3.18 → kash_shell-0.3.21}/.env.template +0 -0
  52. {kash_shell-0.3.18 → kash_shell-0.3.21}/.gitignore +0 -0
  53. {kash_shell-0.3.18 → kash_shell-0.3.21}/LICENSE +0 -0
  54. {kash_shell-0.3.18 → kash_shell-0.3.21}/devtools/generate_readme.xsh +0 -0
  55. {kash_shell-0.3.18 → kash_shell-0.3.21}/devtools/lint.py +0 -0
  56. {kash_shell-0.3.18 → kash_shell-0.3.21}/devtools/profile_main.py +0 -0
  57. {kash_shell-0.3.18 → kash_shell-0.3.21}/installation.md +0 -0
  58. {kash_shell-0.3.18 → kash_shell-0.3.21}/publishing.md +0 -0
  59. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/__init__.py +0 -0
  60. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/__main__.py +0 -0
  61. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/__init__.py +0 -0
  62. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/assistant_chat.py +0 -0
  63. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/chat.py +0 -0
  64. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/format_markdown_template.py +0 -0
  65. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/minify_html.py +0 -0
  66. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/readability.py +0 -0
  67. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/render_as_html.py +0 -0
  68. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/show_webpage.py +0 -0
  69. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/strip_html.py +0 -0
  70. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/summarize_as_bullets.py +0 -0
  71. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/tabbed_webpage_config.py +0 -0
  72. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/tabbed_webpage_generate.py +0 -0
  73. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/meta/write_instructions.py +0 -0
  74. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/meta/write_new_action.py +0 -0
  75. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/__init__.py +0 -0
  76. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/basic_file_commands.py +0 -0
  77. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/browser_commands.py +0 -0
  78. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/debug_commands.py +0 -0
  79. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/diff_commands.py +0 -0
  80. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/files_command.py +0 -0
  81. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/general_commands.py +0 -0
  82. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/logs_commands.py +0 -0
  83. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/model_commands.py +0 -0
  84. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/reformat_command.py +0 -0
  85. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/search_command.py +0 -0
  86. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/show_command.py +0 -0
  87. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/extras/parse_uv_lock.py +0 -0
  88. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/extras/utils_commands.py +0 -0
  89. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/assistant_commands.py +0 -0
  90. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/doc_commands.py +0 -0
  91. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/help_commands.py +0 -0
  92. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/logo.py +0 -0
  93. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/welcome.py +0 -0
  94. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/workspace/selection_commands.py +0 -0
  95. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/__init__.py +0 -0
  96. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/capture_output.py +0 -0
  97. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/env_settings.py +0 -0
  98. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/init.py +0 -0
  99. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/lazy_imports.py +0 -0
  100. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/logger.py +0 -0
  101. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/logger_basic.py +0 -0
  102. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/logo.txt +0 -0
  103. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/server_config.py +0 -0
  104. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/settings.py +0 -0
  105. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/setup.py +0 -0
  106. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/suppress_warnings.py +0 -0
  107. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/__init__.py +0 -0
  108. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/all_docs.py +0 -0
  109. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/load_actions_info.py +0 -0
  110. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/load_api_docs.py +0 -0
  111. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/load_help_topics.py +0 -0
  112. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/load_source_code.py +0 -0
  113. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/api_docs_template.md +0 -0
  114. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/assistant_instructions_template.md +0 -0
  115. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/readme_template.md +0 -0
  116. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a2_installation.md +0 -0
  117. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a3_getting_started.md +0 -0
  118. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a4_elements.md +0 -0
  119. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a5_tips_for_use_with_other_tools.md +0 -0
  120. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b0_philosophy_of_kash.md +0 -0
  121. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b2_workspace_and_file_formats.md +0 -0
  122. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b3_modern_shell_tool_recommendations.md +0 -0
  123. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b4_faq.md +0 -0
  124. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/warning.md +0 -0
  125. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/welcome.md +0 -0
  126. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/docs_base.py +0 -0
  127. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/load_custom_command_info.py +0 -0
  128. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/load_faqs.py +0 -0
  129. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/load_recipe_snippets.py +0 -0
  130. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/recipes/general_system_commands.sh +0 -0
  131. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/recipes/python_dev_commands.sh +0 -0
  132. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/recipes/tldr_standard_commands.sh +0 -0
  133. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/embeddings/cosine.py +0 -0
  134. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/embeddings/embeddings.py +0 -0
  135. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/embeddings/text_similarity.py +0 -0
  136. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/action_registry.py +0 -0
  137. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/combiners.py +0 -0
  138. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/command_exec.py +0 -0
  139. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/command_registry.py +0 -0
  140. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/history.py +0 -0
  141. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/importing.py +0 -0
  142. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/precondition_checks.py +0 -0
  143. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/precondition_registry.py +0 -0
  144. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/preconditions.py +0 -0
  145. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/resolve_args.py +0 -0
  146. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/runtime_settings.py +0 -0
  147. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/__init__.py +0 -0
  148. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/args_model.py +0 -0
  149. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/commands_model.py +0 -0
  150. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/script_model.py +0 -0
  151. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/shell_model.py +0 -0
  152. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/__init__.py +0 -0
  153. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/item_file_format.py +0 -0
  154. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/metadata_dirs.py +0 -0
  155. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/persisted_yaml.py +0 -0
  156. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/store_cache_warmer.py +0 -0
  157. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/__init__.py +0 -0
  158. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/assistant.py +0 -0
  159. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/assistant_instructions.py +0 -0
  160. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/assistant_output.py +0 -0
  161. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_embeddings.py +0 -0
  162. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_lookups.py +0 -0
  163. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_types.py +0 -0
  164. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/recommended_commands.py +0 -0
  165. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/tldr_help.py +0 -0
  166. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/__init__.py +0 -0
  167. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/clean_headings.py +0 -0
  168. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/custom_sliding_transforms.py +0 -0
  169. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/fuzzy_parsing.py +0 -0
  170. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/init_litellm.py +0 -0
  171. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_api_keys.py +0 -0
  172. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_features.py +0 -0
  173. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_messages.py +0 -0
  174. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_names.py +0 -0
  175. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llms.py +0 -0
  176. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/__init__.py +0 -0
  177. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/local_server.py +0 -0
  178. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/local_server_commands.py +0 -0
  179. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/local_server_routes.py +0 -0
  180. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/local_url_formatters.py +0 -0
  181. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/port_tools.py +0 -0
  182. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/rich_html_template.py +0 -0
  183. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/__init__.py +0 -0
  184. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_cli.py +0 -0
  185. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_main.py +0 -0
  186. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_commands.py +0 -0
  187. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_routes.py +0 -0
  188. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_sse.py +0 -0
  189. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_stdio.py +0 -0
  190. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/__init__.py +0 -0
  191. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/audio_processing.py +0 -0
  192. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/media_cache.py +0 -0
  193. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/media_services.py +0 -0
  194. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/media_tools.py +0 -0
  195. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/services/local_file_media.py +0 -0
  196. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/timestamp_citations.py +0 -0
  197. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/transcription_deepgram.py +0 -0
  198. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/transcription_format.py +0 -0
  199. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/transcription_whisper.py +0 -0
  200. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/__init__.py +0 -0
  201. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/assistant_response_model.py +0 -0
  202. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/compound_actions_model.py +0 -0
  203. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/concept_model.py +0 -0
  204. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/exec_model.py +0 -0
  205. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/graph_model.py +0 -0
  206. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/language_list.py +0 -0
  207. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/llm_actions_model.py +0 -0
  208. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/media_model.py +0 -0
  209. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/operations_model.py +0 -0
  210. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/params_model.py +0 -0
  211. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/paths_model.py +0 -0
  212. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/preconditions_model.py +0 -0
  213. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/__init__.py +0 -0
  214. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/completions/completion_scoring.py +0 -0
  215. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/completions/completion_types.py +0 -0
  216. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/completions/shell_completions.py +0 -0
  217. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/file_icons/color_for_format.py +0 -0
  218. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/file_icons/nerd_icons.py +0 -0
  219. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/__init__.py +0 -0
  220. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/input_prompts.py +0 -0
  221. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/inquirer_settings.py +0 -0
  222. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/param_inputs.py +0 -0
  223. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/shell_confirm.py +0 -0
  224. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/__init__.py +0 -0
  225. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/kerm_code_utils.py +0 -0
  226. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/kerm_codes.py +0 -0
  227. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/kmarkdown.py +0 -0
  228. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/shell_formatting.py +0 -0
  229. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/shell_main.py +0 -0
  230. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/ui/__init__.py +0 -0
  231. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/ui/shell_results.py +0 -0
  232. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/ui/shell_syntax.py +0 -0
  233. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/utils/exception_printing.py +0 -0
  234. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/utils/native_utils.py +0 -0
  235. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/utils/shell_function_wrapper.py +0 -0
  236. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/version.py +0 -0
  237. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/__init__.py +0 -0
  238. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/__init__.py +0 -0
  239. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/format_utils.py +0 -0
  240. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/import_utils.py +0 -0
  241. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/lazyobject.py +0 -0
  242. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/obj_replace.py +0 -0
  243. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/parse_key_vals.py +0 -0
  244. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/parse_shell_args.py +0 -0
  245. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/stack_traces.py +0 -0
  246. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/task_stack.py +0 -0
  247. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/type_utils.py +0 -0
  248. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/uniquifier.py +0 -0
  249. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/url.py +0 -0
  250. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/url_slice.py +0 -0
  251. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/errors.py +0 -0
  252. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_formats/chat_format.py +0 -0
  253. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/__init__.py +0 -0
  254. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/dir_info.py +0 -0
  255. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_ext.py +0 -0
  256. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_formats.py +0 -0
  257. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_formats_model.py +0 -0
  258. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_sort_filter.py +0 -0
  259. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_walk.py +0 -0
  260. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/filename_parsing.py +0 -0
  261. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/ignore_files.py +0 -0
  262. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/mtime_cache.py +0 -0
  263. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/path_utils.py +0 -0
  264. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/lang_utils/__init__.py +0 -0
  265. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/lang_utils/capitalization.py +0 -0
  266. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/__init__.py +0 -0
  267. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/ansi_cell_len.py +0 -0
  268. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_char_transform.py +0 -0
  269. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_indent.py +0 -0
  270. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_markdown_fork.py +0 -0
  271. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/doc_normalization.py +0 -0
  272. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdown_utils.py +0 -0
  273. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdownify_utils.py +0 -0
  274. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/unified_diffs.py +0 -0
  275. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/canon_url.py +0 -0
  276. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/dir_store.py +0 -0
  277. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/file_cache_utils.py +0 -0
  278. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/file_processing.py +0 -0
  279. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/local_file_cache.py +0 -0
  280. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_extract_justext.py +0 -0
  281. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_extract_readabilipy.py +0 -0
  282. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_fetch.py +0 -0
  283. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/__init__.py +0 -0
  284. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/simple_webpage.py +0 -0
  285. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/tabbed_webpage.py +0 -0
  286. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/template_render.py +0 -0
  287. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/base_webpage.html.jinja +0 -0
  288. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/toc_scripts.js.jinja +0 -0
  289. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/content_styles.css.jinja +0 -0
  290. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/explain_view.html.jinja +0 -0
  291. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/item_view.html.jinja +0 -0
  292. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/simple_webpage.html.jinja +0 -0
  293. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/tabbed_webpage.html.jinja +0 -0
  294. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/__init__.py +0 -0
  295. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/param_state.py +0 -0
  296. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/selections.py +0 -0
  297. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/source_items.py +0 -0
  298. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/workspace_dirs.py +0 -0
  299. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/workspace_output.py +0 -0
  300. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/workspace_registry.py +0 -0
  301. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/workspaces.py +0 -0
  302. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/command_nl_utils.py +0 -0
  303. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/custom_shell.py +0 -0
  304. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/customize_prompt.py +0 -0
  305. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/load_into_xonsh.py +0 -0
  306. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/shell_load_commands.py +0 -0
  307. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/shell_which.py +0 -0
  308. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_completers.py +0 -0
  309. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_env.py +0 -0
  310. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_keybindings.py +0 -0
  311. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_modern_tools.py +0 -0
  312. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_ranking_completer.py +0 -0
  313. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xontrib/fnm.py +0 -0
  314. {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xontrib/kash_extension.py +0 -0
  315. {kash_shell-0.3.18 → 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.10
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.
@@ -16,10 +16,10 @@ Always use full type annotations, generics, and other modern practices.
16
16
 
17
17
  ## Project Setup and Developer Workflows
18
18
 
19
- - This project has a modern pyproject.toml file and a Makefile.
20
- Be sure you read and understand both.
19
+ - Important: BE SURE you read and understand the project setup by reading the
20
+ pyproject.toml file and the Makefile.
21
21
 
22
- - Use uv for running all code and managing dependencies.
22
+ - ALWAYS use uv for running all code and managing dependencies.
23
23
  Never use direct `pip` or `python` commands.
24
24
 
25
25
  - Use modern uv commands: `uv sync`, `uv run ...`, etc.
@@ -56,10 +56,13 @@ Always use full type annotations, generics, and other modern practices.
56
56
  - Be sure to resolve the pyright (basedpyright) linter errors as you develop and make
57
57
  changes.
58
58
 
59
- - If type checker errors are hard to resolve, check pyproject.toml to see if they are an
60
- excessively pedantic error.
61
- In special cases you may consider disabling it globally it in pyproject.toml but you
62
- *must ask for confirmation* from the user before doing this.
59
+ - If type checker errors are hard to resolve, you may add a comment `# pyright: ignore`
60
+ to disable Pyright warnings or errors but ONLY if you know they are not a real problem
61
+ and are difficult to fix.
62
+
63
+ - In special cases you may consider disabling it globally it in pyproject.toml but YOU
64
+ MUST ASK FOR CONFIRMATION from the user before globally disabling lint or type checker
65
+ rules.
63
66
 
64
67
  - Never change an existing comment, pydoc, or a log statement, unless it is directly
65
68
  fixing the issue you are changing, or the user has asked you to clean up the code.
@@ -87,18 +90,27 @@ Always use full type annotations, generics, and other modern practices.
87
90
  - Use strif's `atomic_output_file` context manager when writing files to ensure output
88
91
  files are written atomically.
89
92
 
90
- - 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.
91
97
 
92
98
  ## Testing
93
99
 
94
- - Don't write one-off test code in extra files or within `if __name__ == "__main__":`
95
- blocks. Instead, for simple tests, create simple test functions in the original file
96
- below a `## Tests` comment.
97
- 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.
107
+
108
+ - DO NOT write one-off test code in extra files that are throwaway.
98
109
 
99
- - For longer tests `test_somename.py` in the `tests/` directory.
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`.
100
112
 
101
- - Then you can run such tests with `uv run python -s src/.../path/to/test`
113
+ - You can run such individual tests with `uv run pytest -s src/.../path/to/test`
102
114
 
103
115
  - Don't add docs to assertions unless it's not obvious what they're checking - the
104
116
  assertion appears in the stack trace.
@@ -106,16 +118,19 @@ Always use full type annotations, generics, and other modern practices.
106
118
  x is 5`. That is redundant.
107
119
  Just write `assert x == 5`.
108
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
+
109
124
  - NEVER write `assert False`. If a test reaches an unexpected branch and must fail
110
125
  explicitly, `raise AssertionError("Explanation")` instead.
111
126
  This is best typical best practice in Python since assertions can be removed with
112
127
  optimization.
113
128
 
114
- - 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
115
130
  unless absolutely necessary in more complex tests.
116
- It is often far simpler to use simple assertions and put the checks inside the test.
117
- This is preferable because then we want simple tests in original source files but
118
- 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.
119
134
 
120
135
  ## Types and Type Annotations
121
136
 
@@ -147,7 +162,7 @@ Always use full type annotations, generics, and other modern practices.
147
162
  binary = "binary"
148
163
  ```
149
164
 
150
- ## Guidelines for Formatting Literal strings
165
+ ## Guidelines for Literal Strings
151
166
 
152
167
  - For multi-line strings NEVER put multi-line strings flush against the left margin.
153
168
  ALWAYS use a `dedent()` function to make it more readable.
@@ -163,6 +178,22 @@ Always use full type annotations, generics, and other modern practices.
163
178
  """).strip()
164
179
  ```
165
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
+
166
197
  ## Guidelines for Docstrings
167
198
 
168
199
  - Here is an example of the correct style for docstrings:
@@ -204,8 +235,9 @@ Always use full type annotations, generics, and other modern practices.
204
235
  - Docstrings *should* mention any key rationale or pitfalls when using the class or
205
236
  function.
206
237
 
207
- - Don't add pydocs that just repeat information obvious from the function, variable
208
- names, or concise description.
238
+ - Avoid obvious or repetitive docstrings.
239
+ Do NOT add pydocs that just repeat in English facts that are obvious from the function
240
+ name, variable name, or types.
209
241
  That is silly and obvious and makes the code longer for no reason.
210
242
 
211
243
  - Do NOT list args and return values if they're obvious.
@@ -220,11 +252,24 @@ Always use full type annotations, generics, and other modern practices.
220
252
 
221
253
  ## General Clean Coding Practices
222
254
 
223
- - When writing a class DO NOT blindly make delegation methods for consistency.
224
- For exmaple DO NOT write methods like this:
255
+ - Avoid writing trivial wrapper functions.
256
+ For example, when writing a class DO NOT blindly make delegation methods around public
257
+ member variables. DO NOT write methods like this:
225
258
  ```python
226
259
  def reassemble(self) -> str:
227
260
  """Call the original reassemble method."""
228
261
  return self.paragraph.reassemble()
229
262
  ```
230
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.
@@ -42,7 +42,7 @@ jobs:
42
42
  uses: astral-sh/setup-uv@v5
43
43
  with:
44
44
  # Update this as needed:
45
- version: "0.7.11"
45
+ version: "0.7.13"
46
46
  enable-cache: true
47
47
  python-version: ${{ matrix.python-version }}
48
48
 
@@ -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
@@ -25,7 +25,7 @@ jobs:
25
25
  - name: Install uv (official Astral action)
26
26
  uses: astral-sh/setup-uv@v5
27
27
  with:
28
- version: "0.7.11"
28
+ version: "0.7.13"
29
29
  enable-cache: true
30
30
  python-version: "3.12"
31
31
 
@@ -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
@@ -43,5 +43,8 @@ jobs:
43
43
  - name: Build package
44
44
  run: uv build
45
45
 
46
- - name: Publish to PyPI (using uv)
47
- uses: pypa/gh-action-pypi-publish@release/v1
46
+ - name: Publish to PyPI
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
@@ -18,7 +18,10 @@ test:
18
18
  uv run pytest
19
19
 
20
20
  test-full:
21
- ENABLE_TESTS_LLM=1 ENABLE_TESTS_INTEGRATION=1 uv run pytest
21
+ ENABLE_TESTS_ONLINE=1 ENABLE_TESTS_INTEGRATION=1 uv run pytest
22
+
23
+ run: install lint test
24
+ uv run kash
22
25
 
23
26
  upgrade:
24
27
  uv sync --upgrade --all-extras --dev
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.18
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'
@@ -115,7 +117,7 @@ the Python framework, a few core utilities, and the Kash command-line shell.
115
117
  Additional actions for handling more complex tasks like converting documents and
116
118
  transcribing, researching, or annotating videos, are in the
117
119
  [kash-docs](https://github.com/jlevy/kash-docs) and
118
- [kash-media](https://github.com/jlevy/kash-docs) packages, all available on PyPI and
120
+ [kash-media](https://github.com/jlevy/kash-media) packages, all available on PyPI and
119
121
  quick to install via uv.
120
122
 
121
123
  ### Key Concepts
@@ -43,7 +43,7 @@ the Python framework, a few core utilities, and the Kash command-line shell.
43
43
  Additional actions for handling more complex tasks like converting documents and
44
44
  transcribing, researching, or annotating videos, are in the
45
45
  [kash-docs](https://github.com/jlevy/kash-docs) and
46
- [kash-media](https://github.com/jlevy/kash-docs) packages, all available on PyPI and
46
+ [kash-media](https://github.com/jlevy/kash-media) packages, all available on PyPI and
47
47
  quick to install via uv.
48
48
 
49
49
  ### Key Concepts
@@ -17,11 +17,11 @@ 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
 
24
- # Run uv sync, lint, and test:
24
+ # Run uv sync, lint, and test (and also generate agent rules):
25
25
  make
26
26
 
27
27
  # Build wheel:
@@ -66,6 +66,17 @@ source .venv/bin/activate
66
66
 
67
67
  See [uv docs](https://docs.astral.sh/uv/) for details.
68
68
 
69
+ ## Agent Rules
70
+
71
+ See [.cursor/rules](.cursor/rules) for agent rules.
72
+ These are written for [Cursor](https://www.cursor.com/) but are also used by other
73
+ agents because the Makefile will generate `CLAUDE.md` and `AGENTS.md` from the same
74
+ rules.
75
+
76
+ ```shell
77
+ make agent-rules
78
+ ```
79
+
69
80
  ## IDE setup
70
81
 
71
82
  If you use VSCode or a fork like Cursor or Windsurf, you can install the following
@@ -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
@@ -11,13 +11,10 @@ from kash.web_content.web_extract_readabilipy import extract_text_readabilipy
11
11
  log = get_logger(__name__)
12
12
 
13
13
 
14
- @kash_action(
15
- precondition=is_url_resource | has_html_body,
16
- mcp_tool=True,
17
- )
18
- def markdownify(item: Item) -> Item:
14
+ @kash_action(precondition=is_url_resource | has_html_body, mcp_tool=True)
15
+ def markdownify_html(item: Item) -> Item:
19
16
  """
20
- Converts a URL or raw HTML item to Markdown, fetching with the content
17
+ Converts raw HTML or the URL of an HTML page to Markdown, fetching with the content
21
18
  cache if needed. Also uses readability to clean up the HTML.
22
19
  """
23
20
 
@@ -23,14 +23,12 @@ from kash.exec import (
23
23
  resolve_locator_arg,
24
24
  )
25
25
  from kash.exec.action_registry import get_all_actions_defaults
26
- from kash.exec.fetch_url_metadata import fetch_url_metadata
26
+ from kash.exec.fetch_url_items import fetch_url_item
27
27
  from kash.exec.precondition_checks import actions_matching_paths
28
28
  from kash.exec.precondition_registry import get_all_preconditions
29
- from kash.exec.preconditions import is_url_resource
30
29
  from kash.exec_model.shell_model import ShellResult
31
30
  from kash.local_server.local_url_formatters import local_url_formatter
32
31
  from kash.media_base import media_tools
33
- from kash.media_base.media_services import is_media_url
34
32
  from kash.model.items_model import Item, ItemType
35
33
  from kash.model.params_model import GLOBAL_PARAMS
36
34
  from kash.model.paths_model import StorePath, fmt_store_path
@@ -54,12 +52,11 @@ from kash.utils.common.format_utils import fmt_loc
54
52
  from kash.utils.common.obj_replace import remove_values
55
53
  from kash.utils.common.parse_key_vals import parse_key_value
56
54
  from kash.utils.common.type_utils import not_none
57
- from kash.utils.common.url import Url, is_url, parse_http_url
55
+ from kash.utils.common.url import Url
58
56
  from kash.utils.errors import InvalidInput
59
57
  from kash.utils.file_formats.chat_format import tail_chat_history
60
58
  from kash.utils.file_utils.dir_info import is_nonempty_dir
61
59
  from kash.utils.file_utils.file_formats_model import Format
62
- from kash.utils.text_handling.doc_normalization import can_normalize
63
60
  from kash.web_content.file_cache_utils import cache_file
64
61
  from kash.workspaces import (
65
62
  current_ws,
@@ -189,85 +186,6 @@ def cache_content(*urls_or_paths: str, refetch: bool = False) -> None:
189
186
  PrintHooks.spacer()
190
187
 
191
188
 
192
- @kash_command
193
- def download(*urls_or_paths: str, refetch: bool = False, no_format: bool = False) -> ShellResult:
194
- """
195
- Download a URL or resource. Uses cached content if available, unless `refetch` is true.
196
- Inputs can be URLs or paths to URL resources.
197
- Creates both resource and document versions for text content.
198
-
199
- :param no_format: If true, do not also normalize Markdown content.
200
- """
201
- ws = current_ws()
202
- saved_paths = []
203
-
204
- for url_or_path in urls_or_paths:
205
- locator = resolve_locator_arg(url_or_path)
206
- url: Url | None = None
207
-
208
- # Get the URL from the locator
209
- if not isinstance(locator, Path) and is_url(locator):
210
- url = Url(locator)
211
- elif isinstance(locator, StorePath):
212
- url_item = ws.load(locator)
213
- if is_url_resource(url_item):
214
- url = url_item.url
215
-
216
- if not url:
217
- raise InvalidInput(f"Not a URL or URL resource: {fmt_loc(locator)}")
218
-
219
- # Handle media URLs differently
220
- if is_media_url(url):
221
- log.message(
222
- "URL is a media URL, so adding as a resource and will cache media: %s", fmt_loc(url)
223
- )
224
- store_path = ws.import_item(url, as_type=ItemType.resource, reimport=refetch)
225
- saved_paths.append(store_path)
226
- media_tools.cache_media(url)
227
- else:
228
- # Cache the content first
229
- expiration_sec = 0 if refetch else None
230
- cache_result = cache_file(url, expiration_sec=expiration_sec)
231
- original_filename = Path(parse_http_url(url).path).name
232
- mime_type = cache_result.content.headers and cache_result.content.headers.mime_type
233
-
234
- # Create a resource item
235
- resource_item = Item.from_external_path(
236
- cache_result.content.path,
237
- ItemType.resource,
238
- url=url,
239
- mime_type=mime_type,
240
- original_filename=original_filename,
241
- )
242
- # For initial content, do not format or add frontmatter.
243
- store_path = ws.save(resource_item, no_frontmatter=True, no_format=True)
244
- saved_paths.append(store_path)
245
- select(store_path)
246
-
247
- # Also create a doc version for text content if we want to normalize formatting.
248
- if resource_item.format and can_normalize(resource_item.format) and not no_format:
249
- doc_item = Item.from_external_path(
250
- cache_result.content.path,
251
- ItemType.doc,
252
- url=url,
253
- mime_type=mime_type,
254
- original_filename=original_filename,
255
- )
256
- # Now use default formatting and frontmatter.
257
- doc_store_path = ws.save(doc_item)
258
- saved_paths.append(doc_store_path)
259
- select(doc_store_path)
260
-
261
- print_status(
262
- "Downloaded %s %s:\n%s",
263
- len(saved_paths),
264
- plural("item", len(saved_paths)),
265
- fmt_lines(saved_paths),
266
- )
267
-
268
- return ShellResult(show_selection=True)
269
-
270
-
271
189
  @kash_command
272
190
  def history(max: int = 30, raw: bool = False) -> None:
273
191
  """
@@ -536,10 +454,14 @@ def save_clipboard(
536
454
 
537
455
 
538
456
  @kash_command
539
- def fetch_metadata(*files_or_urls: str, refetch: bool = False) -> ShellResult:
457
+ def fetch_url(*files_or_urls: str, refetch: bool = False) -> ShellResult:
540
458
  """
541
- Fetch metadata for the given URLs or resources. Imports new URLs and saves back
542
- the fetched metadata for existing resources.
459
+ Fetch content and metadata for the given URLs or resources, saving to the
460
+ current workspace.
461
+
462
+ Imports new URLs and saves back the fetched metadata for existing resources.
463
+ Also saves a resource item with the content of the URL, either HTML, text, or
464
+ of any other type.
543
465
 
544
466
  Skips items that already have a title and description, unless `refetch` is true.
545
467
  Skips (with a warning) items that are not URL resources.
@@ -552,7 +474,7 @@ def fetch_metadata(*files_or_urls: str, refetch: bool = False) -> ShellResult:
552
474
  store_paths = []
553
475
  for locator in locators:
554
476
  try:
555
- fetched_item = fetch_url_metadata(locator, refetch=refetch)
477
+ fetched_item = fetch_url_item(locator, refetch=refetch)
556
478
  store_paths.append(fetched_item.store_path)
557
479
  except InvalidInput as e:
558
480
  log.warning(
@@ -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 = "⦊"
@@ -34,7 +34,7 @@ the Python framework, a few core utilities, and the Kash command-line shell.
34
34
  Additional actions for handling more complex tasks like converting documents and
35
35
  transcribing, researching, or annotating videos, are in the
36
36
  [kash-docs](https://github.com/jlevy/kash-docs) and
37
- [kash-media](https://github.com/jlevy/kash-docs) packages, all available on PyPI and
37
+ [kash-media](https://github.com/jlevy/kash-media) packages, all available on PyPI and
38
38
  quick to install via uv.
39
39
 
40
40
  ### Key Concepts