code-muse 0.0.1__py3-none-any.whl
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.
- code_muse/__init__.py +26 -0
- code_muse/__main__.py +10 -0
- code_muse/agents/__init__.py +31 -0
- code_muse/agents/_builder.py +214 -0
- code_muse/agents/_compaction.py +506 -0
- code_muse/agents/_diagnostics.py +171 -0
- code_muse/agents/_history.py +382 -0
- code_muse/agents/_key_listeners.py +148 -0
- code_muse/agents/_non_streaming_render.py +148 -0
- code_muse/agents/_runtime.py +596 -0
- code_muse/agents/agent_creator_agent.py +603 -0
- code_muse/agents/agent_helios.py +47 -0
- code_muse/agents/agent_manager.py +740 -0
- code_muse/agents/agent_muse.py +78 -0
- code_muse/agents/agent_planning.py +44 -0
- code_muse/agents/agent_qa_melpomene.py +207 -0
- code_muse/agents/base_agent.py +194 -0
- code_muse/agents/event_stream_handler.py +361 -0
- code_muse/agents/json_agent.py +201 -0
- code_muse/agents/prompt_v3.py +521 -0
- code_muse/agents/subagent_stream_handler.py +273 -0
- code_muse/callbacks.py +941 -0
- code_muse/chatgpt_codex_client.py +333 -0
- code_muse/claude_cache_client.py +853 -0
- code_muse/cli_runner/__init__.py +319 -0
- code_muse/cli_runner/args.py +63 -0
- code_muse/cli_runner/loop.py +510 -0
- code_muse/cli_runner/resume.py +72 -0
- code_muse/cli_runner/runner.py +161 -0
- code_muse/command_line/__init__.py +1 -0
- code_muse/command_line/add_model_menu.py +1331 -0
- code_muse/command_line/agent_menu.py +674 -0
- code_muse/command_line/attachments.py +397 -0
- code_muse/command_line/autosave_menu.py +709 -0
- code_muse/command_line/clipboard.py +528 -0
- code_muse/command_line/colors_menu.py +530 -0
- code_muse/command_line/command_handler.py +262 -0
- code_muse/command_line/command_registry.py +150 -0
- code_muse/command_line/config_commands.py +711 -0
- code_muse/command_line/core_commands.py +740 -0
- code_muse/command_line/diff_menu.py +865 -0
- code_muse/command_line/file_path_completion.py +73 -0
- code_muse/command_line/load_context_completion.py +57 -0
- code_muse/command_line/model_picker_completion.py +512 -0
- code_muse/command_line/model_settings_menu.py +983 -0
- code_muse/command_line/onboarding_slides.py +162 -0
- code_muse/command_line/onboarding_wizard.py +337 -0
- code_muse/command_line/pagination.py +41 -0
- code_muse/command_line/pin_command_completion.py +329 -0
- code_muse/command_line/prompt_toolkit_completion.py +886 -0
- code_muse/command_line/session_commands.py +304 -0
- code_muse/command_line/shell_passthrough.py +145 -0
- code_muse/command_line/skills_completion.py +158 -0
- code_muse/command_line/types.py +18 -0
- code_muse/command_line/uc_menu.py +908 -0
- code_muse/command_line/utils.py +105 -0
- code_muse/command_line/wiggum_state.py +77 -0
- code_muse/config.py +1138 -0
- code_muse/config_agent.py +168 -0
- code_muse/config_appearance.py +241 -0
- code_muse/config_model.py +357 -0
- code_muse/config_security.py +73 -0
- code_muse/error_logging.py +132 -0
- code_muse/evals/__init__.py +35 -0
- code_muse/evals/eval_helpers.py +81 -0
- code_muse/evals/eval_runner.py +299 -0
- code_muse/evals/sample_evals/__init__.py +1 -0
- code_muse/evals/sample_evals/eval_frugal_reads.py +59 -0
- code_muse/evals/sample_evals/eval_memory_planning.py +31 -0
- code_muse/evals/sample_evals/eval_shell_efficiency.py +39 -0
- code_muse/evals/sample_evals/eval_tool_masking.py +33 -0
- code_muse/fs_scan_cache/__init__.py +31 -0
- code_muse/fs_scan_cache/invalidation_hooks.py +89 -0
- code_muse/fs_scan_cache/scan_cache_core.cpython-314-darwin.so +0 -0
- code_muse/fs_scan_cache/scan_cache_core.pyx +203 -0
- code_muse/fs_scan_cache/tool_integration.py +309 -0
- code_muse/fs_scan_cache/ttl_policy.py +44 -0
- code_muse/gemini_code_assist.py +383 -0
- code_muse/gemini_model.py +838 -0
- code_muse/hook_engine/README.md +105 -0
- code_muse/hook_engine/__init__.py +21 -0
- code_muse/hook_engine/aliases.py +153 -0
- code_muse/hook_engine/engine.py +221 -0
- code_muse/hook_engine/executor.py +347 -0
- code_muse/hook_engine/matcher.py +154 -0
- code_muse/hook_engine/models.py +245 -0
- code_muse/hook_engine/registry.py +114 -0
- code_muse/hook_engine/trust.py +268 -0
- code_muse/hook_engine/validator.py +144 -0
- code_muse/http_utils.py +360 -0
- code_muse/keymap.py +128 -0
- code_muse/list_filtering.py +26 -0
- code_muse/main.py +10 -0
- code_muse/messaging/__init__.py +259 -0
- code_muse/messaging/bus.py +621 -0
- code_muse/messaging/commands.py +166 -0
- code_muse/messaging/markdown_patches.py +57 -0
- code_muse/messaging/message_queue.py +397 -0
- code_muse/messaging/messages.py +591 -0
- code_muse/messaging/queue_console.py +269 -0
- code_muse/messaging/renderers.py +308 -0
- code_muse/messaging/rich_renderer.py +1158 -0
- code_muse/messaging/shimmer.py +154 -0
- code_muse/messaging/spinner/__init__.py +87 -0
- code_muse/messaging/spinner/console_spinner.py +250 -0
- code_muse/messaging/spinner/spinner_base.py +82 -0
- code_muse/messaging/subagent_console.py +458 -0
- code_muse/model_factory.py +1203 -0
- code_muse/model_switching.py +59 -0
- code_muse/model_utils.py +156 -0
- code_muse/models.json +66 -0
- code_muse/models_cache/__init__.py +26 -0
- code_muse/models_cache/blocking_lru_cache.py +98 -0
- code_muse/models_cache/cache_writer.py +86 -0
- code_muse/models_cache/sha256_hash.cpython-314-darwin.so +0 -0
- code_muse/models_cache/sha256_hash.pyx +34 -0
- code_muse/models_cache/startup_integration.py +75 -0
- code_muse/models_dev_api.json +1 -0
- code_muse/models_dev_parser.py +590 -0
- code_muse/motion.py +126 -0
- code_muse/plugins/__init__.py +471 -0
- code_muse/plugins/agent_skills/__init__.py +32 -0
- code_muse/plugins/agent_skills/config.py +176 -0
- code_muse/plugins/agent_skills/discovery.py +309 -0
- code_muse/plugins/agent_skills/downloader.py +389 -0
- code_muse/plugins/agent_skills/installer.py +19 -0
- code_muse/plugins/agent_skills/metadata.py +293 -0
- code_muse/plugins/agent_skills/prompt_builder.py +66 -0
- code_muse/plugins/agent_skills/register_callbacks.py +298 -0
- code_muse/plugins/agent_skills/remote_catalog.py +320 -0
- code_muse/plugins/agent_skills/skill_catalog.py +254 -0
- code_muse/plugins/agent_skills/skills_install_menu.py +690 -0
- code_muse/plugins/agent_skills/skills_menu.py +791 -0
- code_muse/plugins/autonomous_memory/__init__.py +39 -0
- code_muse/plugins/autonomous_memory/bm25_scorer.cpython-314-darwin.so +0 -0
- code_muse/plugins/autonomous_memory/bm25_scorer.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/autonomous_memory/bm25_scorer.pyx +291 -0
- code_muse/plugins/autonomous_memory/consolidation.py +82 -0
- code_muse/plugins/autonomous_memory/extraction.py +382 -0
- code_muse/plugins/autonomous_memory/lease_lock.py +105 -0
- code_muse/plugins/autonomous_memory/memory_injection.py +59 -0
- code_muse/plugins/autonomous_memory/register_callbacks.py +268 -0
- code_muse/plugins/autonomous_memory/secret_scanner.py +62 -0
- code_muse/plugins/autonomous_memory/session_scanner.py +163 -0
- code_muse/plugins/aws_bedrock/__init__.py +14 -0
- code_muse/plugins/aws_bedrock/config.py +99 -0
- code_muse/plugins/aws_bedrock/register_callbacks.py +241 -0
- code_muse/plugins/aws_bedrock/utils.py +153 -0
- code_muse/plugins/azure_foundry/README.md +238 -0
- code_muse/plugins/azure_foundry/__init__.py +15 -0
- code_muse/plugins/azure_foundry/config.py +125 -0
- code_muse/plugins/azure_foundry/discovery.py +187 -0
- code_muse/plugins/azure_foundry/register_callbacks.py +495 -0
- code_muse/plugins/azure_foundry/token.py +180 -0
- code_muse/plugins/azure_foundry/utils.py +345 -0
- code_muse/plugins/build_filter/__init__.py +1 -0
- code_muse/plugins/build_filter/register_callbacks.py +201 -0
- code_muse/plugins/build_filter/strategies/__init__.py +1 -0
- code_muse/plugins/build_filter/strategies/build.py +397 -0
- code_muse/plugins/chatgpt_oauth/__init__.py +6 -0
- code_muse/plugins/chatgpt_oauth/config.py +52 -0
- code_muse/plugins/chatgpt_oauth/oauth_flow.py +338 -0
- code_muse/plugins/chatgpt_oauth/register_callbacks.py +172 -0
- code_muse/plugins/chatgpt_oauth/test_plugin.py +301 -0
- code_muse/plugins/chatgpt_oauth/utils.py +538 -0
- code_muse/plugins/checkpointing/__init__.py +29 -0
- code_muse/plugins/checkpointing/checkpoint_hook.py +51 -0
- code_muse/plugins/checkpointing/conversation_snapshots.py +117 -0
- code_muse/plugins/checkpointing/register_callbacks.py +51 -0
- code_muse/plugins/checkpointing/restore_command.py +263 -0
- code_muse/plugins/checkpointing/rewind_shortcut.py +88 -0
- code_muse/plugins/checkpointing/shadow_git.py +90 -0
- code_muse/plugins/claude_code_hooks/__init__.py +1 -0
- code_muse/plugins/claude_code_hooks/config.py +188 -0
- code_muse/plugins/claude_code_hooks/register_callbacks.py +208 -0
- code_muse/plugins/claude_code_oauth/README.md +167 -0
- code_muse/plugins/claude_code_oauth/SETUP.md +93 -0
- code_muse/plugins/claude_code_oauth/__init__.py +25 -0
- code_muse/plugins/claude_code_oauth/config.py +52 -0
- code_muse/plugins/claude_code_oauth/fast_mode.py +124 -0
- code_muse/plugins/claude_code_oauth/prompt_handler.py +63 -0
- code_muse/plugins/claude_code_oauth/register_callbacks.py +547 -0
- code_muse/plugins/claude_code_oauth/test_fast_mode.py +165 -0
- code_muse/plugins/claude_code_oauth/test_plugin.py +283 -0
- code_muse/plugins/claude_code_oauth/token_refresh_heartbeat.py +237 -0
- code_muse/plugins/claude_code_oauth/utils.py +664 -0
- code_muse/plugins/copilot_auth/__init__.py +11 -0
- code_muse/plugins/copilot_auth/config.py +91 -0
- code_muse/plugins/copilot_auth/reasoning_client.py +409 -0
- code_muse/plugins/copilot_auth/register_callbacks.py +461 -0
- code_muse/plugins/copilot_auth/utils.py +584 -0
- code_muse/plugins/custom_commands/__init__.py +14 -0
- code_muse/plugins/custom_commands/args_injection.py +82 -0
- code_muse/plugins/custom_commands/command_discovery.py +89 -0
- code_muse/plugins/custom_commands/command_toml_schema.py +71 -0
- code_muse/plugins/custom_commands/register_callbacks.py +176 -0
- code_muse/plugins/customizable_commands/__init__.py +0 -0
- code_muse/plugins/customizable_commands/register_callbacks.py +136 -0
- code_muse/plugins/destructive_command_guard/__init__.py +14 -0
- code_muse/plugins/destructive_command_guard/detector.py +375 -0
- code_muse/plugins/destructive_command_guard/register_callbacks.py +148 -0
- code_muse/plugins/example_custom_command/README.md +280 -0
- code_muse/plugins/example_custom_command/register_callbacks.py +51 -0
- code_muse/plugins/file_permission_handler/__init__.py +4 -0
- code_muse/plugins/file_permission_handler/register_callbacks.py +441 -0
- code_muse/plugins/filter_engine/__init__.py +30 -0
- code_muse/plugins/filter_engine/classifier.py +153 -0
- code_muse/plugins/filter_engine/content_detector.py +184 -0
- code_muse/plugins/filter_engine/dispatcher.py +244 -0
- code_muse/plugins/filter_engine/register_callbacks.py +188 -0
- code_muse/plugins/filter_engine/registry.py +279 -0
- code_muse/plugins/filter_engine/strategies/__init__.py +8 -0
- code_muse/plugins/filter_engine/strategies/ast_compressor.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/ast_compressor.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/ast_compressor.pyx +348 -0
- code_muse/plugins/filter_engine/strategies/ast_parser.py +167 -0
- code_muse/plugins/filter_engine/strategies/code.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/code.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/code.pyx +584 -0
- code_muse/plugins/filter_engine/strategies/git.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/git.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/git.pyx +438 -0
- code_muse/plugins/filter_engine/strategies/json_compressor.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/json_compressor.pyx +253 -0
- code_muse/plugins/filter_engine/strategies/json_patterns.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/json_patterns.pyx +178 -0
- code_muse/plugins/filter_engine/strategies/lint.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/lint.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/lint.pyx +626 -0
- code_muse/plugins/filter_engine/strategies/test.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/test.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/test.pyx +431 -0
- code_muse/plugins/filter_engine/verbosity.py +63 -0
- code_muse/plugins/force_push_guard/__init__.py +5 -0
- code_muse/plugins/force_push_guard/detector.py +96 -0
- code_muse/plugins/force_push_guard/register_callbacks.py +144 -0
- code_muse/plugins/force_push_guard/test_detector.py +143 -0
- code_muse/plugins/frontend_emitter/__init__.py +25 -0
- code_muse/plugins/frontend_emitter/emitter.py +121 -0
- code_muse/plugins/frontend_emitter/register_callbacks.py +259 -0
- code_muse/plugins/gac/__init__.py +4 -0
- code_muse/plugins/gac/git_ops.py +136 -0
- code_muse/plugins/gac/prompt.py +191 -0
- code_muse/plugins/gac/register_callbacks.py +82 -0
- code_muse/plugins/hook_creator/__init__.py +1 -0
- code_muse/plugins/hook_creator/register_callbacks.py +34 -0
- code_muse/plugins/hook_manager/__init__.py +1 -0
- code_muse/plugins/hook_manager/config.py +289 -0
- code_muse/plugins/hook_manager/hooks_menu.py +563 -0
- code_muse/plugins/hook_manager/register_callbacks.py +227 -0
- code_muse/plugins/hook_monitor/register_callbacks.py +36 -0
- code_muse/plugins/mindpack/__init__.py +0 -0
- code_muse/plugins/mindpack/factory.py +930 -0
- code_muse/plugins/mindpack/judge.py +573 -0
- code_muse/plugins/mindpack/memory.py +100 -0
- code_muse/plugins/mindpack/mindpack_menu.py +1552 -0
- code_muse/plugins/mindpack/orchestration.py +605 -0
- code_muse/plugins/mindpack/register_callbacks.py +175 -0
- code_muse/plugins/mindpack/schemas.py +358 -0
- code_muse/plugins/mindpack/tools.py +387 -0
- code_muse/plugins/oauth_muse_html.py +226 -0
- code_muse/plugins/ollama_setup/__init__.py +5 -0
- code_muse/plugins/ollama_setup/completer.py +36 -0
- code_muse/plugins/ollama_setup/register_callbacks.py +410 -0
- code_muse/plugins/plan_command/__init__.py +0 -0
- code_muse/plugins/plan_command/register_callbacks.py +206 -0
- code_muse/plugins/plan_mode/__init__.py +37 -0
- code_muse/plugins/plan_mode/mode_cycling.py +40 -0
- code_muse/plugins/plan_mode/plan_generation.py +68 -0
- code_muse/plugins/plan_mode/plan_hooks.py +74 -0
- code_muse/plugins/plan_mode/plan_mode_tools.py +138 -0
- code_muse/plugins/plan_mode/register_callbacks.py +121 -0
- code_muse/plugins/plugin_trust/register_callbacks.py +140 -0
- code_muse/plugins/policy_engine/__init__.py +46 -0
- code_muse/plugins/policy_engine/approval_flow_integration.py +59 -0
- code_muse/plugins/policy_engine/policy_evaluator.py +75 -0
- code_muse/plugins/policy_engine/policy_file_discovery.py +90 -0
- code_muse/plugins/policy_engine/policy_toml_schema.py +115 -0
- code_muse/plugins/policy_engine/register_callbacks.py +112 -0
- code_muse/plugins/pop_command/__init__.py +1 -0
- code_muse/plugins/pop_command/register_callbacks.py +189 -0
- code_muse/plugins/prompt_newline/__init__.py +13 -0
- code_muse/plugins/prompt_newline/config.py +19 -0
- code_muse/plugins/prompt_newline/register_callbacks.py +159 -0
- code_muse/plugins/safety_status/__init__.py +0 -0
- code_muse/plugins/safety_status/register_callbacks.py +113 -0
- code_muse/plugins/semantic_compression/__init__.py +6 -0
- code_muse/plugins/semantic_compression/compressor.py +295 -0
- code_muse/plugins/semantic_compression/config.py +123 -0
- code_muse/plugins/semantic_compression/register_callbacks.py +320 -0
- code_muse/plugins/shell_minimizer/__init__.py +50 -0
- code_muse/plugins/shell_minimizer/builtin_filters.toml +393 -0
- code_muse/plugins/shell_minimizer/pipeline.py +556 -0
- code_muse/plugins/shell_minimizer/primitives.py +482 -0
- code_muse/plugins/shell_minimizer/register_callbacks.py +276 -0
- code_muse/plugins/shell_safety/__init__.py +6 -0
- code_muse/plugins/shell_safety/agent_shell_safety.py +69 -0
- code_muse/plugins/shell_safety/command_cache.py +149 -0
- code_muse/plugins/shell_safety/register_callbacks.py +202 -0
- code_muse/plugins/synthetic_status/__init__.py +1 -0
- code_muse/plugins/synthetic_status/register_callbacks.py +128 -0
- code_muse/plugins/synthetic_status/status_api.py +145 -0
- code_muse/plugins/token_caching/__init__.py +21 -0
- code_muse/plugins/token_caching/cache_hit_tracking.py +128 -0
- code_muse/plugins/token_caching/cacheable_prefix_detection.py +28 -0
- code_muse/plugins/token_caching/register_callbacks.py +54 -0
- code_muse/plugins/token_caching/stats_display.py +35 -0
- code_muse/plugins/token_tracking/__init__.py +26 -0
- code_muse/plugins/token_tracking/database.py +381 -0
- code_muse/plugins/token_tracking/edit_analyzer.py +97 -0
- code_muse/plugins/token_tracking/record.py +55 -0
- code_muse/plugins/token_tracking/register_callbacks.py +277 -0
- code_muse/plugins/token_tracking/reports.py +329 -0
- code_muse/plugins/universal_constructor/__init__.py +13 -0
- code_muse/plugins/universal_constructor/models.py +136 -0
- code_muse/plugins/universal_constructor/register_callbacks.py +47 -0
- code_muse/plugins/universal_constructor/registry.py +390 -0
- code_muse/plugins/universal_constructor/runner.py +474 -0
- code_muse/plugins/universal_constructor/safety.py +440 -0
- code_muse/plugins/universal_constructor/sandbox.py +584 -0
- code_muse/provider_identity.py +105 -0
- code_muse/pydantic_patches.py +410 -0
- code_muse/reopenable_async_client.py +233 -0
- code_muse/round_robin_model.py +151 -0
- code_muse/secret_storage.py +74 -0
- code_muse/security/__init__.py +1 -0
- code_muse/security/redaction.cpython-314-darwin.so +0 -0
- code_muse/security/redaction.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/security/redaction.pyx +135 -0
- code_muse/session_storage.py +565 -0
- code_muse/status_display.py +261 -0
- code_muse/stream_parser/__init__.py +76 -0
- code_muse/stream_parser/assistant_text_parser.py +90 -0
- code_muse/stream_parser/citation_parser.py +76 -0
- code_muse/stream_parser/inline_hidden_tag_parser.py +236 -0
- code_muse/stream_parser/proposed_plan_parser.py +158 -0
- code_muse/stream_parser/stream_text_chunk.py +23 -0
- code_muse/stream_parser/stream_text_parser.py +27 -0
- code_muse/stream_parser/tagged_line_parser.cpython-314-darwin.so +0 -0
- code_muse/stream_parser/tagged_line_parser.pyx +251 -0
- code_muse/stream_parser/utf8_stream_parser.cpython-314-darwin.so +0 -0
- code_muse/stream_parser/utf8_stream_parser.pyx +206 -0
- code_muse/summarization_agent.py +308 -0
- code_muse/terminal_utils.cpython-314-darwin.so +0 -0
- code_muse/terminal_utils.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/terminal_utils.pyx +483 -0
- code_muse/tools/__init__.py +459 -0
- code_muse/tools/agent_tools.py +613 -0
- code_muse/tools/ask_user_question/__init__.py +26 -0
- code_muse/tools/ask_user_question/constants.py +73 -0
- code_muse/tools/ask_user_question/demo_tui.py +55 -0
- code_muse/tools/ask_user_question/handler.py +232 -0
- code_muse/tools/ask_user_question/models.py +302 -0
- code_muse/tools/ask_user_question/registration.py +37 -0
- code_muse/tools/ask_user_question/renderers.py +336 -0
- code_muse/tools/ask_user_question/terminal_ui.py +327 -0
- code_muse/tools/ask_user_question/theme.py +156 -0
- code_muse/tools/ask_user_question/tui_loop.py +422 -0
- code_muse/tools/background_jobs.py +99 -0
- code_muse/tools/browser/__init__.py +37 -0
- code_muse/tools/browser/browser_control.py +289 -0
- code_muse/tools/browser/browser_interactions.py +545 -0
- code_muse/tools/browser/browser_locators.py +640 -0
- code_muse/tools/browser/browser_manager.py +376 -0
- code_muse/tools/browser/browser_navigation.py +251 -0
- code_muse/tools/browser/browser_screenshot.py +180 -0
- code_muse/tools/browser/browser_scripts.py +462 -0
- code_muse/tools/browser/browser_workflows.py +222 -0
- code_muse/tools/chrome_cdp/__init__.py +1070 -0
- code_muse/tools/chrome_cdp/register_callbacks.py +61 -0
- code_muse/tools/command_runner.py +1401 -0
- code_muse/tools/common.py +1407 -0
- code_muse/tools/display.py +87 -0
- code_muse/tools/file_modifications.py +1099 -0
- code_muse/tools/file_operations.py +860 -0
- code_muse/tools/image_tools.py +185 -0
- code_muse/tools/meetin_proxy/__init__.py +243 -0
- code_muse/tools/meetin_proxy/capture_addon.py +82 -0
- code_muse/tools/meetin_proxy/proxy_manager.py +326 -0
- code_muse/tools/meetin_proxy/register_callbacks.py +45 -0
- code_muse/tools/path_policy.py +219 -0
- code_muse/tools/skills_tools.py +586 -0
- code_muse/tools/subagent_context.py +158 -0
- code_muse/tools/tools_content.py +50 -0
- code_muse/tools/universal_constructor.py +965 -0
- code_muse/uvx_detection.py +241 -0
- code_muse/version_checker.py +86 -0
- code_muse-0.0.1.data/data/code_muse/models.json +66 -0
- code_muse-0.0.1.data/data/code_muse/models_dev_api.json +1 -0
- code_muse-0.0.1.dist-info/METADATA +845 -0
- code_muse-0.0.1.dist-info/RECORD +394 -0
- code_muse-0.0.1.dist-info/WHEEL +4 -0
- code_muse-0.0.1.dist-info/entry_points.txt +2 -0
- code_muse-0.0.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
# cython: language_level=3
|
|
2
|
+
"""Code / read compression strategies for the filter engine.
|
|
3
|
+
|
|
4
|
+
Handles comment stripping, tree compression, and smart truncation for
|
|
5
|
+
file-reading commands.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import re
|
|
10
|
+
from collections import defaultdict
|
|
11
|
+
from typing import ClassVar
|
|
12
|
+
|
|
13
|
+
from code_muse.plugins.filter_engine.registry import get_registry
|
|
14
|
+
|
|
15
|
+
# AST-aware compression (Epic 021)
|
|
16
|
+
from code_muse.plugins.filter_engine.strategies.ast_compressor import (
|
|
17
|
+
compress_ast_code,
|
|
18
|
+
)
|
|
19
|
+
from code_muse.plugins.filter_engine.verbosity import VerbosityLevel
|
|
20
|
+
from code_muse.tools.command_runner import ShellCommandOutput
|
|
21
|
+
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
# Comment stripping helpers
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class MinimalFilter:
|
|
28
|
+
"""Strip only comments, preserving docstrings that look like API docs."""
|
|
29
|
+
|
|
30
|
+
# Language → (single_line_pattern, multi_line_pattern)
|
|
31
|
+
# multi_line_pattern should capture the content between delimiters.
|
|
32
|
+
PATTERNS: ClassVar[dict[str, tuple[str | None, str | None]]] = {
|
|
33
|
+
"python": (
|
|
34
|
+
r"#.*$",
|
|
35
|
+
r'("""[\s\S]*?""")|(\'\'\'[\s\S]*?\'\'\')',
|
|
36
|
+
),
|
|
37
|
+
"javascript": (
|
|
38
|
+
r"//.*$",
|
|
39
|
+
r"/\*[\s\S]*?\*/",
|
|
40
|
+
),
|
|
41
|
+
"typescript": (
|
|
42
|
+
r"//.*$",
|
|
43
|
+
r"/\*[\s\S]*?\*/",
|
|
44
|
+
),
|
|
45
|
+
"rust": (
|
|
46
|
+
r"//.*$",
|
|
47
|
+
r"/\*[\s\S]*?\*/",
|
|
48
|
+
),
|
|
49
|
+
"go": (
|
|
50
|
+
r"//.*$",
|
|
51
|
+
r"/\*[\s\S]*?\*/",
|
|
52
|
+
),
|
|
53
|
+
"java": (
|
|
54
|
+
r"//.*$",
|
|
55
|
+
r"/\*[\s\S]*?\*/",
|
|
56
|
+
),
|
|
57
|
+
"cpp": (
|
|
58
|
+
r"//.*$",
|
|
59
|
+
r"/\*[\s\S]*?\*/",
|
|
60
|
+
),
|
|
61
|
+
"ruby": (
|
|
62
|
+
r"#.*$",
|
|
63
|
+
r"=begin[\s\S]*?=end",
|
|
64
|
+
),
|
|
65
|
+
"bash": (
|
|
66
|
+
r"#.*$",
|
|
67
|
+
None,
|
|
68
|
+
),
|
|
69
|
+
"sql": (
|
|
70
|
+
r"--.*$",
|
|
71
|
+
r"/\*[\s\S]*?\*/",
|
|
72
|
+
),
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@classmethod
|
|
76
|
+
def strip_comments(cls, text: str, language: str = "python") -> str:
|
|
77
|
+
"""Remove single-line comments from *text* for *language*.
|
|
78
|
+
|
|
79
|
+
Multi-line comments / docstrings are kept when they look like API
|
|
80
|
+
documentation (contain words such as ``Args``, ``Returns``,
|
|
81
|
+
``Example``, ``Note``).
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
text: Source code text.
|
|
85
|
+
language: Language key (see :attr:`PATTERNS`).
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
Text with comments stripped.
|
|
89
|
+
"""
|
|
90
|
+
single, multi = cls.PATTERNS.get(language, (None, None))
|
|
91
|
+
result = text
|
|
92
|
+
|
|
93
|
+
if single:
|
|
94
|
+
result = re.sub(single, "", result, flags=re.MULTILINE)
|
|
95
|
+
|
|
96
|
+
if multi:
|
|
97
|
+
# Replace multi-line comments, but keep those that look like docs
|
|
98
|
+
def _maybe_keep(match: re.Match[str]) -> str:
|
|
99
|
+
block = match.group(0)
|
|
100
|
+
doc_markers = (
|
|
101
|
+
"Args:",
|
|
102
|
+
"Returns:",
|
|
103
|
+
"Raises:",
|
|
104
|
+
"Example:",
|
|
105
|
+
"Note:",
|
|
106
|
+
"Notes:",
|
|
107
|
+
)
|
|
108
|
+
if any(marker in block for marker in doc_markers):
|
|
109
|
+
return block
|
|
110
|
+
return ""
|
|
111
|
+
|
|
112
|
+
result = re.sub(multi, _maybe_keep, result)
|
|
113
|
+
|
|
114
|
+
return result
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class AggressiveFilter:
|
|
118
|
+
"""Strip comments, docstrings, blank lines, and boilerplate."""
|
|
119
|
+
|
|
120
|
+
PATTERNS: ClassVar[dict[str, tuple[str | None, str | None]]] = (
|
|
121
|
+
MinimalFilter.PATTERNS
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
@classmethod
|
|
125
|
+
def strip_comments(cls, text: str, language: str = "python") -> str:
|
|
126
|
+
"""Aggressively strip all comments and collapse blank lines.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
text: Source code text.
|
|
130
|
+
language: Language key.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Compact text.
|
|
134
|
+
"""
|
|
135
|
+
single, multi = cls.PATTERNS.get(language, (None, None))
|
|
136
|
+
result = text
|
|
137
|
+
|
|
138
|
+
if single:
|
|
139
|
+
result = re.sub(single, "", result, flags=re.MULTILINE)
|
|
140
|
+
|
|
141
|
+
if multi:
|
|
142
|
+
result = re.sub(multi, "", result)
|
|
143
|
+
|
|
144
|
+
# Collapse multiple blank lines into one
|
|
145
|
+
result = re.sub(r"\n\s*\n+", "\n\n", result)
|
|
146
|
+
|
|
147
|
+
return result.strip()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
# ---------------------------------------------------------------------------
|
|
151
|
+
# Smart truncation
|
|
152
|
+
# ---------------------------------------------------------------------------
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _is_important_line(line: str) -> bool:
|
|
156
|
+
"""Heuristic: is this line important enough to preserve during truncation?"""
|
|
157
|
+
stripped = line.strip()
|
|
158
|
+
if not stripped:
|
|
159
|
+
return False
|
|
160
|
+
|
|
161
|
+
# Import lines
|
|
162
|
+
if stripped.startswith("import ") or stripped.startswith("from "):
|
|
163
|
+
return True
|
|
164
|
+
|
|
165
|
+
# Function / class / method signatures
|
|
166
|
+
if re.match(
|
|
167
|
+
r"^(def |class |async def |fn |pub fn |func |function |method )", stripped
|
|
168
|
+
):
|
|
169
|
+
return True
|
|
170
|
+
|
|
171
|
+
# Decorators
|
|
172
|
+
if stripped.startswith("@"):
|
|
173
|
+
return True
|
|
174
|
+
|
|
175
|
+
# Type signatures / interfaces
|
|
176
|
+
if re.match(r"^(interface |type |struct |enum |trait |impl )", stripped):
|
|
177
|
+
return True
|
|
178
|
+
|
|
179
|
+
# Module / package declarations
|
|
180
|
+
return bool(re.match(r"^(module |package |namespace )", stripped))
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def _is_boilerplate(line: str) -> bool:
|
|
184
|
+
"""Heuristic: is this line boilerplate that can be dropped?"""
|
|
185
|
+
stripped = line.strip()
|
|
186
|
+
boilerplate_patterns = [
|
|
187
|
+
r"^#\s*TODO",
|
|
188
|
+
r"^#\s*FIXME",
|
|
189
|
+
r"^#\s*HACK",
|
|
190
|
+
r"^#\s*NOTE",
|
|
191
|
+
r"^\s*\{\s*\}\s*$", # empty blocks
|
|
192
|
+
r"^\s*pass\s*$", # Python pass
|
|
193
|
+
]
|
|
194
|
+
return any(re.search(pattern, stripped) for pattern in boilerplate_patterns)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def smart_truncate(
|
|
198
|
+
text: str,
|
|
199
|
+
max_lines: int = 60,
|
|
200
|
+
preserve_imports: bool = True,
|
|
201
|
+
preserve_signatures: bool = True,
|
|
202
|
+
) -> str:
|
|
203
|
+
"""Truncate *text* to at most *max_lines* while preserving important lines.
|
|
204
|
+
|
|
205
|
+
Important lines (imports, signatures, decorators) are always kept.
|
|
206
|
+
Blank runs and boilerplate are collapsed or dropped.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
text: The text to truncate.
|
|
210
|
+
max_lines: Maximum number of lines to return.
|
|
211
|
+
preserve_imports: Keep import lines even if they'd be dropped.
|
|
212
|
+
preserve_signatures: Keep function/class signatures.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
Truncated text.
|
|
216
|
+
"""
|
|
217
|
+
if not text:
|
|
218
|
+
return ""
|
|
219
|
+
|
|
220
|
+
lines = text.splitlines()
|
|
221
|
+
if len(lines) <= max_lines:
|
|
222
|
+
return text
|
|
223
|
+
|
|
224
|
+
important: list[str] = []
|
|
225
|
+
body: list[str] = []
|
|
226
|
+
|
|
227
|
+
cdef str line
|
|
228
|
+
cdef str stripped
|
|
229
|
+
|
|
230
|
+
for line in lines:
|
|
231
|
+
if _is_boilerplate(line):
|
|
232
|
+
continue
|
|
233
|
+
stripped = line.strip()
|
|
234
|
+
if (preserve_imports and (stripped.startswith("import ") or stripped.startswith("from "))) or (
|
|
235
|
+
preserve_signatures and _is_important_line(line)
|
|
236
|
+
):
|
|
237
|
+
important.append(line)
|
|
238
|
+
else:
|
|
239
|
+
body.append(line)
|
|
240
|
+
|
|
241
|
+
# Keep all important lines, then fill with body up to max_lines
|
|
242
|
+
result = important[:max_lines]
|
|
243
|
+
remaining = max_lines - len(result)
|
|
244
|
+
if remaining > 0:
|
|
245
|
+
result.extend(body[:remaining])
|
|
246
|
+
|
|
247
|
+
if len(body) > remaining and remaining > 0:
|
|
248
|
+
result.append(f"... ({len(body) - remaining} more lines)")
|
|
249
|
+
|
|
250
|
+
return "\n".join(result)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
# ---------------------------------------------------------------------------
|
|
254
|
+
# Tree / ls compression
|
|
255
|
+
# ---------------------------------------------------------------------------
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def compress_tree(
|
|
259
|
+
stdout: str,
|
|
260
|
+
stderr: str,
|
|
261
|
+
verbosity: VerbosityLevel,
|
|
262
|
+
) -> ShellCommandOutput:
|
|
263
|
+
"""Convert flat ``ls -R`` or ``tree`` output into a hierarchical summary.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
stdout: Raw stdout.
|
|
267
|
+
stderr: Raw stderr.
|
|
268
|
+
verbosity: Current verbosity level.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
Compressed :class:`ShellCommandOutput`.
|
|
272
|
+
"""
|
|
273
|
+
cdef list lines = stdout.splitlines()
|
|
274
|
+
cdef str current_dir = "."
|
|
275
|
+
cdef object dir_files = defaultdict(list)
|
|
276
|
+
cdef object dir_dirs = defaultdict(list)
|
|
277
|
+
|
|
278
|
+
cdef str line
|
|
279
|
+
cdef str stripped
|
|
280
|
+
cdef int file_count
|
|
281
|
+
cdef int dir_count
|
|
282
|
+
|
|
283
|
+
for line in lines:
|
|
284
|
+
stripped = line.rstrip("\r")
|
|
285
|
+
if stripped.endswith(":"):
|
|
286
|
+
current_dir = stripped.rstrip(":")
|
|
287
|
+
continue
|
|
288
|
+
if not stripped or stripped.startswith("total "):
|
|
289
|
+
continue
|
|
290
|
+
|
|
291
|
+
# Heuristic: directories in ls -R are often marked with / or listed before files
|
|
292
|
+
if stripped.endswith("/"):
|
|
293
|
+
dir_dirs[current_dir].append(stripped)
|
|
294
|
+
else:
|
|
295
|
+
dir_files[current_dir].append(stripped)
|
|
296
|
+
|
|
297
|
+
if not dir_files and not dir_dirs:
|
|
298
|
+
return ShellCommandOutput(
|
|
299
|
+
success=True,
|
|
300
|
+
command="ls/tree",
|
|
301
|
+
stdout=stdout.strip() or "Empty directory",
|
|
302
|
+
stderr=stderr if verbosity >= VerbosityLevel.VERY_VERBOSE else None,
|
|
303
|
+
exit_code=0,
|
|
304
|
+
execution_time=None,
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
parts: list[str] = []
|
|
308
|
+
cdef str directory
|
|
309
|
+
cdef list files
|
|
310
|
+
cdef list dirs
|
|
311
|
+
|
|
312
|
+
for directory in sorted(set(list(dir_files.keys()) + list(dir_dirs.keys()))):
|
|
313
|
+
files = dir_files.get(directory, [])
|
|
314
|
+
dirs = dir_dirs.get(directory, [])
|
|
315
|
+
file_count = len(files)
|
|
316
|
+
dir_count = len(dirs)
|
|
317
|
+
parts.append(f"{directory}: {file_count} files, {dir_count} dirs")
|
|
318
|
+
if verbosity >= VerbosityLevel.VERBOSE:
|
|
319
|
+
for d in dirs[:5]:
|
|
320
|
+
parts.append(f" /{d}")
|
|
321
|
+
for f in files[:10]:
|
|
322
|
+
parts.append(f" {f}")
|
|
323
|
+
if len(files) > 10:
|
|
324
|
+
parts.append(f" ... {len(files) - 10} more files")
|
|
325
|
+
if len(dirs) > 5:
|
|
326
|
+
parts.append(f" ... {len(dirs) - 5} more dirs")
|
|
327
|
+
|
|
328
|
+
return ShellCommandOutput(
|
|
329
|
+
success=True,
|
|
330
|
+
command="ls/tree",
|
|
331
|
+
stdout="\n".join(parts),
|
|
332
|
+
stderr=stderr if verbosity >= VerbosityLevel.VERY_VERBOSE else None,
|
|
333
|
+
exit_code=0,
|
|
334
|
+
execution_time=None,
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
# ---------------------------------------------------------------------------
|
|
339
|
+
# Filename extraction helper
|
|
340
|
+
# ---------------------------------------------------------------------------
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def _extract_code_filename(command: str) -> str | None:
|
|
344
|
+
"""Extract the last filename with an AST-supported extension from *command*."""
|
|
345
|
+
pattern = r"[\w./-]+\.(?:py|pyi|js|mjs|cjs|jsx|ts|tsx|go)\b"
|
|
346
|
+
matches = re.findall(pattern, command)
|
|
347
|
+
return matches[-1] if matches else None
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
# ---------------------------------------------------------------------------
|
|
351
|
+
# Read command compression
|
|
352
|
+
# ---------------------------------------------------------------------------
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
def compress_read(
|
|
356
|
+
command: str,
|
|
357
|
+
stdout: str,
|
|
358
|
+
stderr: str,
|
|
359
|
+
exit_code: int,
|
|
360
|
+
verbosity: VerbosityLevel,
|
|
361
|
+
) -> ShellCommandOutput:
|
|
362
|
+
"""Compress output from read commands (``cat``, ``head``, ``tail``, etc.).
|
|
363
|
+
|
|
364
|
+
Applies AST-aware compression for supported languages, falling back to
|
|
365
|
+
smart truncation and comment stripping for others.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
command: The original read command.
|
|
369
|
+
stdout: Raw stdout.
|
|
370
|
+
stderr: Raw stderr.
|
|
371
|
+
exit_code: Process exit code.
|
|
372
|
+
verbosity: Current verbosity level.
|
|
373
|
+
|
|
374
|
+
Returns:
|
|
375
|
+
Compressed :class:`ShellCommandOutput`.
|
|
376
|
+
"""
|
|
377
|
+
if verbosity >= VerbosityLevel.VERY_VERBOSE:
|
|
378
|
+
return ShellCommandOutput(
|
|
379
|
+
success=exit_code == 0,
|
|
380
|
+
command=command,
|
|
381
|
+
stdout=stdout,
|
|
382
|
+
stderr=stderr,
|
|
383
|
+
exit_code=exit_code,
|
|
384
|
+
execution_time=None,
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
# Extract filename from command for AST language detection
|
|
388
|
+
cdef str filename = _extract_code_filename(command) or ""
|
|
389
|
+
|
|
390
|
+
# Try AST-aware compression when we have a supported filename
|
|
391
|
+
if filename:
|
|
392
|
+
try:
|
|
393
|
+
compressed = compress_ast_code(
|
|
394
|
+
stdout, filename=filename, verbosity=verbosity
|
|
395
|
+
)
|
|
396
|
+
return ShellCommandOutput(
|
|
397
|
+
success=exit_code == 0,
|
|
398
|
+
command=command,
|
|
399
|
+
stdout=compressed,
|
|
400
|
+
stderr=stderr if verbosity >= VerbosityLevel.VERY_VERBOSE else None,
|
|
401
|
+
exit_code=exit_code,
|
|
402
|
+
execution_time=None,
|
|
403
|
+
)
|
|
404
|
+
except Exception:
|
|
405
|
+
logger = logging.getLogger(__name__)
|
|
406
|
+
logger.debug("AST compression failed for %s, falling back", command)
|
|
407
|
+
|
|
408
|
+
# Fallback: traditional comment stripping + smart truncation
|
|
409
|
+
cdef str text = stdout
|
|
410
|
+
cdef str language_str = "python"
|
|
411
|
+
cdef object ext_match = re.search(
|
|
412
|
+
r"\.(py|pyi|js|mjs|cjs|jsx|ts|tsx|rs|go|java|cpp|c|h|rb|sh|sql)\b", command
|
|
413
|
+
)
|
|
414
|
+
if ext_match:
|
|
415
|
+
ext_map = {
|
|
416
|
+
"py": "python",
|
|
417
|
+
"pyi": "python",
|
|
418
|
+
"js": "javascript",
|
|
419
|
+
"mjs": "javascript",
|
|
420
|
+
"cjs": "javascript",
|
|
421
|
+
"jsx": "javascript",
|
|
422
|
+
"ts": "typescript",
|
|
423
|
+
"tsx": "typescript",
|
|
424
|
+
"rs": "rust",
|
|
425
|
+
"go": "go",
|
|
426
|
+
"java": "java",
|
|
427
|
+
"cpp": "cpp",
|
|
428
|
+
"c": "cpp",
|
|
429
|
+
"h": "cpp",
|
|
430
|
+
"rb": "ruby",
|
|
431
|
+
"sh": "bash",
|
|
432
|
+
"sql": "sql",
|
|
433
|
+
}
|
|
434
|
+
language_str = ext_map.get(ext_match.group(1), "python")
|
|
435
|
+
|
|
436
|
+
if verbosity <= VerbosityLevel.COMPACT:
|
|
437
|
+
text = MinimalFilter.strip_comments(text, language_str)
|
|
438
|
+
|
|
439
|
+
cdef int max_lines = 60
|
|
440
|
+
if verbosity == VerbosityLevel.ULTRA_COMPACT:
|
|
441
|
+
max_lines = 20
|
|
442
|
+
elif verbosity == VerbosityLevel.COMPACT:
|
|
443
|
+
max_lines = 60
|
|
444
|
+
elif verbosity == VerbosityLevel.VERBOSE:
|
|
445
|
+
max_lines = 120
|
|
446
|
+
|
|
447
|
+
cdef str truncated = smart_truncate(text, max_lines=max_lines)
|
|
448
|
+
|
|
449
|
+
return ShellCommandOutput(
|
|
450
|
+
success=exit_code == 0,
|
|
451
|
+
command=command,
|
|
452
|
+
stdout=truncated,
|
|
453
|
+
stderr=stderr if verbosity >= VerbosityLevel.VERY_VERBOSE else None,
|
|
454
|
+
exit_code=exit_code,
|
|
455
|
+
execution_time=None,
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
# ---------------------------------------------------------------------------
|
|
460
|
+
# Code command compression (alias for read + ls/tree)
|
|
461
|
+
# ---------------------------------------------------------------------------
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def compress_ls(
|
|
465
|
+
command: str,
|
|
466
|
+
stdout: str,
|
|
467
|
+
stderr: str,
|
|
468
|
+
exit_code: int,
|
|
469
|
+
verbosity: VerbosityLevel,
|
|
470
|
+
) -> ShellCommandOutput:
|
|
471
|
+
"""Compress ``ls`` / ``tree`` output.
|
|
472
|
+
|
|
473
|
+
Args:
|
|
474
|
+
command: The original ls command.
|
|
475
|
+
stdout: Raw stdout.
|
|
476
|
+
stderr: Raw stderr.
|
|
477
|
+
exit_code: Process exit code.
|
|
478
|
+
verbosity: Current verbosity level.
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
Compressed :class:`ShellCommandOutput`.
|
|
482
|
+
"""
|
|
483
|
+
return compress_tree(stdout, stderr, verbosity)
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
def compress_code(
|
|
487
|
+
command: str,
|
|
488
|
+
stdout: str,
|
|
489
|
+
stderr: str,
|
|
490
|
+
exit_code: int,
|
|
491
|
+
verbosity: VerbosityLevel,
|
|
492
|
+
) -> ShellCommandOutput | None:
|
|
493
|
+
"""Main dispatcher for code / read compression strategies.
|
|
494
|
+
|
|
495
|
+
Args:
|
|
496
|
+
command: The original command.
|
|
497
|
+
stdout: Raw stdout.
|
|
498
|
+
stderr: Raw stderr.
|
|
499
|
+
exit_code: Process exit code.
|
|
500
|
+
verbosity: Current verbosity level.
|
|
501
|
+
|
|
502
|
+
Returns:
|
|
503
|
+
A compressed :class:`ShellCommandOutput` or ``None``.
|
|
504
|
+
"""
|
|
505
|
+
cdef str stripped = command.strip()
|
|
506
|
+
cdef str text
|
|
507
|
+
cdef str filename
|
|
508
|
+
cdef bint ast_used = False
|
|
509
|
+
cdef str language_str
|
|
510
|
+
cdef int max_lines
|
|
511
|
+
cdef object ext_match
|
|
512
|
+
cdef str truncated
|
|
513
|
+
|
|
514
|
+
# Read commands
|
|
515
|
+
if re.search(r"\b(cat|head|tail|less|bat|nl)\b", stripped):
|
|
516
|
+
return compress_read(command, stdout, stderr, exit_code, verbosity)
|
|
517
|
+
|
|
518
|
+
# Directory listing
|
|
519
|
+
if re.search(r"\b(ls|tree)\b", stripped):
|
|
520
|
+
return compress_ls(command, stdout, stderr, exit_code, verbosity)
|
|
521
|
+
|
|
522
|
+
# Generic code commands: apply smart truncate + minimal comment strip
|
|
523
|
+
text = stdout
|
|
524
|
+
filename = _extract_code_filename(command) or ""
|
|
525
|
+
|
|
526
|
+
if filename:
|
|
527
|
+
try:
|
|
528
|
+
text = compress_ast_code(stdout, filename=filename, verbosity=verbosity)
|
|
529
|
+
ast_used = True
|
|
530
|
+
except Exception:
|
|
531
|
+
logger = logging.getLogger(__name__)
|
|
532
|
+
logger.debug("AST compression failed for %s, falling back", command)
|
|
533
|
+
|
|
534
|
+
if not ast_used and verbosity <= VerbosityLevel.COMPACT:
|
|
535
|
+
language_str = "python"
|
|
536
|
+
ext_match = re.search(
|
|
537
|
+
r"\.(py|pyi|js|mjs|cjs|jsx|ts|tsx|rs|go|java|cpp|c|h|rb|sh|sql)\b", command
|
|
538
|
+
)
|
|
539
|
+
if ext_match:
|
|
540
|
+
ext_map = {
|
|
541
|
+
"py": "python",
|
|
542
|
+
"pyi": "python",
|
|
543
|
+
"js": "javascript",
|
|
544
|
+
"mjs": "javascript",
|
|
545
|
+
"cjs": "javascript",
|
|
546
|
+
"jsx": "javascript",
|
|
547
|
+
"ts": "typescript",
|
|
548
|
+
"tsx": "typescript",
|
|
549
|
+
"rs": "rust",
|
|
550
|
+
"go": "go",
|
|
551
|
+
"java": "java",
|
|
552
|
+
"cpp": "cpp",
|
|
553
|
+
"c": "cpp",
|
|
554
|
+
"h": "cpp",
|
|
555
|
+
"rb": "ruby",
|
|
556
|
+
"sh": "bash",
|
|
557
|
+
"sql": "sql",
|
|
558
|
+
}
|
|
559
|
+
language_str = ext_map.get(ext_match.group(1), "python")
|
|
560
|
+
text = MinimalFilter.strip_comments(text, language_str)
|
|
561
|
+
|
|
562
|
+
max_lines = 60
|
|
563
|
+
if verbosity == VerbosityLevel.ULTRA_COMPACT:
|
|
564
|
+
max_lines = 20
|
|
565
|
+
elif verbosity == VerbosityLevel.VERBOSE:
|
|
566
|
+
max_lines = 120
|
|
567
|
+
|
|
568
|
+
truncated = smart_truncate(text, max_lines=max_lines)
|
|
569
|
+
|
|
570
|
+
return ShellCommandOutput(
|
|
571
|
+
success=exit_code == 0,
|
|
572
|
+
command=command,
|
|
573
|
+
stdout=truncated,
|
|
574
|
+
stderr=stderr if verbosity >= VerbosityLevel.VERY_VERBOSE else None,
|
|
575
|
+
exit_code=exit_code,
|
|
576
|
+
execution_time=None,
|
|
577
|
+
)
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
# ---------------------------------------------------------------------------
|
|
581
|
+
# Register with the strategy registry
|
|
582
|
+
# ---------------------------------------------------------------------------
|
|
583
|
+
get_registry().register("code", compress_code, priority=0)
|
|
584
|
+
get_registry().register("read", compress_code, priority=0)
|
|
Binary file
|