kash-shell 0.3.7__tar.gz → 0.3.8__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 (293) hide show
  1. {kash_shell-0.3.7 → kash_shell-0.3.8}/.env.template +1 -8
  2. {kash_shell-0.3.7 → kash_shell-0.3.8}/PKG-INFO +1 -1
  3. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/debug_commands.py +2 -1
  4. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/general_commands.py +26 -38
  5. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/logs_commands.py +2 -1
  6. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/model_commands.py +16 -14
  7. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/search_command.py +2 -2
  8. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/workspace/workspace_commands.py +1 -2
  9. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/logger.py +44 -35
  10. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/logger_basic.py +2 -1
  11. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/settings.py +23 -19
  12. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/setup.py +1 -1
  13. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/llm_transforms.py +1 -1
  14. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/file_storage/metadata_dirs.py +2 -2
  15. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/help_pages.py +1 -1
  16. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/help_printing.py +1 -2
  17. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/llm_utils/__init__.py +1 -0
  18. kash_shell-0.3.8/src/kash/llm_utils/llm_api_keys.py +39 -0
  19. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/mcp/mcp_cli.py +2 -2
  20. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/mcp/mcp_server_commands.py +8 -3
  21. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/media_base/services/local_file_media.py +2 -2
  22. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/media_base/speech_transcription.py +1 -1
  23. kash_shell-0.3.8/src/kash/shell/clideps/api_keys.py +99 -0
  24. kash_shell-0.3.7/src/kash/shell/input/collect_dotenv.py → kash_shell-0.3.8/src/kash/shell/clideps/dotenv_setup.py +39 -5
  25. {kash_shell-0.3.7/src/kash/config → kash_shell-0.3.8/src/kash/shell/clideps}/dotenv_utils.py +2 -1
  26. kash_shell-0.3.7/src/kash/shell/utils/sys_tool_deps.py → kash_shell-0.3.8/src/kash/shell/clideps/pkg_deps.py +36 -97
  27. kash_shell-0.3.8/src/kash/shell/clideps/platforms.py +11 -0
  28. kash_shell-0.3.8/src/kash/shell/clideps/terminal_features.py +56 -0
  29. kash_shell-0.3.8/src/kash/shell/output/shell_formatting.py +106 -0
  30. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/output/shell_output.py +1 -94
  31. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/utils/native_utils.py +11 -10
  32. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/file_formats.py +2 -2
  33. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/workspaces/workspace_output.py +2 -1
  34. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/workspaces/workspaces.py +9 -10
  35. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/load_into_xonsh.py +2 -2
  36. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/xonsh_modern_tools.py +5 -5
  37. {kash_shell-0.3.7 → kash_shell-0.3.8}/uv.lock +201 -204
  38. kash_shell-0.3.7/src/kash/config/api_keys.py +0 -109
  39. {kash_shell-0.3.7 → kash_shell-0.3.8}/.copier-answers.yml +0 -0
  40. {kash_shell-0.3.7 → kash_shell-0.3.8}/.github/workflows/ci.yml +0 -0
  41. {kash_shell-0.3.7 → kash_shell-0.3.8}/.github/workflows/publish.yml +0 -0
  42. {kash_shell-0.3.7 → kash_shell-0.3.8}/.gitignore +0 -0
  43. {kash_shell-0.3.7 → kash_shell-0.3.8}/LICENSE +0 -0
  44. {kash_shell-0.3.7 → kash_shell-0.3.8}/Makefile +0 -0
  45. {kash_shell-0.3.7 → kash_shell-0.3.8}/README.md +0 -0
  46. {kash_shell-0.3.7 → kash_shell-0.3.8}/development.md +0 -0
  47. {kash_shell-0.3.7 → kash_shell-0.3.8}/devtools/generate_readme.xsh +0 -0
  48. {kash_shell-0.3.7 → kash_shell-0.3.8}/devtools/lint.py +0 -0
  49. {kash_shell-0.3.7 → kash_shell-0.3.8}/devtools/profile_main.py +0 -0
  50. {kash_shell-0.3.7 → kash_shell-0.3.8}/pyproject.toml +0 -0
  51. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/__init__.py +0 -0
  52. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/__main__.py +0 -0
  53. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/__init__.py +0 -0
  54. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/assistant_chat.py +0 -0
  55. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/chat.py +0 -0
  56. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/format_markdown_template.py +0 -0
  57. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/markdownify.py +0 -0
  58. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/readability.py +0 -0
  59. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/show_webpage.py +0 -0
  60. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/strip_html.py +0 -0
  61. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/summarize_as_bullets.py +0 -0
  62. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/webpage_config.py +0 -0
  63. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/core/webpage_generate.py +0 -0
  64. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/meta/write_instructions.py +0 -0
  65. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/actions/meta/write_new_action.py +0 -0
  66. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/__init__.py +0 -0
  67. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/basic_file_commands.py +0 -0
  68. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/browser_commands.py +0 -0
  69. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/diff_commands.py +0 -0
  70. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/files_command.py +0 -0
  71. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/reformat_command.py +0 -0
  72. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/base/show_command.py +0 -0
  73. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/extras/utils_commands.py +0 -0
  74. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/help/assistant_commands.py +0 -0
  75. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/help/doc_commands.py +0 -0
  76. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/help/help_commands.py +0 -0
  77. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/help/logo.py +0 -0
  78. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/commands/workspace/selection_commands.py +0 -0
  79. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/concepts/concept_formats.py +0 -0
  80. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/concepts/cosine.py +0 -0
  81. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/concepts/embeddings.py +0 -0
  82. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/concepts/text_similarity.py +0 -0
  83. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/__init__.py +0 -0
  84. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/capture_output.py +0 -0
  85. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/colors.py +0 -0
  86. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/init.py +0 -0
  87. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/lazy_imports.py +0 -0
  88. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/logo.txt +0 -0
  89. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/server_config.py +0 -0
  90. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/suppress_warnings.py +0 -0
  91. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/config/text_styles.py +0 -0
  92. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/__init__.py +0 -0
  93. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/all_docs.py +0 -0
  94. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/load_actions_info.py +0 -0
  95. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/load_api_docs.py +0 -0
  96. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/load_help_topics.py +0 -0
  97. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/load_source_code.py +0 -0
  98. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/api_docs_template.md +0 -0
  99. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/assistant_instructions_template.md +0 -0
  100. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/readme_template.md +0 -0
  101. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/a1_what_is_kash.md +0 -0
  102. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/a2_installation.md +0 -0
  103. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/a3_getting_started.md +0 -0
  104. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/a4_elements.md +0 -0
  105. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/a5_tips_for_use_with_other_tools.md +0 -0
  106. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/b0_philosophy_of_kash.md +0 -0
  107. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/b1_kash_overview.md +0 -0
  108. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/b2_workspace_and_file_formats.md +0 -0
  109. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/b3_modern_shell_tool_recommendations.md +0 -0
  110. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/topics/b4_faq.md +0 -0
  111. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/warning.md +0 -0
  112. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs/markdown/welcome.md +0 -0
  113. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs_base/docs_base.py +0 -0
  114. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs_base/load_custom_command_info.py +0 -0
  115. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs_base/load_faqs.py +0 -0
  116. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs_base/load_recipe_snippets.py +0 -0
  117. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs_base/recipes/general_system_commands.ksh +0 -0
  118. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs_base/recipes/python_dev_commands.ksh +0 -0
  119. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/docs_base/recipes/tldr_standard_commands.ksh +0 -0
  120. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/__init__.py +0 -0
  121. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/action_decorators.py +0 -0
  122. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/action_exec.py +0 -0
  123. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/action_registry.py +0 -0
  124. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/combiners.py +0 -0
  125. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/command_exec.py +0 -0
  126. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/command_registry.py +0 -0
  127. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/fetch_url_metadata.py +0 -0
  128. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/history.py +0 -0
  129. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/precondition_checks.py +0 -0
  130. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/precondition_registry.py +0 -0
  131. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/preconditions.py +0 -0
  132. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/resolve_args.py +0 -0
  133. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec/shell_callable_action.py +0 -0
  134. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec_model/__init__.py +0 -0
  135. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec_model/args_model.py +0 -0
  136. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec_model/commands_model.py +0 -0
  137. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec_model/script_model.py +0 -0
  138. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/exec_model/shell_model.py +0 -0
  139. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/file_storage/__init__.py +0 -0
  140. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/file_storage/file_store.py +0 -0
  141. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/file_storage/item_file_format.py +0 -0
  142. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/file_storage/persisted_yaml.py +0 -0
  143. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/file_storage/store_cache_warmer.py +0 -0
  144. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/file_storage/store_filenames.py +0 -0
  145. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/__init__.py +0 -0
  146. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/assistant.py +0 -0
  147. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/assistant_instructions.py +0 -0
  148. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/assistant_output.py +0 -0
  149. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/docstring_utils.py +0 -0
  150. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/function_param_info.py +0 -0
  151. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/help_embeddings.py +0 -0
  152. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/help_lookups.py +0 -0
  153. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/help_types.py +0 -0
  154. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/recommended_commands.py +0 -0
  155. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/help/tldr_help.py +0 -0
  156. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/llm_utils/clean_headings.py +0 -0
  157. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/llm_utils/fuzzy_parsing.py +0 -0
  158. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/llm_utils/llm_completion.py +0 -0
  159. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/llm_utils/llm_messages.py +0 -0
  160. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/llm_utils/llm_names.py +0 -0
  161. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/llm_utils/llms.py +0 -0
  162. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/local_server/__init__.py +0 -0
  163. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/local_server/local_server.py +0 -0
  164. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/local_server/local_server_commands.py +0 -0
  165. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/local_server/local_server_routes.py +0 -0
  166. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/local_server/local_url_formatters.py +0 -0
  167. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/local_server/port_tools.py +0 -0
  168. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/local_server/rich_html_template.py +0 -0
  169. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/mcp/__init__.py +0 -0
  170. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/mcp/mcp_main.py +0 -0
  171. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/mcp/mcp_server_routes.py +0 -0
  172. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/mcp/mcp_server_sse.py +0 -0
  173. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/mcp/mcp_server_stdio.py +0 -0
  174. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/media_base/__init__.py +0 -0
  175. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/media_base/audio_processing.py +0 -0
  176. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/media_base/media_cache.py +0 -0
  177. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/media_base/media_services.py +0 -0
  178. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/media_base/media_tools.py +0 -0
  179. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/media_base/timestamp_citations.py +0 -0
  180. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/__init__.py +0 -0
  181. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/actions_model.py +0 -0
  182. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/assistant_response_model.py +0 -0
  183. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/compound_actions_model.py +0 -0
  184. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/graph_model.py +0 -0
  185. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/items_model.py +0 -0
  186. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/language_list.py +0 -0
  187. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/llm_actions_model.py +0 -0
  188. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/media_model.py +0 -0
  189. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/operations_model.py +0 -0
  190. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/params_model.py +0 -0
  191. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/paths_model.py +0 -0
  192. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/model/preconditions_model.py +0 -0
  193. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/__init__.py +0 -0
  194. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/completions/completion_scoring.py +0 -0
  195. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/completions/completion_types.py +0 -0
  196. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/completions/shell_completions.py +0 -0
  197. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/file_icons/color_for_format.py +0 -0
  198. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/file_icons/nerd_icons.py +0 -0
  199. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/input/__init__.py +0 -0
  200. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/input/input_prompts.py +0 -0
  201. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/input/inquirer_settings.py +0 -0
  202. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/input/param_inputs.py +0 -0
  203. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/input/shell_confirm.py +0 -0
  204. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/output/__init__.py +0 -0
  205. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/output/kerm_code_utils.py +0 -0
  206. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/output/kerm_codes.py +0 -0
  207. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/output/kmarkdown.py +0 -0
  208. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/shell_main.py +0 -0
  209. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/ui/__init__.py +0 -0
  210. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/ui/shell_results.py +0 -0
  211. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/ui/shell_syntax.py +0 -0
  212. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/utils/argparse_utils.py +0 -0
  213. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/utils/exception_printing.py +0 -0
  214. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/utils/osc_utils.py +0 -0
  215. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/utils/shell_function_wrapper.py +0 -0
  216. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/utils/terminal_images.py +0 -0
  217. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/shell/version.py +0 -0
  218. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/text_handling/custom_sliding_transforms.py +0 -0
  219. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/text_handling/doc_normalization.py +0 -0
  220. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/text_handling/markdown_util.py +0 -0
  221. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/text_handling/unified_diffs.py +0 -0
  222. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/__init__.py +0 -0
  223. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/__init__.py +0 -0
  224. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/atomic_var.py +0 -0
  225. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/format_utils.py +0 -0
  226. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/function_inspect.py +0 -0
  227. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/import_utils.py +0 -0
  228. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/lazyobject.py +0 -0
  229. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/obj_replace.py +0 -0
  230. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/parse_key_vals.py +0 -0
  231. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/parse_shell_args.py +0 -0
  232. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/stack_traces.py +0 -0
  233. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/string_replace.py +0 -0
  234. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/string_template.py +0 -0
  235. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/task_stack.py +0 -0
  236. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/type_utils.py +0 -0
  237. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/uniquifier.py +0 -0
  238. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/common/url.py +0 -0
  239. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/errors.py +0 -0
  240. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_formats/chat_format.py +0 -0
  241. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/__init__.py +0 -0
  242. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/dir_size.py +0 -0
  243. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/file_ext.py +0 -0
  244. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/file_formats_model.py +0 -0
  245. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/file_sort_filter.py +0 -0
  246. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/file_walk.py +0 -0
  247. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/filename_parsing.py +0 -0
  248. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/ignore_files.py +0 -0
  249. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/mtime_cache.py +0 -0
  250. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/file_utils/path_utils.py +0 -0
  251. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/lang_utils/__init__.py +0 -0
  252. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/lang_utils/capitalization.py +0 -0
  253. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/lang_utils/inflection.py +0 -0
  254. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/rich_custom/__init__.py +0 -0
  255. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/rich_custom/ansi_cell_len.py +0 -0
  256. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/rich_custom/rich_char_transform.py +0 -0
  257. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/rich_custom/rich_indent.py +0 -0
  258. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/utils/rich_custom/rich_markdown_fork.py +0 -0
  259. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/canon_url.py +0 -0
  260. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/dir_store.py +0 -0
  261. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/file_cache_utils.py +0 -0
  262. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/local_file_cache.py +0 -0
  263. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/web_extract.py +0 -0
  264. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/web_extract_justext.py +0 -0
  265. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/web_extract_readabilipy.py +0 -0
  266. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/web_fetch.py +0 -0
  267. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_content/web_page_model.py +0 -0
  268. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/__init__.py +0 -0
  269. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/tabbed_webpage.py +0 -0
  270. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/template_render.py +0 -0
  271. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/templates/base_styles.css.jinja +0 -0
  272. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/templates/base_webpage.html.jinja +0 -0
  273. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/templates/content_styles.css.jinja +0 -0
  274. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/templates/explain_view.html.jinja +0 -0
  275. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/templates/item_view.html.jinja +0 -0
  276. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/web_gen/templates/tabbed_webpage.html.jinja +0 -0
  277. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/workspaces/__init__.py +0 -0
  278. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/workspaces/param_state.py +0 -0
  279. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/workspaces/selections.py +0 -0
  280. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/workspaces/source_items.py +0 -0
  281. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/workspaces/workspace_importing.py +0 -0
  282. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/workspaces/workspace_registry.py +0 -0
  283. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/command_nl_utils.py +0 -0
  284. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/custom_shell.py +0 -0
  285. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/customize_prompt.py +0 -0
  286. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/shell_load_commands.py +0 -0
  287. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/shell_which.py +0 -0
  288. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/xonsh_completers.py +0 -0
  289. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/xonsh_env.py +0 -0
  290. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xonsh_custom/xonsh_ranking_completer.py +0 -0
  291. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xontrib/fnm.py +0 -0
  292. {kash_shell-0.3.7 → kash_shell-0.3.8}/src/kash/xontrib/kash_extension.py +0 -0
  293. {kash_shell-0.3.7 → kash_shell-0.3.8}/tests/test_shell.py +0 -0
