kash-shell 0.3.14__tar.gz → 0.3.16__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 (300) hide show
  1. {kash_shell-0.3.14 → kash_shell-0.3.16}/PKG-INFO +1 -1
  2. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/render_as_html.py +3 -1
  3. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/tabbed_webpage_generate.py +3 -1
  4. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/workspace/selection_commands.py +22 -0
  5. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/workspace/workspace_commands.py +11 -5
  6. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/colors.py +87 -13
  7. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/action_exec.py +23 -4
  8. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/precondition_registry.py +5 -3
  9. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/preconditions.py +7 -2
  10. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/resolve_args.py +2 -2
  11. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/file_storage/file_store.py +87 -54
  12. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/file_storage/item_file_format.py +0 -2
  13. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/local_server/local_server_routes.py +1 -1
  14. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/actions_model.py +5 -1
  15. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/items_model.py +39 -38
  16. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/completions/shell_completions.py +1 -1
  17. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/file_formats_model.py +15 -7
  18. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/text_handling/doc_normalization.py +7 -0
  19. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/simple_webpage.py +4 -1
  20. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/tabbed_webpage.py +8 -3
  21. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/templates/base_styles.css.jinja +48 -5
  22. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/templates/base_webpage.html.jinja +128 -0
  23. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/templates/item_view.html.jinja +4 -2
  24. kash_shell-0.3.16/src/kash/web_gen/templates/simple_webpage.html.jinja +48 -0
  25. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xontrib/kash_extension.py +3 -2
  26. {kash_shell-0.3.14 → kash_shell-0.3.16}/uv.lock +231 -195
  27. kash_shell-0.3.14/src/kash/web_gen/templates/simple_webpage.html.jinja +0 -24
  28. {kash_shell-0.3.14 → kash_shell-0.3.16}/.copier-answers.yml +0 -0
  29. {kash_shell-0.3.14 → kash_shell-0.3.16}/.env.template +0 -0
  30. {kash_shell-0.3.14 → kash_shell-0.3.16}/.github/workflows/ci.yml +0 -0
  31. {kash_shell-0.3.14 → kash_shell-0.3.16}/.github/workflows/publish.yml +0 -0
  32. {kash_shell-0.3.14 → kash_shell-0.3.16}/.gitignore +0 -0
  33. {kash_shell-0.3.14 → kash_shell-0.3.16}/LICENSE +0 -0
  34. {kash_shell-0.3.14 → kash_shell-0.3.16}/Makefile +0 -0
  35. {kash_shell-0.3.14 → kash_shell-0.3.16}/README.md +0 -0
  36. {kash_shell-0.3.14 → kash_shell-0.3.16}/development.md +0 -0
  37. {kash_shell-0.3.14 → kash_shell-0.3.16}/devtools/generate_readme.xsh +0 -0
  38. {kash_shell-0.3.14 → kash_shell-0.3.16}/devtools/lint.py +0 -0
  39. {kash_shell-0.3.14 → kash_shell-0.3.16}/devtools/profile_main.py +0 -0
  40. {kash_shell-0.3.14 → kash_shell-0.3.16}/installation.md +0 -0
  41. {kash_shell-0.3.14 → kash_shell-0.3.16}/publishing.md +0 -0
  42. {kash_shell-0.3.14 → kash_shell-0.3.16}/pyproject.toml +0 -0
  43. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/__init__.py +0 -0
  44. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/__main__.py +0 -0
  45. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/__init__.py +0 -0
  46. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/assistant_chat.py +0 -0
  47. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/chat.py +0 -0
  48. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/format_markdown_template.py +0 -0
  49. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/markdownify.py +0 -0
  50. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/readability.py +0 -0
  51. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/show_webpage.py +0 -0
  52. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/strip_html.py +0 -0
  53. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/summarize_as_bullets.py +0 -0
  54. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/core/tabbed_webpage_config.py +0 -0
  55. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/meta/write_instructions.py +0 -0
  56. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/actions/meta/write_new_action.py +0 -0
  57. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/__init__.py +0 -0
  58. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/basic_file_commands.py +0 -0
  59. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/browser_commands.py +0 -0
  60. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/debug_commands.py +0 -0
  61. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/diff_commands.py +0 -0
  62. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/files_command.py +0 -0
  63. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/general_commands.py +0 -0
  64. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/logs_commands.py +0 -0
  65. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/model_commands.py +0 -0
  66. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/reformat_command.py +0 -0
  67. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/search_command.py +0 -0
  68. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/base/show_command.py +0 -0
  69. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/extras/parse_uv_lock.py +0 -0
  70. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/extras/utils_commands.py +0 -0
  71. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/help/assistant_commands.py +0 -0
  72. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/help/doc_commands.py +0 -0
  73. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/help/help_commands.py +0 -0
  74. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/help/logo.py +0 -0
  75. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/commands/help/welcome.py +0 -0
  76. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/__init__.py +0 -0
  77. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/capture_output.py +0 -0
  78. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/env_settings.py +0 -0
  79. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/init.py +0 -0
  80. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/lazy_imports.py +0 -0
  81. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/logger.py +0 -0
  82. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/logger_basic.py +0 -0
  83. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/logo.txt +0 -0
  84. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/server_config.py +0 -0
  85. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/settings.py +0 -0
  86. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/setup.py +0 -0
  87. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/suppress_warnings.py +0 -0
  88. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/config/text_styles.py +0 -0
  89. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/__init__.py +0 -0
  90. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/all_docs.py +0 -0
  91. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/load_actions_info.py +0 -0
  92. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/load_api_docs.py +0 -0
  93. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/load_help_topics.py +0 -0
  94. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/load_source_code.py +0 -0
  95. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/api_docs_template.md +0 -0
  96. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/assistant_instructions_template.md +0 -0
  97. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/readme_template.md +0 -0
  98. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/a1_what_is_kash.md +0 -0
  99. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/a2_installation.md +0 -0
  100. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/a3_getting_started.md +0 -0
  101. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/a4_elements.md +0 -0
  102. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/a5_tips_for_use_with_other_tools.md +0 -0
  103. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/b0_philosophy_of_kash.md +0 -0
  104. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/b1_kash_overview.md +0 -0
  105. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/b2_workspace_and_file_formats.md +0 -0
  106. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/b3_modern_shell_tool_recommendations.md +0 -0
  107. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/topics/b4_faq.md +0 -0
  108. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/warning.md +0 -0
  109. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs/markdown/welcome.md +0 -0
  110. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs_base/docs_base.py +0 -0
  111. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs_base/load_custom_command_info.py +0 -0
  112. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs_base/load_faqs.py +0 -0
  113. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs_base/load_recipe_snippets.py +0 -0
  114. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs_base/recipes/general_system_commands.sh +0 -0
  115. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs_base/recipes/python_dev_commands.sh +0 -0
  116. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/docs_base/recipes/tldr_standard_commands.sh +0 -0
  117. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/embeddings/cosine.py +0 -0
  118. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/embeddings/embeddings.py +0 -0
  119. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/embeddings/text_similarity.py +0 -0
  120. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/__init__.py +0 -0
  121. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/action_decorators.py +0 -0
  122. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/action_registry.py +0 -0
  123. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/combiners.py +0 -0
  124. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/command_exec.py +0 -0
  125. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/command_registry.py +0 -0
  126. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/fetch_url_metadata.py +0 -0
  127. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/history.py +0 -0
  128. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/importing.py +0 -0
  129. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/llm_transforms.py +0 -0
  130. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/precondition_checks.py +0 -0
  131. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/runtime_settings.py +0 -0
  132. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec/shell_callable_action.py +0 -0
  133. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec_model/__init__.py +0 -0
  134. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec_model/args_model.py +0 -0
  135. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec_model/commands_model.py +0 -0
  136. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec_model/script_model.py +0 -0
  137. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/exec_model/shell_model.py +0 -0
  138. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/file_storage/__init__.py +0 -0
  139. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/file_storage/metadata_dirs.py +0 -0
  140. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/file_storage/persisted_yaml.py +0 -0
  141. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/file_storage/store_cache_warmer.py +0 -0
  142. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/file_storage/store_filenames.py +0 -0
  143. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/__init__.py +0 -0
  144. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/assistant.py +0 -0
  145. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/assistant_instructions.py +0 -0
  146. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/assistant_output.py +0 -0
  147. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/docstring_utils.py +0 -0
  148. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/function_param_info.py +0 -0
  149. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/help_embeddings.py +0 -0
  150. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/help_lookups.py +0 -0
  151. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/help_pages.py +0 -0
  152. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/help_printing.py +0 -0
  153. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/help_types.py +0 -0
  154. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/recommended_commands.py +0 -0
  155. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/help/tldr_help.py +0 -0
  156. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/__init__.py +0 -0
  157. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/clean_headings.py +0 -0
  158. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/custom_sliding_transforms.py +0 -0
  159. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/fuzzy_parsing.py +0 -0
  160. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/init_litellm.py +0 -0
  161. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/llm_api_keys.py +0 -0
  162. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/llm_completion.py +0 -0
  163. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/llm_features.py +0 -0
  164. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/llm_messages.py +0 -0
  165. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/llm_names.py +0 -0
  166. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/llm_utils/llms.py +0 -0
  167. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/local_server/__init__.py +0 -0
  168. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/local_server/local_server.py +0 -0
  169. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/local_server/local_server_commands.py +0 -0
  170. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/local_server/local_url_formatters.py +0 -0
  171. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/local_server/port_tools.py +0 -0
  172. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/local_server/rich_html_template.py +0 -0
  173. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/mcp/__init__.py +0 -0
  174. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/mcp/mcp_cli.py +0 -0
  175. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/mcp/mcp_main.py +0 -0
  176. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/mcp/mcp_server_commands.py +0 -0
  177. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/mcp/mcp_server_routes.py +0 -0
  178. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/mcp/mcp_server_sse.py +0 -0
  179. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/mcp/mcp_server_stdio.py +0 -0
  180. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/__init__.py +0 -0
  181. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/audio_processing.py +0 -0
  182. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/media_cache.py +0 -0
  183. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/media_services.py +0 -0
  184. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/media_tools.py +0 -0
  185. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/services/local_file_media.py +0 -0
  186. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/timestamp_citations.py +0 -0
  187. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/transcription_deepgram.py +0 -0
  188. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/transcription_format.py +0 -0
  189. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/media_base/transcription_whisper.py +0 -0
  190. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/__init__.py +0 -0
  191. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/assistant_response_model.py +0 -0
  192. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/compound_actions_model.py +0 -0
  193. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/concept_model.py +0 -0
  194. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/exec_model.py +0 -0
  195. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/graph_model.py +0 -0
  196. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/language_list.py +0 -0
  197. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/llm_actions_model.py +0 -0
  198. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/media_model.py +0 -0
  199. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/operations_model.py +0 -0
  200. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/params_model.py +0 -0
  201. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/paths_model.py +0 -0
  202. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/model/preconditions_model.py +0 -0
  203. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/__init__.py +0 -0
  204. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/completions/completion_scoring.py +0 -0
  205. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/completions/completion_types.py +0 -0
  206. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/file_icons/color_for_format.py +0 -0
  207. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/file_icons/nerd_icons.py +0 -0
  208. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/input/__init__.py +0 -0
  209. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/input/input_prompts.py +0 -0
  210. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/input/inquirer_settings.py +0 -0
  211. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/input/param_inputs.py +0 -0
  212. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/input/shell_confirm.py +0 -0
  213. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/output/__init__.py +0 -0
  214. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/output/kerm_code_utils.py +0 -0
  215. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/output/kerm_codes.py +0 -0
  216. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/output/kmarkdown.py +0 -0
  217. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/output/shell_formatting.py +0 -0
  218. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/output/shell_output.py +0 -0
  219. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/shell_main.py +0 -0
  220. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/ui/__init__.py +0 -0
  221. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/ui/shell_results.py +0 -0
  222. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/ui/shell_syntax.py +0 -0
  223. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/utils/exception_printing.py +0 -0
  224. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/utils/native_utils.py +0 -0
  225. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/utils/shell_function_wrapper.py +0 -0
  226. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/shell/version.py +0 -0
  227. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/__init__.py +0 -0
  228. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/__init__.py +0 -0
  229. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/format_utils.py +0 -0
  230. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/function_inspect.py +0 -0
  231. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/import_utils.py +0 -0
  232. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/lazyobject.py +0 -0
  233. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/obj_replace.py +0 -0
  234. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/parse_key_vals.py +0 -0
  235. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/parse_shell_args.py +0 -0
  236. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/stack_traces.py +0 -0
  237. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/task_stack.py +0 -0
  238. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/type_utils.py +0 -0
  239. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/uniquifier.py +0 -0
  240. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/common/url.py +0 -0
  241. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/errors.py +0 -0
  242. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_formats/chat_format.py +0 -0
  243. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/__init__.py +0 -0
  244. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/dir_info.py +0 -0
  245. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/file_ext.py +0 -0
  246. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/file_formats.py +0 -0
  247. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/file_sort_filter.py +0 -0
  248. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/file_walk.py +0 -0
  249. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/filename_parsing.py +0 -0
  250. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/ignore_files.py +0 -0
  251. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/mtime_cache.py +0 -0
  252. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/file_utils/path_utils.py +0 -0
  253. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/lang_utils/__init__.py +0 -0
  254. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/lang_utils/capitalization.py +0 -0
  255. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/rich_custom/__init__.py +0 -0
  256. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/rich_custom/ansi_cell_len.py +0 -0
  257. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/rich_custom/rich_char_transform.py +0 -0
  258. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/rich_custom/rich_indent.py +0 -0
  259. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/rich_custom/rich_markdown_fork.py +0 -0
  260. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/text_handling/escape_html_tags.py +0 -0
  261. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/text_handling/markdown_render.py +0 -0
  262. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/text_handling/markdown_utils.py +0 -0
  263. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/text_handling/markdownify_utils.py +0 -0
  264. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/utils/text_handling/unified_diffs.py +0 -0
  265. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/canon_url.py +0 -0
  266. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/dir_store.py +0 -0
  267. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/file_cache_utils.py +0 -0
  268. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/file_processing.py +0 -0
  269. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/local_file_cache.py +0 -0
  270. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/web_extract.py +0 -0
  271. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/web_extract_justext.py +0 -0
  272. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/web_extract_readabilipy.py +0 -0
  273. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/web_fetch.py +0 -0
  274. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_content/web_page_model.py +0 -0
  275. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/__init__.py +0 -0
  276. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/template_render.py +0 -0
  277. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/templates/content_styles.css.jinja +0 -0
  278. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/templates/explain_view.html.jinja +0 -0
  279. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/web_gen/templates/tabbed_webpage.html.jinja +0 -0
  280. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/workspaces/__init__.py +0 -0
  281. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/workspaces/param_state.py +0 -0
  282. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/workspaces/selections.py +0 -0
  283. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/workspaces/source_items.py +0 -0
  284. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/workspaces/workspace_dirs.py +0 -0
  285. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/workspaces/workspace_output.py +0 -0
  286. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/workspaces/workspace_registry.py +0 -0
  287. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/workspaces/workspaces.py +0 -0
  288. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/command_nl_utils.py +0 -0
  289. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/custom_shell.py +0 -0
  290. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/customize_prompt.py +0 -0
  291. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/load_into_xonsh.py +0 -0
  292. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/shell_load_commands.py +0 -0
  293. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/shell_which.py +0 -0
  294. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/xonsh_completers.py +0 -0
  295. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/xonsh_env.py +0 -0
  296. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/xonsh_keybindings.py +0 -0
  297. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/xonsh_modern_tools.py +0 -0
  298. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xonsh_custom/xonsh_ranking_completer.py +0 -0
  299. {kash_shell-0.3.14 → kash_shell-0.3.16}/src/kash/xontrib/fnm.py +0 -0
  300. {kash_shell-0.3.14 → kash_shell-0.3.16}/tests/test_shell.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kash-shell
