kash-shell 0.3.18__tar.gz → 0.3.21__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kash_shell-0.3.18 → kash_shell-0.3.21}/.copier-answers.yml +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/.cursor/rules/general.mdc +18 -13
- {kash_shell-0.3.18 → kash_shell-0.3.21}/.cursor/rules/python.mdc +68 -23
- {kash_shell-0.3.18 → kash_shell-0.3.21}/.github/workflows/ci.yml +2 -2
- {kash_shell-0.3.18 → kash_shell-0.3.21}/.github/workflows/publish.yml +7 -4
- {kash_shell-0.3.18 → kash_shell-0.3.21}/Makefile +5 -2
- {kash_shell-0.3.18 → kash_shell-0.3.21}/PKG-INFO +4 -2
- {kash_shell-0.3.18 → kash_shell-0.3.21}/README.md +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/development.md +13 -2
- {kash_shell-0.3.18 → kash_shell-0.3.21}/pyproject.toml +4 -1
- kash_shell-0.3.18/src/kash/actions/core/markdownify.py → kash_shell-0.3.21/src/kash/actions/core/markdownify_html.py +3 -6
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/workspace/workspace_commands.py +10 -88
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/colors.py +8 -6
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/text_styles.py +2 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a1_what_is_kash.md +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b1_kash_overview.md +34 -45
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/__init__.py +3 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/action_decorators.py +20 -5
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/action_exec.py +2 -2
- kash_shell-0.3.18/src/kash/exec/fetch_url_metadata.py → kash_shell-0.3.21/src/kash/exec/fetch_url_items.py +42 -14
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/llm_transforms.py +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/shell_callable_action.py +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/file_store.py +7 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/store_filenames.py +4 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/function_param_info.py +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_pages.py +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_printing.py +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_completion.py +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/actions_model.py +6 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/items_model.py +18 -3
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/shell_output.py +15 -0
- kash_shell-0.3.21/src/kash/utils/api_utils/api_retries.py +305 -0
- kash_shell-0.3.21/src/kash/utils/api_utils/cache_requests_limited.py +84 -0
- kash_shell-0.3.21/src/kash/utils/api_utils/gather_limited.py +987 -0
- kash_shell-0.3.21/src/kash/utils/api_utils/progress_protocol.py +299 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/function_inspect.py +66 -1
- kash_shell-0.3.21/src/kash/utils/common/parse_docstring.py +347 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/testing.py +10 -7
- kash_shell-0.3.21/src/kash/utils/rich_custom/multitask_status.py +631 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/escape_html_tags.py +16 -11
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdown_render.py +1 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_extract.py +34 -15
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_page_model.py +10 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/base_styles.css.jinja +26 -20
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/toc_styles.css.jinja +1 -1
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/tooltip_scripts.js.jinja +171 -19
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/tooltip_styles.css.jinja +23 -8
- kash_shell-0.3.21/tests/kash/utils/rich_custom/test_multitask_status.py +564 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/uv.lock +269 -269
- kash_shell-0.3.18/src/kash/help/docstring_utils.py +0 -111
- {kash_shell-0.3.18 → kash_shell-0.3.21}/.env.template +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/.gitignore +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/LICENSE +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/devtools/generate_readme.xsh +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/devtools/lint.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/devtools/profile_main.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/installation.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/publishing.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/__main__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/assistant_chat.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/chat.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/format_markdown_template.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/minify_html.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/readability.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/render_as_html.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/show_webpage.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/strip_html.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/summarize_as_bullets.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/tabbed_webpage_config.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/core/tabbed_webpage_generate.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/meta/write_instructions.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/actions/meta/write_new_action.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/basic_file_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/browser_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/debug_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/diff_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/files_command.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/general_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/logs_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/model_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/reformat_command.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/search_command.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/base/show_command.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/extras/parse_uv_lock.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/extras/utils_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/assistant_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/doc_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/help_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/logo.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/help/welcome.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/commands/workspace/selection_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/capture_output.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/env_settings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/init.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/lazy_imports.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/logger.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/logger_basic.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/logo.txt +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/server_config.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/settings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/setup.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/config/suppress_warnings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/all_docs.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/load_actions_info.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/load_api_docs.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/load_help_topics.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/load_source_code.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/api_docs_template.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/assistant_instructions_template.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/readme_template.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a2_installation.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a3_getting_started.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a4_elements.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/a5_tips_for_use_with_other_tools.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b0_philosophy_of_kash.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b2_workspace_and_file_formats.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b3_modern_shell_tool_recommendations.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/topics/b4_faq.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/warning.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs/markdown/welcome.md +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/docs_base.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/load_custom_command_info.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/load_faqs.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/load_recipe_snippets.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/recipes/general_system_commands.sh +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/recipes/python_dev_commands.sh +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/docs_base/recipes/tldr_standard_commands.sh +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/embeddings/cosine.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/embeddings/embeddings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/embeddings/text_similarity.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/action_registry.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/combiners.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/command_exec.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/command_registry.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/history.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/importing.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/precondition_checks.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/precondition_registry.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/preconditions.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/resolve_args.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec/runtime_settings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/args_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/commands_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/script_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/exec_model/shell_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/item_file_format.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/metadata_dirs.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/persisted_yaml.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/file_storage/store_cache_warmer.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/assistant.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/assistant_instructions.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/assistant_output.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_embeddings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_lookups.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/help_types.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/recommended_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/help/tldr_help.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/clean_headings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/custom_sliding_transforms.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/fuzzy_parsing.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/init_litellm.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_api_keys.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_features.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_messages.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llm_names.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/llm_utils/llms.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/local_server.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/local_server_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/local_server_routes.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/local_url_formatters.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/port_tools.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/local_server/rich_html_template.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_cli.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_main.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_routes.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_sse.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/mcp/mcp_server_stdio.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/audio_processing.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/media_cache.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/media_services.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/media_tools.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/services/local_file_media.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/timestamp_citations.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/transcription_deepgram.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/transcription_format.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/media_base/transcription_whisper.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/assistant_response_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/compound_actions_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/concept_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/exec_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/graph_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/language_list.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/llm_actions_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/media_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/operations_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/params_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/paths_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/model/preconditions_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/completions/completion_scoring.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/completions/completion_types.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/completions/shell_completions.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/file_icons/color_for_format.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/file_icons/nerd_icons.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/input_prompts.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/inquirer_settings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/param_inputs.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/input/shell_confirm.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/kerm_code_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/kerm_codes.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/kmarkdown.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/output/shell_formatting.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/shell_main.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/ui/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/ui/shell_results.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/ui/shell_syntax.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/utils/exception_printing.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/utils/native_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/utils/shell_function_wrapper.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/shell/version.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/format_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/import_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/lazyobject.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/obj_replace.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/parse_key_vals.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/parse_shell_args.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/stack_traces.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/task_stack.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/type_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/uniquifier.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/url.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/common/url_slice.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/errors.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_formats/chat_format.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/dir_info.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_ext.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_formats.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_formats_model.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_sort_filter.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/file_walk.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/filename_parsing.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/ignore_files.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/mtime_cache.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/file_utils/path_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/lang_utils/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/lang_utils/capitalization.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/ansi_cell_len.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_char_transform.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_indent.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/rich_custom/rich_markdown_fork.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/doc_normalization.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdown_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/markdownify_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/utils/text_handling/unified_diffs.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/canon_url.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/dir_store.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/file_cache_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/file_processing.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/local_file_cache.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_extract_justext.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_extract_readabilipy.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_content/web_fetch.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/simple_webpage.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/tabbed_webpage.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/template_render.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/base_webpage.html.jinja +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/components/toc_scripts.js.jinja +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/content_styles.css.jinja +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/explain_view.html.jinja +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/item_view.html.jinja +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/simple_webpage.html.jinja +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/web_gen/templates/tabbed_webpage.html.jinja +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/__init__.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/param_state.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/selections.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/source_items.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/workspace_dirs.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/workspace_output.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/workspace_registry.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/workspaces/workspaces.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/command_nl_utils.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/custom_shell.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/customize_prompt.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/load_into_xonsh.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/shell_load_commands.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/shell_which.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_completers.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_env.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_keybindings.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_modern_tools.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xonsh_custom/xonsh_ranking_completer.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xontrib/fnm.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/src/kash/xontrib/kash_extension.py +0 -0
- {kash_shell-0.3.18 → kash_shell-0.3.21}/tests/test_shell.py +0 -0
|
@@ -3,11 +3,14 @@ description: General Guidelines
|
|
|
3
3
|
globs:
|
|
4
4
|
alwaysApply: true
|
|
5
5
|
---
|
|
6
|
-
#
|
|
6
|
+
# Assistant Rules
|
|
7
7
|
|
|
8
|
-
Remember you are a senior engineer and have a
|
|
9
|
-
factual, think step by step and be systematic,
|
|
10
|
-
the user's attention wisely.
|
|
8
|
+
**Your fundamental responsibility:** Remember you are a senior engineer and have a
|
|
9
|
+
serious responsibility to be clear, factual, think step by step and be systematic,
|
|
10
|
+
express expert opinion, and make use of the user's attention wisely.
|
|
11
|
+
|
|
12
|
+
**Rules must be followed:** It is your responsibility to carefully read these rules as
|
|
13
|
+
well as Python or other language-specific rules included here.
|
|
11
14
|
|
|
12
15
|
Therefore:
|
|
13
16
|
|
|
@@ -22,8 +25,8 @@ Therefore:
|
|
|
22
25
|
it. It's your responsibility to suggest approaches that lead to better, simpler
|
|
23
26
|
solutions.
|
|
24
27
|
|
|
25
|
-
- Give thoughtful opinions on better/worse approaches, but
|
|
26
|
-
or "good job" or other non-essential banter
|
|
28
|
+
- Give thoughtful opinions on better/worse approaches, but NEVER say "great idea!"
|
|
29
|
+
or "good job" or other compliments, encouragement, or non-essential banter.
|
|
27
30
|
Your job is to give expert opinions and to solve problems, not to motivate the user.
|
|
28
31
|
|
|
29
32
|
- Avoid gratuitous enthusiasm or generalizations.
|
|
@@ -50,18 +53,20 @@ Therefore:
|
|
|
50
53
|
this is meaningless to anyone reading the code later.
|
|
51
54
|
(Instead, describe in your message to the user any other contextual information.)
|
|
52
55
|
|
|
53
|
-
- DO NOT use fancy headings like "=====
|
|
56
|
+
- DO NOT use fancy or needlessly decorated headings like "===== MIGRATION TOOLS ====="
|
|
57
|
+
in comments
|
|
54
58
|
|
|
55
|
-
- DO NOT
|
|
59
|
+
- DO NOT number steps in comments.
|
|
56
60
|
These are hard to maintain if the code changes.
|
|
57
|
-
|
|
58
|
-
the cache"
|
|
59
|
-
|
|
60
|
-
## Using Emojis
|
|
61
|
+
NEVER DO THIS: "// Step 3: Fetch the data from the cache"\
|
|
62
|
+
This is fine: "// Now fetch the data from the cache"
|
|
61
63
|
|
|
62
64
|
- DO NOT use emojis or special unicode characters like ① or • or – or — in comments.
|
|
63
65
|
|
|
64
66
|
- Use emojis in output if it enhances the clarity and can be done consistently.
|
|
65
67
|
You may use ✔︎ and ✘ to indicate success and failure, and ∆ and ‼︎ for user-facing
|
|
66
68
|
warnings and errors, for example, but be sure to do it consistently.
|
|
67
|
-
|
|
69
|
+
DO NOT use emojis gratuitously in comments or output.
|
|
70
|
+
You may use then ONLY when they have clear meanings (like success or failure).
|
|
71
|
+
Unless the user says otherwise, avoid emojis and Unicode in comments as clutters the
|
|
72
|
+
output with little benefit.
|
|
@@ -16,10 +16,10 @@ Always use full type annotations, generics, and other modern practices.
|
|
|
16
16
|
|
|
17
17
|
## Project Setup and Developer Workflows
|
|
18
18
|
|
|
19
|
-
-
|
|
20
|
-
|
|
19
|
+
- Important: BE SURE you read and understand the project setup by reading the
|
|
20
|
+
pyproject.toml file and the Makefile.
|
|
21
21
|
|
|
22
|
-
-
|
|
22
|
+
- ALWAYS use uv for running all code and managing dependencies.
|
|
23
23
|
Never use direct `pip` or `python` commands.
|
|
24
24
|
|
|
25
25
|
- Use modern uv commands: `uv sync`, `uv run ...`, etc.
|
|
@@ -56,10 +56,13 @@ Always use full type annotations, generics, and other modern practices.
|
|
|
56
56
|
- Be sure to resolve the pyright (basedpyright) linter errors as you develop and make
|
|
57
57
|
changes.
|
|
58
58
|
|
|
59
|
-
- If type checker errors are hard to resolve,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
- If type checker errors are hard to resolve, you may add a comment `# pyright: ignore`
|
|
60
|
+
to disable Pyright warnings or errors but ONLY if you know they are not a real problem
|
|
61
|
+
and are difficult to fix.
|
|
62
|
+
|
|
63
|
+
- In special cases you may consider disabling it globally it in pyproject.toml but YOU
|
|
64
|
+
MUST ASK FOR CONFIRMATION from the user before globally disabling lint or type checker
|
|
65
|
+
rules.
|
|
63
66
|
|
|
64
67
|
- Never change an existing comment, pydoc, or a log statement, unless it is directly
|
|
65
68
|
fixing the issue you are changing, or the user has asked you to clean up the code.
|
|
@@ -87,18 +90,27 @@ Always use full type annotations, generics, and other modern practices.
|
|
|
87
90
|
- Use strif's `atomic_output_file` context manager when writing files to ensure output
|
|
88
91
|
files are written atomically.
|
|
89
92
|
|
|
90
|
-
|
|
93
|
+
## Use Modern Python Practices
|
|
94
|
+
|
|
95
|
+
- ALWAYS use `@override` decorators to override methods from base classes.
|
|
96
|
+
This is a modern Python practice and helps avoid bugs.
|
|
91
97
|
|
|
92
98
|
## Testing
|
|
93
99
|
|
|
94
|
-
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
100
|
+
- For longer tests put them in a file like `tests/test_somename.py` in the `tests/`
|
|
101
|
+
directory (or `tests/module_name/test_somename.py` file for a submodule).
|
|
102
|
+
|
|
103
|
+
- For simple tests, prefer inline functions in the original code file below a `## Tests`
|
|
104
|
+
comment. This keeps the tests easy to maintain and close to the code.
|
|
105
|
+
Inline tests should NOT import pytest or pytest fixtures as we do not want runtime
|
|
106
|
+
dependency on pytest.
|
|
107
|
+
|
|
108
|
+
- DO NOT write one-off test code in extra files that are throwaway.
|
|
98
109
|
|
|
99
|
-
-
|
|
110
|
+
- DO NOT put `if __name__ == "__main__":` just for quick testing.
|
|
111
|
+
Instead use the inline function tests and run them with `uv run pytest`.
|
|
100
112
|
|
|
101
|
-
-
|
|
113
|
+
- You can run such individual tests with `uv run pytest -s src/.../path/to/test`
|
|
102
114
|
|
|
103
115
|
- Don't add docs to assertions unless it's not obvious what they're checking - the
|
|
104
116
|
assertion appears in the stack trace.
|
|
@@ -106,16 +118,19 @@ Always use full type annotations, generics, and other modern practices.
|
|
|
106
118
|
x is 5`. That is redundant.
|
|
107
119
|
Just write `assert x == 5`.
|
|
108
120
|
|
|
121
|
+
- DO NOT write trivial or obvious tests that are evident directly from code, such as
|
|
122
|
+
assertions that confirm the value of a constant setting.
|
|
123
|
+
|
|
109
124
|
- NEVER write `assert False`. If a test reaches an unexpected branch and must fail
|
|
110
125
|
explicitly, `raise AssertionError("Explanation")` instead.
|
|
111
126
|
This is best typical best practice in Python since assertions can be removed with
|
|
112
127
|
optimization.
|
|
113
128
|
|
|
114
|
-
-
|
|
129
|
+
- DO NOT use pytest fixtures like parameterized tests or expected exception decorators
|
|
115
130
|
unless absolutely necessary in more complex tests.
|
|
116
|
-
It is
|
|
117
|
-
This is preferable because then
|
|
118
|
-
|
|
131
|
+
It is typically simpler to use simple assertions and put the checks inside the test.
|
|
132
|
+
This is also preferable because then simple tests have no explicit pytest dependencies
|
|
133
|
+
and can be placed in code anywhere.
|
|
119
134
|
|
|
120
135
|
## Types and Type Annotations
|
|
121
136
|
|
|
@@ -147,7 +162,7 @@ Always use full type annotations, generics, and other modern practices.
|
|
|
147
162
|
binary = "binary"
|
|
148
163
|
```
|
|
149
164
|
|
|
150
|
-
## Guidelines for
|
|
165
|
+
## Guidelines for Literal Strings
|
|
151
166
|
|
|
152
167
|
- For multi-line strings NEVER put multi-line strings flush against the left margin.
|
|
153
168
|
ALWAYS use a `dedent()` function to make it more readable.
|
|
@@ -163,6 +178,22 @@ Always use full type annotations, generics, and other modern practices.
|
|
|
163
178
|
""").strip()
|
|
164
179
|
```
|
|
165
180
|
|
|
181
|
+
## Guidelines for Comments
|
|
182
|
+
|
|
183
|
+
- Comments should be EXPLANATORY: Explain *WHY* something is done a certain way and not
|
|
184
|
+
just *what* is done.
|
|
185
|
+
|
|
186
|
+
- Comments should be CONCISE: Remove all extraneous words.
|
|
187
|
+
|
|
188
|
+
- DO NOT use comments to state obvious things or repeat what is evident from the code.
|
|
189
|
+
Here is an example of a comment that SHOULD BE REMOVED because it simply repeats the
|
|
190
|
+
code, which is distracting and adds no value:
|
|
191
|
+
```python
|
|
192
|
+
if self.failed == 0:
|
|
193
|
+
# All successful
|
|
194
|
+
return "All tasks finished successfully"
|
|
195
|
+
```
|
|
196
|
+
|
|
166
197
|
## Guidelines for Docstrings
|
|
167
198
|
|
|
168
199
|
- Here is an example of the correct style for docstrings:
|
|
@@ -204,8 +235,9 @@ Always use full type annotations, generics, and other modern practices.
|
|
|
204
235
|
- Docstrings *should* mention any key rationale or pitfalls when using the class or
|
|
205
236
|
function.
|
|
206
237
|
|
|
207
|
-
-
|
|
208
|
-
|
|
238
|
+
- Avoid obvious or repetitive docstrings.
|
|
239
|
+
Do NOT add pydocs that just repeat in English facts that are obvious from the function
|
|
240
|
+
name, variable name, or types.
|
|
209
241
|
That is silly and obvious and makes the code longer for no reason.
|
|
210
242
|
|
|
211
243
|
- Do NOT list args and return values if they're obvious.
|
|
@@ -220,11 +252,24 @@ Always use full type annotations, generics, and other modern practices.
|
|
|
220
252
|
|
|
221
253
|
## General Clean Coding Practices
|
|
222
254
|
|
|
223
|
-
-
|
|
224
|
-
For
|
|
255
|
+
- Avoid writing trivial wrapper functions.
|
|
256
|
+
For example, when writing a class DO NOT blindly make delegation methods around public
|
|
257
|
+
member variables. DO NOT write methods like this:
|
|
225
258
|
```python
|
|
226
259
|
def reassemble(self) -> str:
|
|
227
260
|
"""Call the original reassemble method."""
|
|
228
261
|
return self.paragraph.reassemble()
|
|
229
262
|
```
|
|
230
263
|
In general, the user can just call the enclosed objects methods, reducing code bloat.
|
|
264
|
+
|
|
265
|
+
- If a function does not use a parameter, but it should still be present, you can use `#
|
|
266
|
+
pyright: ignore[reportUnusedParameter]` in a comment to suppress the linter warning.
|
|
267
|
+
|
|
268
|
+
## Guidelines for Backward Compatibility
|
|
269
|
+
|
|
270
|
+
- When changing code in a library or general function, if a change to an API or library
|
|
271
|
+
will break backward compatibility, MENTION THIS to the user.
|
|
272
|
+
|
|
273
|
+
- DO NOT implement additional code for backward compatiblity (such as extra methods or
|
|
274
|
+
variable aliases or comments about backward compatibility) UNLESS the user has
|
|
275
|
+
confirmed that it is necessary.
|
|
@@ -42,7 +42,7 @@ jobs:
|
|
|
42
42
|
uses: astral-sh/setup-uv@v5
|
|
43
43
|
with:
|
|
44
44
|
# Update this as needed:
|
|
45
|
-
version: "0.7.
|
|
45
|
+
version: "0.7.13"
|
|
46
46
|
enable-cache: true
|
|
47
47
|
python-version: ${{ matrix.python-version }}
|
|
48
48
|
|
|
@@ -56,7 +56,7 @@ jobs:
|
|
|
56
56
|
# python-version: ${{ matrix.python-version }}
|
|
57
57
|
|
|
58
58
|
- name: Install all dependencies
|
|
59
|
-
run: uv sync --all-extras
|
|
59
|
+
run: uv sync --all-extras
|
|
60
60
|
|
|
61
61
|
- name: Run linting
|
|
62
62
|
run: uv run python devtools/lint.py
|
|
@@ -25,7 +25,7 @@ jobs:
|
|
|
25
25
|
- name: Install uv (official Astral action)
|
|
26
26
|
uses: astral-sh/setup-uv@v5
|
|
27
27
|
with:
|
|
28
|
-
version: "0.7.
|
|
28
|
+
version: "0.7.13"
|
|
29
29
|
enable-cache: true
|
|
30
30
|
python-version: "3.12"
|
|
31
31
|
|
|
@@ -33,7 +33,7 @@ jobs:
|
|
|
33
33
|
run: uv python install
|
|
34
34
|
|
|
35
35
|
- name: Install all dependencies
|
|
36
|
-
run: uv sync --all-extras
|
|
36
|
+
run: uv sync --all-extras
|
|
37
37
|
|
|
38
38
|
- name: Run tests
|
|
39
39
|
run: uv run pytest
|
|
@@ -43,5 +43,8 @@ jobs:
|
|
|
43
43
|
- name: Build package
|
|
44
44
|
run: uv build
|
|
45
45
|
|
|
46
|
-
- name: Publish to PyPI
|
|
47
|
-
|
|
46
|
+
- name: Publish to PyPI
|
|
47
|
+
run: uv publish --trusted-publishing always
|
|
48
|
+
# Although uv is newer and faster, the "official" publishing option is the one from PyPA,
|
|
49
|
+
# which uses twine. If desired, replace `uv publish` with:
|
|
50
|
+
# uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
default: agent-rules install lint test
|
|
10
10
|
|
|
11
11
|
install:
|
|
12
|
-
uv sync --all-extras
|
|
12
|
+
uv sync --all-extras
|
|
13
13
|
|
|
14
14
|
lint:
|
|
15
15
|
uv run python devtools/lint.py
|
|
@@ -18,7 +18,10 @@ test:
|
|
|
18
18
|
uv run pytest
|
|
19
19
|
|
|
20
20
|
test-full:
|
|
21
|
-
|
|
21
|
+
ENABLE_TESTS_ONLINE=1 ENABLE_TESTS_INTEGRATION=1 uv run pytest
|
|
22
|
+
|
|
23
|
+
run: install lint test
|
|
24
|
+
uv run kash
|
|
22
25
|
|
|
23
26
|
upgrade:
|
|
24
27
|
uv sync --upgrade --all-extras --dev
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kash-shell
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.21
|
|
4
4
|
Summary: The knowledge agent shell (core)
|
|
5
5
|
Project-URL: Repository, https://github.com/jlevy/kash-shell
|
|
6
6
|
Author-email: Joshua Levy <joshua@cal.berkeley.edu>
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
17
|
Classifier: Typing :: Typed
|
|
18
18
|
Requires-Python: <4.0,>=3.11
|
|
19
|
+
Requires-Dist: aiolimiter>=1.2.1
|
|
19
20
|
Requires-Dist: anyio>=4.8.0
|
|
20
21
|
Requires-Dist: audioop-lts>=0.2.1; python_version >= '3.13'
|
|
21
22
|
Requires-Dist: cachetools>=5.5.2
|
|
@@ -50,6 +51,7 @@ Requires-Dist: pydantic>=2.10.6
|
|
|
50
51
|
Requires-Dist: pydub>=0.25.1
|
|
51
52
|
Requires-Dist: pygments>=2.19.1
|
|
52
53
|
Requires-Dist: pyperclip>=1.9.0
|
|
54
|
+
Requires-Dist: pyrate-limiter>=3.7.0
|
|
53
55
|
Requires-Dist: python-dotenv>=1.0.1
|
|
54
56
|
Requires-Dist: python-magic-bin>=0.4.14; platform_system == 'Windows'
|
|
55
57
|
Requires-Dist: python-magic>=0.4.27; platform_system == 'Linux' or platform_system == 'Darwin'
|
|
@@ -115,7 +117,7 @@ the Python framework, a few core utilities, and the Kash command-line shell.
|
|
|
115
117
|
Additional actions for handling more complex tasks like converting documents and
|
|
116
118
|
transcribing, researching, or annotating videos, are in the
|
|
117
119
|
[kash-docs](https://github.com/jlevy/kash-docs) and
|
|
118
|
-
[kash-media](https://github.com/jlevy/kash-
|
|
120
|
+
[kash-media](https://github.com/jlevy/kash-media) packages, all available on PyPI and
|
|
119
121
|
quick to install via uv.
|
|
120
122
|
|
|
121
123
|
### Key Concepts
|
|
@@ -43,7 +43,7 @@ the Python framework, a few core utilities, and the Kash command-line shell.
|
|
|
43
43
|
Additional actions for handling more complex tasks like converting documents and
|
|
44
44
|
transcribing, researching, or annotating videos, are in the
|
|
45
45
|
[kash-docs](https://github.com/jlevy/kash-docs) and
|
|
46
|
-
[kash-media](https://github.com/jlevy/kash-
|
|
46
|
+
[kash-media](https://github.com/jlevy/kash-media) packages, all available on PyPI and
|
|
47
47
|
quick to install via uv.
|
|
48
48
|
|
|
49
49
|
### Key Concepts
|
|
@@ -17,11 +17,11 @@ The `Makefile` simply offers shortcuts to `uv` commands for developer convenienc
|
|
|
17
17
|
|
|
18
18
|
```shell
|
|
19
19
|
# First, install all dependencies and set up your virtual environment.
|
|
20
|
-
# This simply runs `uv sync --all-extras
|
|
20
|
+
# This simply runs `uv sync --all-extras` to install all packages,
|
|
21
21
|
# including dev dependencies and optional dependencies.
|
|
22
22
|
make install
|
|
23
23
|
|
|
24
|
-
# Run uv sync, lint, and test:
|
|
24
|
+
# Run uv sync, lint, and test (and also generate agent rules):
|
|
25
25
|
make
|
|
26
26
|
|
|
27
27
|
# Build wheel:
|
|
@@ -66,6 +66,17 @@ source .venv/bin/activate
|
|
|
66
66
|
|
|
67
67
|
See [uv docs](https://docs.astral.sh/uv/) for details.
|
|
68
68
|
|
|
69
|
+
## Agent Rules
|
|
70
|
+
|
|
71
|
+
See [.cursor/rules](.cursor/rules) for agent rules.
|
|
72
|
+
These are written for [Cursor](https://www.cursor.com/) but are also used by other
|
|
73
|
+
agents because the Makefile will generate `CLAUDE.md` and `AGENTS.md` from the same
|
|
74
|
+
rules.
|
|
75
|
+
|
|
76
|
+
```shell
|
|
77
|
+
make agent-rules
|
|
78
|
+
```
|
|
79
|
+
|
|
69
80
|
## IDE setup
|
|
70
81
|
|
|
71
82
|
If you use VSCode or a fork like Cursor or Windsurf, you can install the following
|
|
@@ -77,10 +77,12 @@ dependencies = [
|
|
|
77
77
|
"pathspec>=0.12.1",
|
|
78
78
|
"patch-ng>=1.18.1",
|
|
79
79
|
"inquirerpy>=0.3.4",
|
|
80
|
-
# LLM essentials:
|
|
80
|
+
# LLM and API essentials:
|
|
81
81
|
"tiktoken>=0.9.0",
|
|
82
82
|
"openai>=1.66.3",
|
|
83
83
|
"litellm>=1.63.11",
|
|
84
|
+
"pyrate-limiter>=3.7.0",
|
|
85
|
+
"aiolimiter>=1.2.1",
|
|
84
86
|
# Basic text handling and web scraping:
|
|
85
87
|
"readabilipy>=0.3.0",
|
|
86
88
|
"markdownify>=0.13.1",
|
|
@@ -223,6 +225,7 @@ reportMissingParameterType = false
|
|
|
223
225
|
reportUnannotatedClassAttribute = false
|
|
224
226
|
reportUninitializedInstanceVariable = false
|
|
225
227
|
reportCallInDefaultInitializer = false
|
|
228
|
+
reportUntypedBaseClass = false
|
|
226
229
|
# Make ignoring easier:
|
|
227
230
|
reportIgnoreCommentWithoutRule = false
|
|
228
231
|
reportUnnecessaryTypeIgnoreComment = false
|
|
@@ -11,13 +11,10 @@ from kash.web_content.web_extract_readabilipy import extract_text_readabilipy
|
|
|
11
11
|
log = get_logger(__name__)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
@kash_action(
|
|
15
|
-
|
|
16
|
-
mcp_tool=True,
|
|
17
|
-
)
|
|
18
|
-
def markdownify(item: Item) -> Item:
|
|
14
|
+
@kash_action(precondition=is_url_resource | has_html_body, mcp_tool=True)
|
|
15
|
+
def markdownify_html(item: Item) -> Item:
|
|
19
16
|
"""
|
|
20
|
-
Converts
|
|
17
|
+
Converts raw HTML or the URL of an HTML page to Markdown, fetching with the content
|
|
21
18
|
cache if needed. Also uses readability to clean up the HTML.
|
|
22
19
|
"""
|
|
23
20
|
|
|
@@ -23,14 +23,12 @@ from kash.exec import (
|
|
|
23
23
|
resolve_locator_arg,
|
|
24
24
|
)
|
|
25
25
|
from kash.exec.action_registry import get_all_actions_defaults
|
|
26
|
-
from kash.exec.
|
|
26
|
+
from kash.exec.fetch_url_items import fetch_url_item
|
|
27
27
|
from kash.exec.precondition_checks import actions_matching_paths
|
|
28
28
|
from kash.exec.precondition_registry import get_all_preconditions
|
|
29
|
-
from kash.exec.preconditions import is_url_resource
|
|
30
29
|
from kash.exec_model.shell_model import ShellResult
|
|
31
30
|
from kash.local_server.local_url_formatters import local_url_formatter
|
|
32
31
|
from kash.media_base import media_tools
|
|
33
|
-
from kash.media_base.media_services import is_media_url
|
|
34
32
|
from kash.model.items_model import Item, ItemType
|
|
35
33
|
from kash.model.params_model import GLOBAL_PARAMS
|
|
36
34
|
from kash.model.paths_model import StorePath, fmt_store_path
|
|
@@ -54,12 +52,11 @@ from kash.utils.common.format_utils import fmt_loc
|
|
|
54
52
|
from kash.utils.common.obj_replace import remove_values
|
|
55
53
|
from kash.utils.common.parse_key_vals import parse_key_value
|
|
56
54
|
from kash.utils.common.type_utils import not_none
|
|
57
|
-
from kash.utils.common.url import Url
|
|
55
|
+
from kash.utils.common.url import Url
|
|
58
56
|
from kash.utils.errors import InvalidInput
|
|
59
57
|
from kash.utils.file_formats.chat_format import tail_chat_history
|
|
60
58
|
from kash.utils.file_utils.dir_info import is_nonempty_dir
|
|
61
59
|
from kash.utils.file_utils.file_formats_model import Format
|
|
62
|
-
from kash.utils.text_handling.doc_normalization import can_normalize
|
|
63
60
|
from kash.web_content.file_cache_utils import cache_file
|
|
64
61
|
from kash.workspaces import (
|
|
65
62
|
current_ws,
|
|
@@ -189,85 +186,6 @@ def cache_content(*urls_or_paths: str, refetch: bool = False) -> None:
|
|
|
189
186
|
PrintHooks.spacer()
|
|
190
187
|
|
|
191
188
|
|
|
192
|
-
@kash_command
|
|
193
|
-
def download(*urls_or_paths: str, refetch: bool = False, no_format: bool = False) -> ShellResult:
|
|
194
|
-
"""
|
|
195
|
-
Download a URL or resource. Uses cached content if available, unless `refetch` is true.
|
|
196
|
-
Inputs can be URLs or paths to URL resources.
|
|
197
|
-
Creates both resource and document versions for text content.
|
|
198
|
-
|
|
199
|
-
:param no_format: If true, do not also normalize Markdown content.
|
|
200
|
-
"""
|
|
201
|
-
ws = current_ws()
|
|
202
|
-
saved_paths = []
|
|
203
|
-
|
|
204
|
-
for url_or_path in urls_or_paths:
|
|
205
|
-
locator = resolve_locator_arg(url_or_path)
|
|
206
|
-
url: Url | None = None
|
|
207
|
-
|
|
208
|
-
# Get the URL from the locator
|
|
209
|
-
if not isinstance(locator, Path) and is_url(locator):
|
|
210
|
-
url = Url(locator)
|
|
211
|
-
elif isinstance(locator, StorePath):
|
|
212
|
-
url_item = ws.load(locator)
|
|
213
|
-
if is_url_resource(url_item):
|
|
214
|
-
url = url_item.url
|
|
215
|
-
|
|
216
|
-
if not url:
|
|
217
|
-
raise InvalidInput(f"Not a URL or URL resource: {fmt_loc(locator)}")
|
|
218
|
-
|
|
219
|
-
# Handle media URLs differently
|
|
220
|
-
if is_media_url(url):
|
|
221
|
-
log.message(
|
|
222
|
-
"URL is a media URL, so adding as a resource and will cache media: %s", fmt_loc(url)
|
|
223
|
-
)
|
|
224
|
-
store_path = ws.import_item(url, as_type=ItemType.resource, reimport=refetch)
|
|
225
|
-
saved_paths.append(store_path)
|
|
226
|
-
media_tools.cache_media(url)
|
|
227
|
-
else:
|
|
228
|
-
# Cache the content first
|
|
229
|
-
expiration_sec = 0 if refetch else None
|
|
230
|
-
cache_result = cache_file(url, expiration_sec=expiration_sec)
|
|
231
|
-
original_filename = Path(parse_http_url(url).path).name
|
|
232
|
-
mime_type = cache_result.content.headers and cache_result.content.headers.mime_type
|
|
233
|
-
|
|
234
|
-
# Create a resource item
|
|
235
|
-
resource_item = Item.from_external_path(
|
|
236
|
-
cache_result.content.path,
|
|
237
|
-
ItemType.resource,
|
|
238
|
-
url=url,
|
|
239
|
-
mime_type=mime_type,
|
|
240
|
-
original_filename=original_filename,
|
|
241
|
-
)
|
|
242
|
-
# For initial content, do not format or add frontmatter.
|
|
243
|
-
store_path = ws.save(resource_item, no_frontmatter=True, no_format=True)
|
|
244
|
-
saved_paths.append(store_path)
|
|
245
|
-
select(store_path)
|
|
246
|
-
|
|
247
|
-
# Also create a doc version for text content if we want to normalize formatting.
|
|
248
|
-
if resource_item.format and can_normalize(resource_item.format) and not no_format:
|
|
249
|
-
doc_item = Item.from_external_path(
|
|
250
|
-
cache_result.content.path,
|
|
251
|
-
ItemType.doc,
|
|
252
|
-
url=url,
|
|
253
|
-
mime_type=mime_type,
|
|
254
|
-
original_filename=original_filename,
|
|
255
|
-
)
|
|
256
|
-
# Now use default formatting and frontmatter.
|
|
257
|
-
doc_store_path = ws.save(doc_item)
|
|
258
|
-
saved_paths.append(doc_store_path)
|
|
259
|
-
select(doc_store_path)
|
|
260
|
-
|
|
261
|
-
print_status(
|
|
262
|
-
"Downloaded %s %s:\n%s",
|
|
263
|
-
len(saved_paths),
|
|
264
|
-
plural("item", len(saved_paths)),
|
|
265
|
-
fmt_lines(saved_paths),
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
return ShellResult(show_selection=True)
|
|
269
|
-
|
|
270
|
-
|
|
271
189
|
@kash_command
|
|
272
190
|
def history(max: int = 30, raw: bool = False) -> None:
|
|
273
191
|
"""
|
|
@@ -536,10 +454,14 @@ def save_clipboard(
|
|
|
536
454
|
|
|
537
455
|
|
|
538
456
|
@kash_command
|
|
539
|
-
def
|
|
457
|
+
def fetch_url(*files_or_urls: str, refetch: bool = False) -> ShellResult:
|
|
540
458
|
"""
|
|
541
|
-
Fetch metadata for the given URLs or resources
|
|
542
|
-
|
|
459
|
+
Fetch content and metadata for the given URLs or resources, saving to the
|
|
460
|
+
current workspace.
|
|
461
|
+
|
|
462
|
+
Imports new URLs and saves back the fetched metadata for existing resources.
|
|
463
|
+
Also saves a resource item with the content of the URL, either HTML, text, or
|
|
464
|
+
of any other type.
|
|
543
465
|
|
|
544
466
|
Skips items that already have a title and description, unless `refetch` is true.
|
|
545
467
|
Skips (with a warning) items that are not URL resources.
|
|
@@ -552,7 +474,7 @@ def fetch_metadata(*files_or_urls: str, refetch: bool = False) -> ShellResult:
|
|
|
552
474
|
store_paths = []
|
|
553
475
|
for locator in locators:
|
|
554
476
|
try:
|
|
555
|
-
fetched_item =
|
|
477
|
+
fetched_item = fetch_url_item(locator, refetch=refetch)
|
|
556
478
|
store_paths.append(fetched_item.store_path)
|
|
557
479
|
except InvalidInput as e:
|
|
558
480
|
log.warning(
|
|
@@ -139,14 +139,15 @@ web_light_translucent = SimpleNamespace(
|
|
|
139
139
|
bg_header=hsl_to_hex("hsla(188, 42%, 70%, 0.2)"),
|
|
140
140
|
bg_alt=hsl_to_hex("hsla(39, 24%, 90%, 0.3)"),
|
|
141
141
|
bg_alt_solid=hsl_to_hex("hsla(39, 24%, 97%, 1)"),
|
|
142
|
-
|
|
142
|
+
bg_meta_solid=hsl_to_hex("hsla(39, 24%, 94%, 1)"),
|
|
143
|
+
bg_selected=hsl_to_hex("hsla(188, 21%, 94%, 0.9)"),
|
|
143
144
|
text=hsl_to_hex("hsl(188, 39%, 11%)"),
|
|
144
145
|
code=hsl_to_hex("hsl(44, 38%, 23%)"),
|
|
145
146
|
border=hsl_to_hex("hsl(188, 8%, 50%)"),
|
|
146
147
|
border_hint=hsl_to_hex("hsla(188, 8%, 72%, 0.3)"),
|
|
147
148
|
border_accent=hsl_to_hex("hsla(305, 18%, 65%, 0.85)"),
|
|
148
149
|
hover=hsl_to_hex("hsl(188, 12%, 84%)"),
|
|
149
|
-
hover_bg=hsl_to_hex("hsla(188,
|
|
150
|
+
hover_bg=hsl_to_hex("hsla(188, 18%, 97%, 1)"),
|
|
150
151
|
hint=hsl_to_hex("hsl(188, 11%, 65%)"),
|
|
151
152
|
hint_strong=hsl_to_hex("hsl(188, 11%, 46%)"),
|
|
152
153
|
hint_gentle=hsl_to_hex("hsla(188, 11%, 65%, 0.2)"),
|
|
@@ -165,14 +166,15 @@ web_light_translucent = SimpleNamespace(
|
|
|
165
166
|
web_dark_translucent = SimpleNamespace(
|
|
166
167
|
primary=hsl_to_hex("hsl(188, 40%, 62%)"),
|
|
167
168
|
primary_light=hsl_to_hex("hsl(188, 50%, 72%)"),
|
|
168
|
-
secondary=hsl_to_hex("hsl(188, 12%,
|
|
169
|
-
tertiary=hsl_to_hex("hsl(188, 7%,
|
|
169
|
+
secondary=hsl_to_hex("hsl(188, 12%, 70%)"),
|
|
170
|
+
tertiary=hsl_to_hex("hsl(188, 7%, 45%)"),
|
|
170
171
|
bg=hsl_to_hex("hsla(220, 14%, 7%, 0.95)"),
|
|
171
172
|
bg_solid=hsl_to_hex("hsl(220, 14%, 7%)"),
|
|
172
173
|
bg_header=hsl_to_hex("hsla(188, 42%, 20%, 0.3)"),
|
|
173
174
|
bg_alt=hsl_to_hex("hsla(220, 14%, 12%, 0.5)"),
|
|
174
|
-
bg_alt_solid=hsl_to_hex("hsl(220,
|
|
175
|
-
|
|
175
|
+
bg_alt_solid=hsl_to_hex("hsl(220, 15%, 16%)"),
|
|
176
|
+
bg_meta_solid=hsl_to_hex("hsl(220, 14%, 25%)"),
|
|
177
|
+
bg_selected=hsl_to_hex("hsla(188, 13%, 33%, 0.95)"),
|
|
176
178
|
text=hsl_to_hex("hsl(188, 10%, 90%)"),
|
|
177
179
|
code=hsl_to_hex("hsl(44, 38%, 72%)"),
|
|
178
180
|
border=hsl_to_hex("hsl(188, 8%, 25%)"),
|
|
@@ -34,7 +34,7 @@ the Python framework, a few core utilities, and the Kash command-line shell.
|
|
|
34
34
|
Additional actions for handling more complex tasks like converting documents and
|
|
35
35
|
transcribing, researching, or annotating videos, are in the
|
|
36
36
|
[kash-docs](https://github.com/jlevy/kash-docs) and
|
|
37
|
-
[kash-media](https://github.com/jlevy/kash-
|
|
37
|
+
[kash-media](https://github.com/jlevy/kash-media) packages, all available on PyPI and
|
|
38
38
|
quick to install via uv.
|
|
39
39
|
|
|
40
40
|
### Key Concepts
|