@@ -1,14 +1,7 @@
1
1
  # Copy this template file to ~/.env or another parent directory and set these
2
2
  # values and any other environment variables you need.
3
3
 
4
- # Location of new workspaces. This can be "." to to default to wherever
5
- # you are working, or an absolute path to ensure the default location
6
- # for a new workspace is the same place.
7
- # KASH_WS_ROOT="."
8
- KASH_WS_ROOT="~/Documents/kash"
9
-
10
- # Location of the kash default "global" workspace.
11
- KASH_GLOBAL_WS="~/Documents/kash/global"
4
+ # See settings.py for optional KASH_* environment variables.
12
5
 
13
6
  # API Keys:
14
7
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.7
3
+ Version: 0.3.8
4
4
  Summary: The knowledge agent shell
5
5
  Project-URL: Repository, https://github.com/jlevy/kash-shell
6
6
  Author-email: Joshua Levy <joshua@cal.berkeley.edu>
@@ -12,7 +12,8 @@ from kash.help.function_param_info import annotate_param_info
12
12
  from kash.help.recommended_commands import RECOMMENDED_TLDR_COMMANDS
13
13
  from kash.model.params_model import Param
14
14
  from kash.shell.output.kerm_codes import IframePopover, TextTooltip
15
- from kash.shell.output.shell_output import PrintHooks, console_pager, cprint, format_name_and_value
15
+ from kash.shell.output.shell_formatting import format_name_and_value
16
+ from kash.shell.output.shell_output import PrintHooks, console_pager, cprint
16
17
  from kash.utils.errors import InvalidInput