3
- Version: 0.3.14
3
+ Version: 0.3.16
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>
@@ -27,7 +27,9 @@ def render_as_html(input: ActionInput, no_title: bool = False) -> ActionResult:
27
27
  """
28
28
  if len(input.items) == 1:
29
29
  input_item = input.items[0]
30
- html_body = simple_webpage_render(input_item, add_title_h1=not no_title)
30
+ html_body = simple_webpage_render(
31
+ input_item, add_title_h1=not no_title, show_theme_toggle=True
32
+ )
31
33
  result_item = input_item.derived_copy(
32
34
  type=ItemType.export, format=Format.html, body=html_body
33
35
  )
@@ -17,7 +17,9 @@ def tabbed_webpage_generate(input: ActionInput, add_title: bool = False) -> Acti
17
17
  Generate a tabbed web page from a config item for the tabbed template.
18
18
  """
19
19
  config_item = input.items[0]
20
- html = tabbed_webpage.tabbed_webpage_generate(config_item, add_title_h1=add_title)
20
+ html = tabbed_webpage.tabbed_webpage_generate(
21
+ config_item, add_title_h1=add_title, show_theme_toggle=True
22
+ )
21
23
 
22
24
  webpage_item = Item(
23
25
  title=config_item.title,
@@ -7,6 +7,7 @@ from strif import copyfile_atomic
7
7
 
8
8
  from kash.config.logger import get_logger
9
9
  from kash.exec import kash_command
10
+ from kash.exec.resolve_args import assemble_path_args
10
11
  from kash.exec_model.shell_model import ShellResult
11
12
  from kash.model.paths_model import StorePath
12
13
  from kash.shell.ui.shell_results import shell_print_selection_history
@@ -30,6 +31,7 @@ def select(
30
31
  clear_all: bool = False,
31
32
  clear_future: bool = False,
32
33
  refresh: bool = False,
34
+ no_check: bool = False,
33
35
  ) -> ShellResult:
34
36
  """
35
37
  Set or show the current selection.
@@ -51,6 +53,7 @@ def select(
51
53
  :param clear_all: Clear the full selection history.
52
54
  :param clear_future: Clear all selections from history after the current one.
53
55
  :param refresh: Refresh the current selection to drop any paths that no longer exist.
56
+ :param no_check: Do not check if the paths exist.
54
57
  """
55
58
  ws = current_ws()
56
59
 
@@ -68,6 +71,10 @@ def select(
68
71
  raise InvalidInput("Cannot combine multiple flags")
69
72
  if paths and any(exclusive_flags):
70
73
  raise InvalidInput("Cannot combine paths with other flags")
74
+ if not no_check:
75
+ for path in paths:
76
+ if not Path(ws.base_dir / path).exists():
77
+ raise InvalidInput(f"Path does not exist: {fmt_loc(path)}")
71
78
 
72
79
  if paths:
73
80
  store_paths = [StorePath(path) for path in paths]
@@ -203,3 +210,18 @@ def save(parent: str | None = None, to: str | None = None, no_frontmatter: bool
203
210
  for store_path in store_paths:
204
211
  target_path = target_dir / basename(store_path)
205
212
  copy_file(store_path, target_path)
213
+
214
+
215
+ @kash_command
216
+ def show_parent_dir(*paths: str) -> None:
217
+ """
218
+ Show the parent directory of the first item in the current selection.
219
+ """
220
+ from kash.commands.base.show_command import show
221
+
222
+ input_paths = assemble_path_args(*paths)
223
+ if not input_paths:
224
+ raise InvalidInput("No paths provided")
225
+
226
+ input_path = current_ws().resolve_to_abs_path(input_paths[0])
227
+ show(input_path.parent)
@@ -59,6 +59,7 @@ from kash.utils.errors import InvalidInput
59
59
  from kash.utils.file_formats.chat_format import tail_chat_history
60
60
  from kash.utils.file_utils.dir_info import is_nonempty_dir
61
61
  from kash.utils.file_utils.file_formats_model import Format
62
+ from kash.utils.text_handling.doc_normalization import can_normalize
62
63
  from kash.web_content.file_cache_utils import cache_file
63
64
  from kash.workspaces import (
64
65
  current_ws,
@@ -189,11 +190,13 @@ def cache_content(*urls_or_paths: str, refetch: bool = False) -> None:
189
190
 
190
191
 
191
192
  @kash_command
192
- def download(*urls_or_paths: str, refetch: bool = False) -> ShellResult:
193
+ def download(*urls_or_paths: str, refetch: bool = False, no_format: bool = False) -> ShellResult:
193
194
  """
194
195
  Download a URL or resource. Uses cached content if available, unless `refetch` is true.
195
196
  Inputs can be URLs or paths to URL resources.
196
197
  Creates both resource and document versions for text content.
198
+
199
+ :param no_format: If true, do not also normalize Markdown content.
197
200
  """
198
201
  ws = current_ws()
199
202
  saved_paths = []
@@ -236,11 +239,13 @@ def download(*urls_or_paths: str, refetch: bool = False) -> ShellResult:
236
239
  mime_type=mime_type,
237
240
  original_filename=original_filename,
238
241
  )
242
+ # For initial content, do not format or add frontmatter.
239
243
  store_path = ws.save(resource_item, no_frontmatter=True, no_format=True)
240
244
  saved_paths.append(store_path)
245
+ select(store_path)
241
246
 
242
- # Also create a doc version for text content
243
- if resource_item.format and resource_item.format.supports_frontmatter:
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:
244
249
  doc_item = Item.from_external_path(
245
250
  cache_result.content.path,
246
251
  ItemType.doc,
@@ -248,8 +253,10 @@ def download(*urls_or_paths: str, refetch: bool = False) -> ShellResult:
248
253
  mime_type=mime_type,
249
254
  original_filename=original_filename,
250
255
  )
251
- doc_store_path = ws.save(doc_item, no_frontmatter=False, no_format=False)
256
+ # Now use default formatting and frontmatter.
257
+ doc_store_path = ws.save(doc_item)
252
258
  saved_paths.append(doc_store_path)
259
+ select(doc_store_path)
253
260
 
254
261
  print_status(
255
262
  "Downloaded %s %s:\n%s",
@@ -257,7 +264,6 @@ def download(*urls_or_paths: str, refetch: bool = False) -> ShellResult:
257
264
  plural("item", len(saved_paths)),
258
265
  fmt_lines(saved_paths),
259
266
  )
260
- select(*saved_paths)
261
267
 
262
268
  return ShellResult(show_selection=True)
263
269
 
@@ -148,12 +148,40 @@ web_light_translucent = SimpleNamespace(
148
148
  tooltip_bg=hsl_to_hex("hsla(188, 6%, 37%, 0.7)"),
149
149
  popover_bg=hsl_to_hex("hsla(188, 6%, 37%, 0.7)"),
150
150
  bright=hsl_to_hex("hsl(134, 43%, 60%)"),
151
+ success=hsl_to_hex("hsl(134, 43%, 60%)"),
151
152
  selection="hsla(225, 61%, 82%, 0.80)",
152
153
  scrollbar=hsl_to_hex("hsla(189, 12%, 55%, 0.9)"),
153
154
  scrollbar_hover=hsl_to_hex("hsla(190, 12%, 38%, 0.9)"),
154
155
  )
155
156
 
156
157
 
158
+ # Web dark colors
159
+ web_dark_translucent = SimpleNamespace(
160
+ primary=hsl_to_hex("hsl(188, 40%, 62%)"),
161
+ primary_light=hsl_to_hex("hsl(188, 50%, 72%)"),
162
+ secondary=hsl_to_hex("hsl(188, 12%, 65%)"),
163
+ bg=hsl_to_hex("hsla(220, 14%, 7%, 0.95)"),
164
+ bg_solid=hsl_to_hex("hsl(220, 14%, 7%)"),
165
+ bg_header=hsl_to_hex("hsla(188, 42%, 20%, 0.3)"),
166
+ bg_alt=hsl_to_hex("hsla(220, 14%, 12%, 0.5)"),
167
+ bg_alt_solid=hsl_to_hex("hsl(220, 14%, 12%)"),
168
+ text=hsl_to_hex("hsl(188, 20%, 90%)"),
169
+ border=hsl_to_hex("hsl(188, 8%, 25%)"),
170
+ border_hint=hsl_to_hex("hsla(188, 8%, 35%, 0.7)"),
171
+ border_accent=hsl_to_hex("hsla(305, 30%, 55%, 0.85)"),
172
+ hover=hsl_to_hex("hsl(188, 12%, 35%)"),
173
+ hover_bg=hsl_to_hex("hsla(188, 20%, 25%, 0.4)"),
174
+ hint=hsl_to_hex("hsl(188, 11%, 55%)"),
175
+ tooltip_bg=hsl_to_hex("hsla(188, 6%, 20%, 0.9)"),
176
+ popover_bg=hsl_to_hex("hsla(188, 6%, 20%, 0.9)"),
177
+ bright=hsl_to_hex("hsl(134, 43%, 60%)"),
178
+ success=hsl_to_hex("hsl(134, 43%, 60%)"),
179
+ selection=hsl_to_hex("hsla(225, 61%, 40%, 0.40)"),
180
+ scrollbar=hsl_to_hex("hsla(189, 12%, 35%, 0.9)"),
181
+ scrollbar_hover=hsl_to_hex("hsla(190, 12%, 50%, 0.9)"),
182
+ )
183
+
184
+
157
185
  rich_terminal_dark = TerminalTheme(
158
186
  hex_to_int(terminal_dark.background),
159
187
  hex_to_int(terminal_dark.foreground),
@@ -211,9 +239,6 @@ rich_terminal_light = TerminalTheme(
211
239
  # We default to light colors for Rich content in HTML.
212
240
  rich_terminal = rich_terminal_light
213
241
 
214
- # Only support light web colors for now.
215
- web = web_light_translucent
216
-
217
242
  # Logical colors
218
243
  logical = SimpleNamespace(
219
244
  concept_dark=terminal.green_dark,
@@ -234,18 +259,23 @@ logical = SimpleNamespace(
234
259
  )
235
260
 
236
261
 
237
- def consolidate_color_vars(overrides: dict[str, str] | None = None) -> dict[str, str]:
262
+ def consolidate_color_vars(
263
+ overrides: dict[str, str] | None = None, web_colors: SimpleNamespace | None = None
264
+ ) -> dict[str, str]:
238
265
  """
239
266
  Consolidate all color variables into a single dictionary with appropriate prefixes.
240
267
  Terminal variables have no prefix, while web and logical variables have "color-" prefix.
241
268
  """
242
269
  if overrides is None:
243
270
  overrides = {}
271
+ if web_colors is None:
272
+ web_colors = web_light_translucent
273
+
244
274
  return {
245
275
  # Terminal variables (no prefix)
246
276
  **terminal.__dict__,
247
277
  # Web and logical variables with "color-" prefix
248
- **{f"color-{k}": v for k, v in web.__dict__.items()},
278
+ **{f"color-{k}": v for k, v in web_colors.__dict__.items()},
249
279
  **{f"color-{k}": v for k, v in logical.__dict__.items()},
250
280
  # Overrides take precedence (assume they already have correct prefixes)
251
281
  **overrides,
@@ -262,19 +292,63 @@ def normalize_var_names(variables: dict[str, str]) -> dict[str, str]:
262
292
 
263
293
  def generate_css_vars(overrides: dict[str, str] | None = None) -> str:
264
294
  """
265
- Generate CSS variables for the terminal and web colors.
295
+ Generate CSS variables for terminal and both light and dark themes.
266
296
  """
267
297
  if overrides is None:
268
298
  overrides = {}
269
- normalized_vars = normalize_var_names(consolidate_color_vars(overrides))
270
299
 
271
- # Generate the CSS.
272
- css_variables = ":root {\n"
273
- for name, value in normalized_vars.items():
274
- css_variables += f" --{name}: {value};\n"
275
- css_variables += "}"
300
+ # Get base variables (terminal colors stay the same)
301
+ base_vars = normalize_var_names({k: v for k, v in terminal.__dict__.items()})
302
+
303
+ # Get light theme color variables
304
+ light_color_vars = normalize_var_names(
305
+ {f"color-{k}": v for k, v in web_light_translucent.__dict__.items()}
306
+ )
307
+ light_color_vars.update(
308
+ normalize_var_names({f"color-{k}": v for k, v in logical.__dict__.items()})
309
+ )
310
+
311
+ # Get dark theme color variables
312
+ dark_color_vars = normalize_var_names(
313
+ {f"color-{k}": v for k, v in web_dark_translucent.__dict__.items()}
314
+ )
315
+ dark_color_vars.update(
316
+ normalize_var_names({f"color-{k}": v for k, v in logical.__dict__.items()})
317
+ )
276
318
 
277
- return css_variables
319
+ # Apply overrides
320
+ if overrides:
321
+ normalized_overrides = normalize_var_names(overrides)
322
+ light_color_vars.update(normalized_overrides)
323
+ dark_color_vars.update(normalized_overrides)
324
+
325
+ # Generate CSS
326
+ css_parts = []
327
+
328
+ # Root with all variables (defaults to light)
329
+ css_parts.append(":root {")
330
+ css_parts.extend(f" --{k}: {v};" for k, v in base_vars.items())
331
+ css_parts.extend(f" --{k}: {v};" for k, v in light_color_vars.items())
332
+ css_parts.append("}\n")
333
+
334
+ # Light theme (only color- variables)
335
+ css_parts.append('[data-theme="light"] {')
336
+ css_parts.extend(f" --{k}: {v};" for k, v in light_color_vars.items())
337
+ css_parts.append("}\n")
338
+
339
+ # Dark theme (only color- variables)
340
+ css_parts.append('[data-theme="dark"] {')
341
+ css_parts.extend(f" --{k}: {v};" for k, v in dark_color_vars.items())
342
+ css_parts.append("}\n")
343
+
344
+ # Print media
345
+ css_parts.append("@media print {")
346
+ css_parts.append(' :root, [data-theme="dark"] {')
347
+ css_parts.extend(f" --{k}: {v} !important;" for k, v in light_color_vars.items())
348
+ css_parts.append(" }")
349
+ css_parts.append("}")
350
+
351
+ return "\n".join(css_parts)
278
352
 
279
353
 
280
354
  if __name__ == "__main__":
@@ -1,7 +1,8 @@
1
1
  import time
2
2
  from dataclasses import replace
3
+ from pathlib import Path
3
4
 
4
- from prettyfmt import fmt_lines, plural
5
+ from prettyfmt import fmt_lines, fmt_path, plural
5
6
 
6
7
  from kash.config.logger import get_logger
7
8
  from kash.config.text_styles import (
@@ -287,6 +288,14 @@ def save_action_result(
287
288
  Save the result of an action to the workspace. Handles skipping duplicates and
288
289
  archiving old inputs, if appropriate, based on hints in the ActionResult.
289
290
  """
291
+ # If an action returned an external path, we should confirm it exists or it is probably
292
+ # a bug in the action.
293
+ for item in result.items:
294
+ if item.external_path and not Path(item.external_path).exists():
295
+ raise InvalidOutput(
296
+ f"External path returned by action does not exist: {fmt_path(item.external_path)}"
297
+ )
298
+
290
299
  input_items = action_input.items
291
300
 
292
301
  skipped_paths = []
@@ -377,7 +386,11 @@ def run_action_with_caching(
377
386
  # Run it!
378
387
  result = run_action_operation(context, action_input, operation)
379
388
  result_store_paths, archived_store_paths = save_action_result(
380
- ws, result, action_input, as_tmp=settings.tmp_output, no_format=settings.no_format
389
+ ws,
390
+ result,
391
+ action_input,
392
+ as_tmp=settings.tmp_output,
393
+ no_format=settings.no_format,
381
394
  )
382
395
 
383
396
  PrintHooks.before_done_message()
@@ -448,13 +461,19 @@ def run_action_with_shell_context(
448
461
 
449
462
  # As a special case for convenience, if the action expects no args, ignore any pre-selected inputs.
450
463
  if action.expected_args == NO_ARGS and from_selection:
451
- log.message("Not using current selection since action `%s` expects no args.", action_name)
464
+ log.message(
465
+ "Not using current selection since action `%s` expects no args.",
466
+ action_name,
467
+ )
452
468
  args.clear()
453
469
 
454
470
  if args:
455
471
  source_str = "provided args" if provided_args else "selection"
456
472
  log.message(
457
- "Using %s as inputs to action `%s`:\n%s", source_str, action_name, fmt_lines(args)
473
+ "Using %s as inputs to action `%s`:\n%s",
474
+ source_str,
475
+ action_name,
476
+ fmt_lines(args),
458
477
  )
459
478
 
460
479
  # Get items for each input arg.
@@ -16,11 +16,13 @@ def kash_precondition(func: Callable[[Item], bool]) -> Precondition:
16
16
  """
17
17
  Decorator to register a function as a Precondition.
18
18
  The function should return a bool and/or raise `PreconditionFailure`.
19
+ Returns an actual Precondition object, not the function, so that it's possible to
20
+ do precondition algebra, e.g. `is_file & has_body`.
19
21
 
20
22
  Example:
21
- @register_precondition
22
- def is_file(item: Item) -> bool:
23
- return item.is_file()
23
+ @kash_precondition
24
+ def has_body(item: Item) -> bool:
25
+ return item.has_body()
24
26
  """
25
27
  precondition = Precondition(func)
26
28
 
@@ -104,6 +104,11 @@ def has_html_body(item: Item) -> bool:
104
104
  return bool(has_body(item) and item.format and item.format.is_html)
105
105
 
106
106
 
107
+ @kash_precondition
108
+ def has_html_compatible_body(item: Item) -> bool:
109
+ return bool(has_body(item) and item.format and item.format.is_html_compatible)
110
+
111
+
107
112
  @kash_precondition
108
113
  def has_markdown_body(item: Item) -> bool:
109
114
  return bool(has_body(item) and item.format and item.format.is_markdown)
@@ -136,14 +141,14 @@ def is_markdown_with_html(item: Item) -> bool:
136
141
 
137
142
  @kash_precondition
138
143
  def is_markdown_template(item: Item) -> bool:
139
- return is_markdown(item) and contains_curly_vars(item)
144
+ return has_markdown_body(item) and contains_curly_vars(item)
140
145
 
141
146
 
142
147
  @kash_precondition
143
148
  def is_markdown_list(item: Item) -> bool:
144
149
  try:
145
150
  return (
146
- is_markdown(item)
151
+ has_markdown_body(item)
147
152
  and item.body is not None
148
153
  and len(extract_bullet_points(item.body)) >= 2
149
154
  )
@@ -42,7 +42,7 @@ def resolve_path_arg(path_str: UnresolvedPath) -> Path | StorePath:
42
42
  return path
43
43
  else:
44
44
  try:
45
- store_path = current_ws().resolve_path(path)
45
+ store_path = current_ws().resolve_to_store_path(path)
46
46
  if store_path:
47
47
  return store_path
48
48
  else:
@@ -110,7 +110,7 @@ def resolvable_paths(paths: Sequence[StorePath | Path]) -> list[StorePath]:
110
110
  current workspace.
111
111
  """
112
112
  ws = current_ws()
113
- resolvable = list(filter(None, (ws.resolve_path(p) for p in paths)))
113
+ resolvable = list(filter(None, (ws.resolve_to_store_path(p) for p in paths)))
114
114
  return resolvable
115
115
 
116
116