17
18
 
18
19
  log = get_logger(__name__)
@@ -1,34 +1,32 @@
1
1
  from kash.commands.base.model_commands import list_apis, list_models
2
2
  from kash.commands.workspace.workspace_commands import list_params
3
- from kash.config.api_keys import (
4
- RECOMMENDED_APIS,
5
- Api,
6
- get_all_configured_models,
7
- load_dotenv_paths,
8
- print_api_key_setup,
9
- )
10
- from kash.config.dotenv_utils import env_var_is_set
11
3
  from kash.config.logger import get_logger
4
+ from kash.config.settings import RECOMMENDED_API_KEYS
12
5
  from kash.docs.all_docs import all_docs
13
6
  from kash.exec import kash_command
14
7
  from kash.help.tldr_help import tldr_refresh_cache
8
+ from kash.llm_utils.llm_api_keys import get_all_configured_models
15
9
  from kash.model.params_model import (
16
10
  DEFAULT_CAREFUL_LLM,
17
11
  DEFAULT_FAST_LLM,
18
12
  DEFAULT_STANDARD_LLM,
19
13
  DEFAULT_STRUCTURED_LLM,
20
14
  )
21
- from kash.shell.input.collect_dotenv import fill_missing_dotenv
15
+ from kash.shell.clideps.api_keys import (
16
+ ApiEnvKey,
17
+ load_dotenv_paths,
18
+ print_api_key_setup,
19
+ )
20
+ from kash.shell.clideps.dotenv_setup import interactive_dotenv_setup
21
+ from kash.shell.clideps.pkg_deps import pkg_check
22
+ from kash.shell.clideps.terminal_features import terminal_check
22
23
  from kash.shell.input.input_prompts import input_choice
24
+ from kash.shell.output.shell_formatting import format_name_and_value
23
25
  from kash.shell.output.shell_output import (
24
26
  PrintHooks,
25
27
  cprint,
26
- format_failure,
27
- format_name_and_value,
28
- format_success,
29
28
  print_h2,
30
29
  )
31
- from kash.shell.utils.sys_tool_deps import sys_tool_check, terminal_feature_check
32
30
  from kash.shell.version import get_full_version_name
33
31
  from kash.utils.errors import InvalidState
34
32
  from kash.workspaces.workspaces import current_ws
@@ -50,8 +48,8 @@ def self_check(brief: bool = False) -> None:
50
48
  Self-check kash setup, including termal settings, tools, and API keys.
51
49
  """
52
50
  if brief:
53
- terminal_feature_check().print_term_info()
54
- print_api_key_setup(once=False)
51
+ terminal_check().print_term_info()
52
+ print_api_key_setup(recommended_keys=RECOMMENDED_API_KEYS, once=False)
55
53
  check_system_tools(brief=brief)
56
54
  tldr_refresh_cache()
57
55
  try:
@@ -63,7 +61,7 @@ def self_check(brief: bool = False) -> None:
63
61
  else:
64
62
  version()
65
63
  cprint()
66
- terminal_feature_check().print_term_info()
64
+ terminal_check().print_term_info()
67
65
  cprint()
68
66
  list_apis()
69
67
  cprint()
@@ -86,28 +84,18 @@ def self_check(brief: bool = False) -> None:
86
84
  @kash_command
87
85
  def self_configure(all: bool = False, update: bool = False) -> None:
88
86
  """
89
- Interactively configure your .env file with recommended API keys.
90
-
91
- :param all: Configure all known API keys (instead of just recommended ones).
92
- :param update: Update values even if they are already set.
87
+ Interactively configure API keys and preferred models.
93
88
  """
94
89
 
90
+ if all:
91
+ api_keys = [key.value for key in ApiEnvKey]
92
+ else:
93
+ api_keys = RECOMMENDED_API_KEYS
95
94
  # Show APIs before starting.
96
95
  list_apis()
97
96
 
98
- apis = Api if all else RECOMMENDED_APIS
99
- keys = [api.value for api in apis]
100
- if not update:
101
- keys = [key for key in keys if not env_var_is_set(key)]
102
-
103
- cprint()
104
- print_h2("Configuring .env file")
105
- if keys:
106
- cprint(format_failure(f"API keys needed: {', '.join(keys)}"))
107
- fill_missing_dotenv(keys)
108
- reload_env()
109
- else:
110
- cprint(format_success("All requested API keys are set!"))
97
+ interactive_dotenv_setup(api_keys, update=update)
98
+ reload_env()
111
99
 
112
100
  cprint()
113
101
  ws = current_ws()
@@ -170,15 +158,15 @@ def check_system_tools(warn_only: bool = False, brief: bool = False) -> None:
170
158
  :param brief: Print summary as a single line.
171
159
  """
172
160
  if warn_only:
173
- sys_tool_check().warn_if_missing()
161
+ pkg_check().warn_if_missing()
174
162
  else:
175
163
  if brief:
176
- cprint(sys_tool_check().status())
164
+ cprint(pkg_check().status())
177
165
  else:
178
166
  print_h2("Installed System Tools")
179
- cprint(sys_tool_check().formatted())
167
+ cprint(pkg_check().formatted())
180
168
  cprint()
181
- sys_tool_check().warn_if_missing()
169
+ pkg_check().warn_if_missing()
182
170
 
183
171
 
184
172
  @kash_command
@@ -190,7 +178,7 @@ def reload_env() -> None:
190
178
  env_paths = load_dotenv_paths()
191
179
  if env_paths:
192
180
  cprint("Reloaded environment variables")
193
- print_api_key_setup()
181
+ print_api_key_setup(RECOMMENDED_API_KEYS)
194
182
  else:
195
183
  raise InvalidState("No .env file found")
196
184
 
@@ -11,7 +11,8 @@ from kash.config.settings import (
11
11
  server_log_file_path,
12
12
  )
13
13
  from kash.exec import kash_command
14
- from kash.shell.output.shell_output import cprint, format_name_and_value, print_status
14
+ from kash.shell.output.shell_formatting import format_name_and_value
15
+ from kash.shell.output.shell_output import cprint, print_status
15
16
  from kash.shell.utils.native_utils import tail_file
16
17
  from kash.utils.common.format_utils import fmt_loc
17
18
 
@@ -1,17 +1,19 @@
1
1
  from flowmark import Wrap
2
2
  from rich.text import Text
3
3
 
4
- from kash.config.api_keys import Api
5
- from kash.config.dotenv_utils import env_var_is_set
6
- from kash.config.text_styles import format_success_emoji
7
4
  from kash.exec.command_registry import kash_command
8
- from kash.llm_utils import LLM
9
- from kash.shell.output.shell_output import (
10
- cprint,
5
+ from kash.llm_utils import LLM, api_for_model
6
+ from kash.shell.clideps.api_keys import ApiEnvKey
7
+ from kash.shell.clideps.dotenv_utils import env_var_is_set
8
+ from kash.shell.output.shell_formatting import (
11
9
  format_failure,
12
10
  format_name_and_value,
13
11
  format_success,
12
+ format_success_emoji,
14
13
  format_success_or_failure,
14
+ )
15
+ from kash.shell.output.shell_output import (
16
+ cprint,
15
17
  print_h2,
16
18
  )
17
19
 
@@ -23,11 +25,11 @@ def list_models() -> None:
23
25
  """
24
26
  print_h2("Models")
25
27
  for model in LLM.all_names():
26
- api = Api.for_model(model)
27
- have_key = bool(api and env_var_is_set(api.env_var))
28
+ api = api_for_model(model)
29
+ have_key = bool(api and env_var_is_set(api.value))
28
30
  if api:
29
31
  provider_msg = format_success(f"provider {api.name}")
30
- key_message = format_success_or_failure(have_key, f"{api.env_var}")
32
+ key_message = format_success_or_failure(have_key, f"{api.value}")
31
33
  else:
32
34
  provider_msg = format_failure("provider not recognized")
33
35
  key_message = format_failure("unknown API key")
@@ -46,11 +48,11 @@ def list_apis() -> None:
46
48
  List and check configuration for all APIs.
47
49
  """
48
50
  print_h2("API keys")
49
- for api in Api:
50
- emoji = format_success_emoji(env_var_is_set(api.env_var))
51
+ for api in ApiEnvKey:
52
+ emoji = format_success_emoji(env_var_is_set(api.value))
51
53
  message = (
52
- f"API key {api.env_var} found"
53
- if env_var_is_set(api.env_var)
54
- else f"API key {api.env_var} not found"
54
+ f"API key {api.value} found"
55
+ if env_var_is_set(api.value)
56
+ else f"API key {api.value} not found"
55
57
  )
56
58
  cprint(Text.assemble(emoji, format_name_and_value(api.name, message)))
@@ -3,8 +3,8 @@ from pathlib import Path
3
3
  from kash.config.logger import get_logger
4
4
  from kash.exec import assemble_path_args, kash_command
5
5
  from kash.exec_model.shell_model import ShellResult
6
+ from kash.shell.clideps.pkg_deps import Pkg, pkg_check
6
7
  from kash.shell.output.shell_output import cprint
7
- from kash.shell.utils.sys_tool_deps import SysTool, sys_tool_check
8
8
  from kash.utils.common.parse_shell_args import shell_quote
9
9
  from kash.utils.errors import InvalidState
10
10
 
@@ -33,7 +33,7 @@ def search(
33
33
  :param ignore_case: Ignore case when searching.
34
34
  :param verbose: Also print the ripgrep command line.
35
35
  """
36
- sys_tool_check().require(SysTool.ripgrep)
36
+ pkg_check().require(Pkg.ripgrep)
37
37
  from ripgrepy import RipGrepNotFound, Ripgrepy
38
38
 
39
39
  resolved_paths = assemble_path_args(*paths)
@@ -36,13 +36,12 @@ from kash.model.items_model import Item, ItemType
36
36
  from kash.model.params_model import GLOBAL_PARAMS
37
37
  from kash.model.paths_model import StorePath, fmt_store_path
38
38
  from kash.shell.input.param_inputs import input_param_name, input_param_value
39
+ from kash.shell.output.shell_formatting import format_name_and_description, format_name_and_value
39
40
  from kash.shell.output.shell_output import (
40
41
  PrintHooks,
41
42
  Wrap,
42
43
  console_pager,
43
44
  cprint,
44
- format_name_and_description,
45
- format_name_and_value,
46
45
  print_h2,
47
46
  print_h3,
48
47
  print_status,
@@ -12,7 +12,6 @@ from pathlib import Path
12
12
  from typing import IO, Any, cast
13
13
 
14
14
  import rich
15
- from rich import reconfigure
16
15
  from rich._null_file import NULL_FILE
17
16
  from rich.console import Console
18
17
  from rich.logging import RichHandler
@@ -22,8 +21,12 @@ from strif import atomic_output_file, new_timestamped_uid
22
21
  from typing_extensions import override
23
22
 
24
23
  import kash.config.suppress_warnings # noqa: F401
25
- from kash.config.logger_basic import basic_file_handler
26
- from kash.config.settings import GLOBAL_LOGS_DIR, LogLevel, get_global_kash_dir, global_settings
24
+ from kash.config.logger_basic import basic_file_handler, basic_stderr_handler
25
+ from kash.config.settings import (
26
+ LogLevel,
27
+ get_system_logs_dir,
28
+ global_settings,
29
+ )
27
30
  from kash.config.text_styles import (
28
31
  EMOJI_ERROR,
29
32
  EMOJI_SAVED,
@@ -48,9 +51,9 @@ class LogSettings:
48
51
  log_file_path: Path
49
52
 
50
53
 
51
- _log_base = get_global_kash_dir()
54
+ _log_dir = get_system_logs_dir()
52
55
  """
53
- Parent of the "logs" directory. Initially the global kash data root.
56
+ Parent of the "logs" directory. Initially the global kash workspace.
54
57
  """
55
58
 
56
59
 
@@ -72,14 +75,14 @@ def make_valid_log_name(name: str) -> str:
72
75
 
73
76
 
74
77
  def _read_log_settings() -> LogSettings:
75
- global _log_base, _log_name
78
+ global _log_dir, _log_name
76
79
  return LogSettings(
77
80
  log_console_level=global_settings().console_log_level,
78
81
  log_file_level=global_settings().file_log_level,
79
- global_log_dir=GLOBAL_LOGS_DIR,
80
- log_dir=_log_base / "logs",
81
- log_objects_dir=_log_base / "logs" / "objects" / _log_name,
82
- log_file_path=_log_base / "logs" / f"{_log_name}.log",
82
+ global_log_dir=get_system_logs_dir(),
83
+ log_dir=_log_dir,
84
+ log_objects_dir=_log_dir / "objects" / _log_name,
85
+ log_file_path=_log_dir / f"{_log_name}.log",
83
86
  )
84
87
 
85
88
 
@@ -102,7 +105,7 @@ def reset_log_root(log_root: Path | None = None, log_name: str | None = None):
102
105
  """
103
106
  global _log_lock, _log_base, _log_name
104
107
  with _log_lock:
105
- _log_base = log_root or get_global_kash_dir()
108
+ _log_base = log_root or get_system_logs_dir()
106
109
  _log_name = make_valid_log_name(log_name or LOG_NAME_GLOBAL)
107
110
  reload_rich_logging_setup()
108
111
 
@@ -125,9 +128,6 @@ def get_theme():
125
128
  return Theme(RICH_STYLES)
126
129
 
127
130
 
128
- reconfigure(theme=get_theme(), highlighter=get_highlighter())
129
-
130
-
131
131
  def get_console() -> Console:
132
132
  """
133
133
  Return the Rich global console, unless it is overridden by a
@@ -166,7 +166,7 @@ def record_console() -> Generator[Console, None, None]:
166
166
 
167
167
 
168
168
  _file_handler: logging.FileHandler
169
- _console_handler: RichHandler
169
+ _console_handler: logging.Handler
170
170
 
171
171
 
172
172
  def reload_rich_logging_setup():
@@ -210,20 +210,25 @@ def _do_logging_setup(log_settings: LogSettings):
210
210
  super().emit(record)
211
211
 
212
212
  global _console_handler
213
- _console_handler = PrefixedRichHandler(
214
- # For now we use the fixed global console for logging.
215
- # In the future we may want to add a way to have thread-local capture
216
- # of all system logs.
217
- console=rich.get_console(),
218
- level=log_settings.log_console_level.value,
219
- show_time=False,
220
- show_path=False,
221
- show_level=False,
222
- highlighter=get_highlighter(),
223
- markup=True,
224
- )
225
- _console_handler.setLevel(log_settings.log_console_level.value)
226
- _console_handler.setFormatter(Formatter("%(message)s"))
213
+
214
+ # Use the Rich stdout handler only on terminals, stderr for servers or non-interactive use.
215
+ if get_console().is_terminal:
216
+ _console_handler = PrefixedRichHandler(
217
+ # For now we use the fixed global console for logging.
218
+ # In the future we may want to add a way to have thread-local capture
219
+ # of all system logs.
220
+ console=rich.get_console(),
221
+ level=log_settings.log_console_level.value,
222
+ show_time=False,
223
+ show_path=False,
224
+ show_level=False,
225
+ highlighter=get_highlighter(),
226
+ markup=True,
227
+ )
228
+ _console_handler.setLevel(log_settings.log_console_level.value)
229
+ _console_handler.setFormatter(Formatter("%(message)s"))
230
+ else:
231
+ _console_handler = basic_stderr_handler(log_settings.log_console_level)
227
232
 
228
233
  # Manually adjust logging for a few packages, removing previous verbose default handlers.
229
234
 
@@ -337,17 +342,12 @@ class CustomLogger(logging.Logger):
337
342
  )
338
343
 
339
344
 
340
- logging.setLoggerClass(CustomLogger)
341
-
342
-
343
- reload_rich_logging_setup()
344
-
345
-
346
345
  def get_logger(name: str) -> CustomLogger:
347
346
  """
348
347
  Get a logger that's compatible with system logging but has our additional custom
349
348
  methods.
350
349
  """
350
+ init_rich_logging()
351
351
  logger = logging.getLogger(name)
352
352
  # print("Logger is", logger)
353
353
  return cast(CustomLogger, logger)
@@ -355,3 +355,12 @@ def get_logger(name: str) -> CustomLogger:
355
355
 
356
356
  def get_log_file_stream():
357
357
  return _file_handler.stream
358
+
359
+
360
+ @cache
361
+ def init_rich_logging():
362
+ rich.reconfigure(theme=get_theme(), highlighter=get_highlighter())
363
+
364
+ logging.setLoggerClass(CustomLogger)
365
+
366
+ reload_rich_logging_setup()
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import sys
2
3
  from logging import FileHandler, Formatter
3
4
  from pathlib import Path
4
5
 
@@ -16,7 +17,7 @@ def basic_file_handler(path: Path, level: LogLevel) -> logging.FileHandler:
16
17
 
17
18
 
18
19
  def basic_stderr_handler(level: LogLevel) -> logging.StreamHandler:
19
- handler = logging.StreamHandler()
20
+ handler = logging.StreamHandler(stream=sys.stderr)
20
21
  handler.setLevel(level.value)
21
22
  handler.setFormatter(Formatter("%(asctime)s %(levelname).1s %(name)s - %(message)s"))
22
23
  return handler
@@ -15,9 +15,12 @@ DOT_DIR = ".kash"
15
15
 
16
16
  GLOBAL_WS_NAME = "global"
17
17
 
18
-
19
- def get_global_kash_dir() -> Path:
20
- return Path(os.environ.get("KASH_DIR", "~/.local/kash")).expanduser().resolve()
18
+ RECOMMENDED_API_KEYS = [
19
+ "OPENAI_API_KEY",
20
+ "ANTHROPIC_API_KEY",
21
+ "DEEPGRAM_API_KEY",
22
+ "GROQ_API_KEY",
23
+ ]
21
24
 
22
25
 
23
26
  @overload
@@ -37,22 +40,27 @@ def path_from_env(env_name: str, default: Path | None) -> Path | None:
37
40
 
38
41
 
39
42
  def get_ws_root_dir() -> Path:
40
- return path_from_env("KASH_WS_ROOT", Path("."))
43
+ """Default root directory for kash workspaces."""
44
+ return path_from_env("KASH_WS_ROOT", Path("~/Kash").expanduser().resolve())
41
45
 
42
46
 
43
47
  def get_global_ws_dir() -> Path:
48
+ """Default global workspace directory."""
44
49
  kash_ws_dir = path_from_env("KASH_GLOBAL_WS", None)
45
50
  if kash_ws_dir:
46
51
  return kash_ws_dir
47
52
  else:
48
- docs_dir = Path("~/Documents").expanduser().resolve()
49
- if not docs_dir.exists():
50
- raise ValueError(
51
- f"Documents directory ({docs_dir}) does not exist; "
52
- "set KASH_GLOBAL_WS to specify a global workspace directory"
53
- )
54
- else:
55
- return docs_dir / APP_NAME / GLOBAL_WS_NAME
53
+ return get_ws_root_dir() / GLOBAL_WS_NAME
54
+
55
+
56
+ def get_system_logs_dir() -> Path:
57
+ """Default global and system logs directory (for server logs, etc)."""
58
+ return path_from_env("KASH_SYSTEM_LOGS_DIR", get_ws_root_dir() / "logs")
59
+
60
+
61
+ def get_system_cache_dir() -> Path:
62
+ """Default global and system cache directory (for global media, content, etc)."""
63
+ return path_from_env("KASH_SYSTEM_CACHE_DIR", get_ws_root_dir() / "cache")
56
64
 
57
65
 
58
66
  def get_mcp_ws_dir() -> Path | None:
@@ -70,10 +78,6 @@ def get_rcfile_path() -> Path:
70
78
  return Path("~/.kashrc").expanduser().resolve()
71
79
 
72
80
 
73
- GLOBAL_LOGS_DIR = get_global_kash_dir() / "logs"
74
-
75
-
76
- GLOBAL_CACHE_PATH = get_global_kash_dir() / "cache"
77
81
  MEDIA_CACHE_NAME = "media"
78
82
  CONTENT_CACHE_NAME = "content"
79
83
 
@@ -87,7 +91,7 @@ LOCAL_SERVER_PORT_START = 4470
87
91
  LOCAL_SERVER_PORTS_MAX = 30
88
92
 
89
93
 
90
- SERVER_LOG_FILE = str(GLOBAL_LOGS_DIR / "{name}_{port}.log")
94
+ SERVER_LOG_FILE = str(get_system_logs_dir() / "{name}_{port}.log")
91
95
 
92
96
 
93
97
  class LogLevel(Enum):
@@ -207,8 +211,8 @@ def server_log_file_path(name: str, port: int | str) -> Path:
207
211
  _settings = AtomicVar(
208
212
  Settings(
209
213
  # These default to the global but can be overridden by workspace settings.
210
- media_cache_dir=GLOBAL_CACHE_PATH / MEDIA_CACHE_NAME,
211
- content_cache_dir=GLOBAL_CACHE_PATH / CONTENT_CACHE_NAME,
214
+ media_cache_dir=get_system_cache_dir() / MEDIA_CACHE_NAME,
215
+ content_cache_dir=get_system_cache_dir() / CONTENT_CACHE_NAME,
212
216
  debug_assistant=True,
213
217
  default_editor="nano",
214
218
  file_log_level=LogLevel.info,
@@ -8,8 +8,8 @@ def setup(rich_logging: bool):
8
8
  """
9
9
  One-time setup of essential keys, directories, and configs. Idempotent.
10
10
  """
11
- from kash.config.api_keys import load_dotenv_paths
12
11
  from kash.config.logger import reload_rich_logging_setup
12
+ from kash.shell.clideps.dotenv_utils import load_dotenv_paths
13
13
  from kash.utils.common.stack_traces import add_stacktrace_handler
14
14
 
15
15
  if rich_logging:
@@ -4,7 +4,6 @@ from chopdiff.docs import DiffFilter, TextDoc
4
4
  from chopdiff.transforms import WindowSettings, accept_all, filtered_transform
5
5
  from flowmark import fill_markdown
6
6
 
7
- from kash.config.api_keys import load_dotenv_paths
8
7
  from kash.config.logger import get_logger
9
8
  from kash.llm_utils import LLMName
10
9
  from kash.llm_utils.fuzzy_parsing import strip_markdown_fence
@@ -12,6 +11,7 @@ from kash.llm_utils.llm_completion import llm_template_completion
12
11
  from kash.llm_utils.llm_messages import Message, MessageTemplate
13
12
  from kash.model.actions_model import LLMOptions
14
13
  from kash.model.items_model import Item, ItemType
14
+ from kash.shell.clideps.dotenv_utils import load_dotenv_paths
15
15
  from kash.utils.errors import InvalidInput
16
16
  from kash.utils.file_utils.file_formats_model import Format
17
17
 
@@ -7,7 +7,7 @@ from pathlib import Path
7
7
  from pydantic.dataclasses import dataclass
8
8
 
9
9
  from kash.config.logger import get_logger
10
- from kash.config.settings import CONTENT_CACHE_NAME, DOT_DIR, GLOBAL_CACHE_PATH, MEDIA_CACHE_NAME
10
+ from kash.config.settings import CONTENT_CACHE_NAME, DOT_DIR, MEDIA_CACHE_NAME, get_system_cache_dir
11
11
  from kash.file_storage.persisted_yaml import PersistedYaml
12
12
  from kash.model.paths_model import StorePath
13
13
  from kash.utils.common.format_utils import fmt_loc
@@ -62,7 +62,7 @@ class MetadataDirs:
62
62
  # in which case it is in the global cache path.
63
63
  @property
64
64
  def cache_dir(self) -> Path:
65
- return GLOBAL_CACHE_PATH if self.is_global_ws else StorePath(f"{DOT_DIR}/cache")
65
+ return get_system_cache_dir() if self.is_global_ws else StorePath(f"{DOT_DIR}/cache")
66
66
 
67
67
  @property
68
68
  def media_cache_dir(self) -> Path:
@@ -4,10 +4,10 @@ from kash.config.logger import get_logger
4
4
  from kash.config.text_styles import STYLE_HINT
5
5
  from kash.docs.all_docs import DocSelection, all_docs
6
6
  from kash.help.docstring_utils import parse_docstring
7
+ from kash.shell.output.shell_formatting import format_name_and_value
7
8
  from kash.shell.output.shell_output import (
8
9
  PrintHooks,
9
10
  cprint,
10
- format_name_and_value,
11
11
  print_h2,
12
12
  print_hrule,
13
13
  print_markdown,
@@ -12,11 +12,10 @@ from kash.llm_utils.llm_messages import Message
12
12
  from kash.model.actions_model import Action
13
13
  from kash.model.params_model import COMMON_SHELL_PARAMS, RUNTIME_ACTION_PARAMS, Param
14
14
  from kash.model.preconditions_model import Precondition
15
+ from kash.shell.output.shell_formatting import format_name_and_description, format_name_and_value
15
16
  from kash.shell.output.shell_output import (
16
17
  PrintHooks,
17
18
  cprint,
18
- format_name_and_description,
19
- format_name_and_value,
20
19
  print_help,
21
20
  print_markdown,
22
21
  )
@@ -1,5 +1,6 @@
1
1
  # flake8: noqa: F401
2
2
 
3
+ from kash.llm_utils.llm_api_keys import api_for_model, get_all_configured_models, have_key_for_model
3
4
  from kash.llm_utils.llm_completion import (
4
5
  LLMCompletionResult,
5
6
  llm_completion,
@@ -0,0 +1,39 @@
1
+ from __future__ import annotations
2
+
3
+ import litellm
4
+ from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
5
+
6
+ from kash.llm_utils.llm_names import LLMName
7
+ from kash.llm_utils.llms import LLM
8
+ from kash.shell.clideps.api_keys import ApiEnvKey
9
+ from kash.shell.clideps.dotenv_utils import env_var_is_set
10
+
11
+
12
+ def api_for_model(model: LLMName) -> ApiEnvKey | None:
13
+ """
14
+ Get the API key name for a model or None if not found.
15
+ """
16
+ try:
17
+ _model, custom_llm_provider, _dynamic_api_key, _api_base = get_llm_provider(model)
18
+ except litellm.exceptions.BadRequestError:
19
+ return None
20
+
21
+ return ApiEnvKey.for_provider(custom_llm_provider)
22
+
23
+
24
+ def have_key_for_model(model: LLMName) -> bool:
25
+ """
26
+ Do we have an API key for this model?
27
+ """
28
+ try:
29
+ api = api_for_model(model)
30
+ return bool(api and env_var_is_set(api))
31
+ except ValueError:
32
+ return False
33
+
34
+
35
+ def get_all_configured_models() -> list[LLMName]:
36
+ """
37
+ Get all models that have an API key.
38
+ """
39
+ return [model for model in LLM if have_key_for_model(model)]
@@ -10,7 +10,7 @@ import os
10
10
  from pathlib import Path
11
11
 
12
12
  from kash.config.logger_basic import basic_logging_setup
13
- from kash.config.settings import DEFAULT_MCP_SERVER_PORT, GLOBAL_LOGS_DIR, LogLevel
13
+ from kash.config.settings import DEFAULT_MCP_SERVER_PORT, LogLevel, get_system_logs_dir
14
14
  from kash.config.setup import setup
15
15
  from kash.mcp.mcp_main import McpMode, run_mcp_server
16
16
  from kash.mcp.mcp_server_sse import MCP_LOG_PREFIX
@@ -22,7 +22,7 @@ __version__ = get_version()
22
22
 
23
23
  DEFAULT_PROXY_URL = f"http://localhost:{DEFAULT_MCP_SERVER_PORT}/sse"
24
24
 
25
- LOG_PATH = GLOBAL_LOGS_DIR / f"{MCP_LOG_PREFIX}_cli.log"
25
+ LOG_PATH = get_system_logs_dir() / f"{MCP_LOG_PREFIX}_cli.log"
26
26
 
27
27
  basic_logging_setup(LOG_PATH, LogLevel.info)
28
28