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,345 @@
|
|
|
1
|
+
"""Utility functions for the Azure AI Foundry plugin.
|
|
2
|
+
|
|
3
|
+
This module provides helper functions for configuration management,
|
|
4
|
+
environment variable resolution, and model configuration.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import logging
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from .config import (
|
|
14
|
+
DEFAULT_CONTEXT_LENGTHS,
|
|
15
|
+
ENV_FOUNDRY_RESOURCE,
|
|
16
|
+
get_extra_models_path,
|
|
17
|
+
get_openai_context_length,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
# Context window suffix pattern: [<number><unit>] where unit is k or m (case-insensitive)
|
|
23
|
+
# Examples: [200k], [500k], [1m], [2m]
|
|
24
|
+
_CONTEXT_SUFFIX_PATTERN = re.compile(r"\[(\d+)([km])\]", re.IGNORECASE)
|
|
25
|
+
|
|
26
|
+
# Multipliers for context window units
|
|
27
|
+
_CONTEXT_MULTIPLIERS = {
|
|
28
|
+
"k": 1_000,
|
|
29
|
+
"m": 1_000_000,
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def parse_context_window_suffix(name: str) -> tuple[str, int | None]:
|
|
34
|
+
"""Parse and extract context window suffix from a model/deployment name.
|
|
35
|
+
|
|
36
|
+
Supports Claude Code format: [<number><unit>] where unit is 'k' (thousands)
|
|
37
|
+
or 'm' (millions). Examples: [200k], [500k], [1m], [2m]
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
name: The model or deployment name, possibly with context suffix.
|
|
41
|
+
e.g., "it-entra-claude-opus-4-6[1m]"
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
A tuple of (stripped_name, context_length):
|
|
45
|
+
- stripped_name: The name with the suffix removed
|
|
46
|
+
- context_length: The parsed context length in tokens, or None if no suffix
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
>>> parse_context_window_suffix("claude-opus-4-6[1m]")
|
|
50
|
+
('claude-opus-4-6', 1000000)
|
|
51
|
+
>>> parse_context_window_suffix("claude-sonnet[200k]")
|
|
52
|
+
('claude-sonnet', 200000)
|
|
53
|
+
>>> parse_context_window_suffix("claude-haiku-4-5")
|
|
54
|
+
('claude-haiku-4-5', None)
|
|
55
|
+
"""
|
|
56
|
+
match = _CONTEXT_SUFFIX_PATTERN.search(name)
|
|
57
|
+
if not match:
|
|
58
|
+
return name, None
|
|
59
|
+
|
|
60
|
+
number = int(match.group(1))
|
|
61
|
+
unit = match.group(2).lower()
|
|
62
|
+
multiplier = _CONTEXT_MULTIPLIERS[unit]
|
|
63
|
+
context_length = number * multiplier
|
|
64
|
+
|
|
65
|
+
# Remove the suffix from the name
|
|
66
|
+
stripped_name = _CONTEXT_SUFFIX_PATTERN.sub("", name).strip()
|
|
67
|
+
|
|
68
|
+
return stripped_name, context_length
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def resolve_env_var(value: str) -> str:
|
|
72
|
+
"""Resolve a value that may contain an environment variable reference.
|
|
73
|
+
|
|
74
|
+
If the value starts with '$', it's treated as an environment variable
|
|
75
|
+
reference and resolved. Otherwise, the value is returned as-is.
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
value: The value to resolve, possibly starting with '$'.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
The resolved value.
|
|
82
|
+
|
|
83
|
+
Example:
|
|
84
|
+
>>> os.environ["MY_VAR"] = "test"
|
|
85
|
+
>>> resolve_env_var("$MY_VAR")
|
|
86
|
+
'test'
|
|
87
|
+
>>> resolve_env_var("literal")
|
|
88
|
+
'literal'
|
|
89
|
+
"""
|
|
90
|
+
if value and value.startswith("$"):
|
|
91
|
+
env_var = value[1:]
|
|
92
|
+
resolved = os.environ.get(env_var)
|
|
93
|
+
if resolved is None:
|
|
94
|
+
logger.warning(f"Environment variable '{env_var}' not set")
|
|
95
|
+
return ""
|
|
96
|
+
return resolved
|
|
97
|
+
return value
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def load_extra_models() -> dict[str, Any]:
|
|
101
|
+
"""Load the extra_models.json configuration file.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Dictionary containing model configurations, or empty dict if file
|
|
105
|
+
doesn't exist or is invalid.
|
|
106
|
+
"""
|
|
107
|
+
extra_models_path = get_extra_models_path()
|
|
108
|
+
if not extra_models_path.exists():
|
|
109
|
+
return {}
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
with open(extra_models_path, encoding="utf-8") as f:
|
|
113
|
+
return json.load(f)
|
|
114
|
+
except json.JSONDecodeError as e:
|
|
115
|
+
logger.error(f"Invalid JSON in extra_models.json: {e}")
|
|
116
|
+
return {}
|
|
117
|
+
except Exception as e:
|
|
118
|
+
logger.error(f"Error loading extra_models.json: {e}")
|
|
119
|
+
return {}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def save_extra_models(models: dict[str, Any]) -> bool:
|
|
123
|
+
"""Save model configurations to extra_models.json.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
models: Dictionary of model configurations to save.
|
|
127
|
+
|
|
128
|
+
Returns:
|
|
129
|
+
True if save succeeded, False otherwise.
|
|
130
|
+
"""
|
|
131
|
+
extra_models_path = get_extra_models_path()
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
# Ensure directory exists
|
|
135
|
+
extra_models_path.parent.mkdir(parents=True, exist_ok=True)
|
|
136
|
+
|
|
137
|
+
# Atomic write using temp file
|
|
138
|
+
temp_path = extra_models_path.with_suffix(".tmp")
|
|
139
|
+
with open(temp_path, "w", encoding="utf-8") as f:
|
|
140
|
+
json.dump(models, f, indent=2, ensure_ascii=False)
|
|
141
|
+
temp_path.replace(extra_models_path)
|
|
142
|
+
|
|
143
|
+
logger.info(f"Saved {len(models)} models to extra_models.json")
|
|
144
|
+
return True
|
|
145
|
+
|
|
146
|
+
except Exception as e:
|
|
147
|
+
logger.error(f"Error saving extra_models.json: {e}")
|
|
148
|
+
return False
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def build_foundry_model_config(
|
|
152
|
+
deployment_name: str,
|
|
153
|
+
model_tier: str,
|
|
154
|
+
foundry_resource: str | None = None,
|
|
155
|
+
context_length: int | None = None,
|
|
156
|
+
) -> dict[str, Any]:
|
|
157
|
+
"""Build a Muse model configuration for an Azure Foundry deployment.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
deployment_name: The deployment name in Azure Foundry.
|
|
161
|
+
model_tier: One of "opus", "sonnet", or "haiku".
|
|
162
|
+
foundry_resource: The Foundry resource name. If None, uses env var reference.
|
|
163
|
+
context_length: Override for context length. If None, uses default for tier.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Dictionary containing the model configuration.
|
|
167
|
+
"""
|
|
168
|
+
if context_length is None:
|
|
169
|
+
context_length = DEFAULT_CONTEXT_LENGTHS.get(model_tier.lower(), 200000)
|
|
170
|
+
|
|
171
|
+
resource_value = (
|
|
172
|
+
foundry_resource if foundry_resource else f"${ENV_FOUNDRY_RESOURCE}"
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# All Anthropic models need extended_thinking + budget_tokens for the
|
|
176
|
+
# request body, plus interleaved_thinking for the beta header.
|
|
177
|
+
# Opus additionally supports effort (hand-in-hand with adaptive thinking).
|
|
178
|
+
supported_settings = [
|
|
179
|
+
"temperature",
|
|
180
|
+
"extended_thinking",
|
|
181
|
+
"budget_tokens",
|
|
182
|
+
"interleaved_thinking",
|
|
183
|
+
]
|
|
184
|
+
if model_tier.lower() == "opus":
|
|
185
|
+
supported_settings.append("effort")
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
"type": "azure_foundry",
|
|
189
|
+
"provider": "azure_foundry",
|
|
190
|
+
"name": deployment_name,
|
|
191
|
+
"foundry_resource": resource_value,
|
|
192
|
+
"context_length": context_length,
|
|
193
|
+
"supported_settings": supported_settings,
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def add_foundry_models_to_config(
|
|
198
|
+
resource_name: str,
|
|
199
|
+
opus_deployment: str | None = None,
|
|
200
|
+
sonnet_deployment: str | None = None,
|
|
201
|
+
haiku_deployment: str | None = None,
|
|
202
|
+
) -> list[str]:
|
|
203
|
+
"""Add Azure Foundry model configurations to extra_models.json.
|
|
204
|
+
|
|
205
|
+
Args:
|
|
206
|
+
resource_name: The Azure Foundry resource name.
|
|
207
|
+
opus_deployment: Deployment name for Opus model (optional).
|
|
208
|
+
sonnet_deployment: Deployment name for Sonnet model (optional).
|
|
209
|
+
haiku_deployment: Deployment name for Haiku model (optional).
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
List of model keys that were added.
|
|
213
|
+
"""
|
|
214
|
+
models = load_extra_models()
|
|
215
|
+
added_models: list[str] = []
|
|
216
|
+
|
|
217
|
+
deployments = [
|
|
218
|
+
("opus", opus_deployment, "foundry-claude-opus"),
|
|
219
|
+
("sonnet", sonnet_deployment, "foundry-claude-sonnet"),
|
|
220
|
+
("haiku", haiku_deployment, "foundry-claude-haiku"),
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
for tier, deployment, model_key in deployments:
|
|
224
|
+
if deployment:
|
|
225
|
+
# Parse context window suffix (Claude Code format: [200k], [1m], etc.)
|
|
226
|
+
actual_deployment, context_length = parse_context_window_suffix(deployment)
|
|
227
|
+
|
|
228
|
+
config = build_foundry_model_config(
|
|
229
|
+
deployment_name=actual_deployment,
|
|
230
|
+
model_tier=tier,
|
|
231
|
+
foundry_resource=resource_name,
|
|
232
|
+
context_length=context_length,
|
|
233
|
+
)
|
|
234
|
+
models[model_key] = config
|
|
235
|
+
added_models.append(model_key)
|
|
236
|
+
|
|
237
|
+
if added_models and save_extra_models(models):
|
|
238
|
+
return added_models
|
|
239
|
+
|
|
240
|
+
return []
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
FOUNDRY_TYPES = {"azure_foundry", "azure_foundry_openai"}
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
_GPT5_SUPPORTED_SETTINGS = [
|
|
247
|
+
"reasoning_effort",
|
|
248
|
+
"summary",
|
|
249
|
+
"verbosity",
|
|
250
|
+
]
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def get_foundry_openai_supported_settings(model_name: str) -> list[str]:
|
|
254
|
+
"""Return supported settings for an Azure Foundry OpenAI model.
|
|
255
|
+
|
|
256
|
+
Later GPT-5-family models support Muse's reasoning/summary/verbosity
|
|
257
|
+
controls in addition to the baseline temperature setting.
|
|
258
|
+
"""
|
|
259
|
+
supported_settings = ["temperature"]
|
|
260
|
+
if model_name.startswith("gpt-5"):
|
|
261
|
+
supported_settings.extend(_GPT5_SUPPORTED_SETTINGS)
|
|
262
|
+
return supported_settings
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def add_discovered_models_to_config(
|
|
266
|
+
resource_name: str,
|
|
267
|
+
deployments: list,
|
|
268
|
+
) -> list[str]:
|
|
269
|
+
"""Add auto-discovered deployments to extra_models.json.
|
|
270
|
+
|
|
271
|
+
Classifies each deployment by model format (Anthropic vs OpenAI)
|
|
272
|
+
and creates the appropriate model config.
|
|
273
|
+
"""
|
|
274
|
+
from .discovery import AzureDeployment
|
|
275
|
+
|
|
276
|
+
models = load_extra_models()
|
|
277
|
+
added: list[str] = []
|
|
278
|
+
|
|
279
|
+
for d in deployments:
|
|
280
|
+
if not isinstance(d, AzureDeployment):
|
|
281
|
+
continue
|
|
282
|
+
|
|
283
|
+
key = f"foundry-{d.name}"
|
|
284
|
+
|
|
285
|
+
if d.model_format == "Anthropic":
|
|
286
|
+
tier = "haiku"
|
|
287
|
+
for t in ("opus", "sonnet"):
|
|
288
|
+
if t in d.model_name.lower():
|
|
289
|
+
tier = t
|
|
290
|
+
break
|
|
291
|
+
models[key] = build_foundry_model_config(
|
|
292
|
+
deployment_name=d.name,
|
|
293
|
+
model_tier=tier,
|
|
294
|
+
foundry_resource=resource_name,
|
|
295
|
+
)
|
|
296
|
+
added.append(key)
|
|
297
|
+
|
|
298
|
+
elif d.model_format == "OpenAI":
|
|
299
|
+
models[key] = {
|
|
300
|
+
"type": "azure_foundry_openai",
|
|
301
|
+
"provider": "azure_foundry_openai",
|
|
302
|
+
"name": d.name,
|
|
303
|
+
"foundry_resource": resource_name,
|
|
304
|
+
"context_length": get_openai_context_length(d.model_name),
|
|
305
|
+
"supported_settings": get_foundry_openai_supported_settings(
|
|
306
|
+
d.model_name
|
|
307
|
+
),
|
|
308
|
+
}
|
|
309
|
+
added.append(key)
|
|
310
|
+
|
|
311
|
+
if added and save_extra_models(models):
|
|
312
|
+
return added
|
|
313
|
+
return []
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def remove_foundry_models_from_config() -> list[str]:
|
|
317
|
+
"""Remove all Azure Foundry model configurations from extra_models.json."""
|
|
318
|
+
models = load_extra_models()
|
|
319
|
+
removed_models: list[str] = []
|
|
320
|
+
|
|
321
|
+
keys_to_remove = [
|
|
322
|
+
key
|
|
323
|
+
for key, config in models.items()
|
|
324
|
+
if isinstance(config, dict) and config.get("type") in FOUNDRY_TYPES
|
|
325
|
+
]
|
|
326
|
+
|
|
327
|
+
for key in keys_to_remove:
|
|
328
|
+
del models[key]
|
|
329
|
+
removed_models.append(key)
|
|
330
|
+
|
|
331
|
+
if removed_models and not save_extra_models(models):
|
|
332
|
+
logger.error("Failed to persist model removal")
|
|
333
|
+
return []
|
|
334
|
+
|
|
335
|
+
return removed_models
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def get_foundry_models_from_config() -> dict[str, Any]:
|
|
339
|
+
"""Get all Azure Foundry model configurations from extra_models.json."""
|
|
340
|
+
models = load_extra_models()
|
|
341
|
+
return {
|
|
342
|
+
key: config
|
|
343
|
+
for key, config in models.items()
|
|
344
|
+
if isinstance(config, dict) and config.get("type") in FOUNDRY_TYPES
|
|
345
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Build Filter plugin — compresses build command output."""
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"""Build Filter plugin for Muse — callback registration.
|
|
2
|
+
|
|
3
|
+
Registers:
|
|
4
|
+
- ``run_shell_command`` callback that intercepts build commands
|
|
5
|
+
- ``/build-filter`` custom command
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import re
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
from code_muse.callbacks import register_callback
|
|
13
|
+
from code_muse.messaging import emit_info
|
|
14
|
+
|
|
15
|
+
# Import strategies so they self-register with the strategy registry
|
|
16
|
+
from code_muse.plugins.build_filter.strategies import build # noqa: F401
|
|
17
|
+
from code_muse.plugins.filter_engine.verbosity import get_verbosity
|
|
18
|
+
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
21
|
+
# ---------------------------------------------------------------------------
|
|
22
|
+
# Build command classifier
|
|
23
|
+
# ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
BUILD_PATTERNS = [
|
|
26
|
+
# make / cmake / ninja / msbuild
|
|
27
|
+
r"^\s*make\b",
|
|
28
|
+
r"^\s*cmake\b",
|
|
29
|
+
r"^\s*ninja\b",
|
|
30
|
+
r"^\s*msbuild\b",
|
|
31
|
+
# Cargo
|
|
32
|
+
r"^\s*cargo\s+build\b",
|
|
33
|
+
r"^\s*cargo\s+run\b",
|
|
34
|
+
# Go
|
|
35
|
+
r"^\s*go\s+build\b",
|
|
36
|
+
r"^\s*go\s+install\b",
|
|
37
|
+
r"^\s*go\s+run\b",
|
|
38
|
+
# Node
|
|
39
|
+
r"^\s*npm\s+run\s+build\b",
|
|
40
|
+
r"^\s*yarn\s+build\b",
|
|
41
|
+
r"^\s*pnpm\s+build\b",
|
|
42
|
+
r"^\s*npx\s+.*build\b",
|
|
43
|
+
# Docker
|
|
44
|
+
r"^\s*docker\s+build\b",
|
|
45
|
+
r"^\s*docker\s+compose\s+build\b",
|
|
46
|
+
r"^\s*docker-compose\s+build\b",
|
|
47
|
+
# pip / uv
|
|
48
|
+
r"^\s*pip\s+install\b",
|
|
49
|
+
r"^\s*pip3\s+install\b",
|
|
50
|
+
r"^\s*uv\s+pip\s+install\b",
|
|
51
|
+
r"^\s*python\s+-m\s+pip\s+install\b",
|
|
52
|
+
# Generic build tools
|
|
53
|
+
r"^\s*\./configure\b",
|
|
54
|
+
r"^\s*meson\b",
|
|
55
|
+
r"^\s*bazel\s+build\b",
|
|
56
|
+
r"^\s*gradle\s+build\b",
|
|
57
|
+
r"^\s*mvn\s+compile\b",
|
|
58
|
+
r"^\s*mvn\s+package\b",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
_compiled_patterns = [re.compile(pattern) for pattern in BUILD_PATTERNS]
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _is_build_command(command: str) -> bool:
|
|
65
|
+
"""Check if a command matches any build pattern."""
|
|
66
|
+
stripped = command.strip()
|
|
67
|
+
return any(pattern.search(stripped) for pattern in _compiled_patterns)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# ---------------------------------------------------------------------------
|
|
71
|
+
# run_shell_command callback
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
async def build_filter_callback(
|
|
76
|
+
context: Any,
|
|
77
|
+
command: str,
|
|
78
|
+
cwd: str | None = None,
|
|
79
|
+
timeout: int = 60,
|
|
80
|
+
) -> dict[str, Any] | None:
|
|
81
|
+
"""Intercept build commands and compress their output.
|
|
82
|
+
|
|
83
|
+
Returns ``{"pre_executed": True, "output": ShellCommandOutput(...)}`` for
|
|
84
|
+
build commands, or ``None`` to passthrough to the filter engine.
|
|
85
|
+
"""
|
|
86
|
+
if not _is_build_command(command):
|
|
87
|
+
return None # Let filter_engine handle it
|
|
88
|
+
|
|
89
|
+
verbosity = get_verbosity()
|
|
90
|
+
if verbosity.value >= 4: # RAW: no filtering
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
from code_muse.plugins.filter_engine.registry import get_registry
|
|
95
|
+
from code_muse.tools.command_runner import _execute_shell_command
|
|
96
|
+
from code_muse.tools.subagent_context import is_subagent
|
|
97
|
+
|
|
98
|
+
silent = is_subagent()
|
|
99
|
+
group_id = f"build_filter_{id(command)}"
|
|
100
|
+
|
|
101
|
+
output = await _execute_shell_command(
|
|
102
|
+
command=command,
|
|
103
|
+
cwd=cwd,
|
|
104
|
+
timeout=timeout,
|
|
105
|
+
group_id=group_id,
|
|
106
|
+
silent=silent,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
strategy = get_registry().get_strategy("build")
|
|
110
|
+
if strategy is None:
|
|
111
|
+
return None # Shouldn't happen since we registered it
|
|
112
|
+
|
|
113
|
+
filtered = strategy(
|
|
114
|
+
command,
|
|
115
|
+
output.stdout or "",
|
|
116
|
+
output.stderr or "",
|
|
117
|
+
output.exit_code or 0,
|
|
118
|
+
verbosity,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
if filtered is None:
|
|
122
|
+
return None
|
|
123
|
+
|
|
124
|
+
# Track token savings (best-effort)
|
|
125
|
+
try:
|
|
126
|
+
from code_muse.plugins.token_tracking.record import record_command
|
|
127
|
+
|
|
128
|
+
record_command(
|
|
129
|
+
command=command,
|
|
130
|
+
raw_stdout=output.stdout or "",
|
|
131
|
+
raw_stderr=output.stderr or "",
|
|
132
|
+
compressed_stdout=filtered.stdout or "",
|
|
133
|
+
compressed_stderr=filtered.stderr or "",
|
|
134
|
+
category="build",
|
|
135
|
+
strategy="compress_build",
|
|
136
|
+
exit_code=output.exit_code or 0,
|
|
137
|
+
)
|
|
138
|
+
except Exception:
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
return {"pre_executed": True, "output": filtered}
|
|
142
|
+
|
|
143
|
+
except Exception:
|
|
144
|
+
logger.exception("BuildFilter: strategy failed for %r", command)
|
|
145
|
+
return None # Fallback to raw execution
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
# ---------------------------------------------------------------------------
|
|
149
|
+
# Help entries
|
|
150
|
+
# ---------------------------------------------------------------------------
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _on_custom_command_help() -> list[tuple[str, str]]:
|
|
154
|
+
return [
|
|
155
|
+
("/build-filter status", "Show which build commands are being filtered"),
|
|
156
|
+
]
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# ---------------------------------------------------------------------------
|
|
160
|
+
# /build-filter custom command
|
|
161
|
+
# ---------------------------------------------------------------------------
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _on_custom_command(command: str, name: str) -> bool | None: # noqa: ARG001
|
|
165
|
+
if name != "build-filter":
|
|
166
|
+
return None
|
|
167
|
+
|
|
168
|
+
tokens = command.strip().split()
|
|
169
|
+
subcommand = tokens[1] if len(tokens) > 1 else "status"
|
|
170
|
+
|
|
171
|
+
if subcommand == "status":
|
|
172
|
+
emit_info(
|
|
173
|
+
"Build Filter active — compressing output for:\n"
|
|
174
|
+
" • make / cmake / ninja / msbuild\n"
|
|
175
|
+
" • cargo build / cargo run\n"
|
|
176
|
+
" • go build / go install\n"
|
|
177
|
+
" • npm run build / yarn build / pnpm build\n"
|
|
178
|
+
" • docker build / docker-compose build\n"
|
|
179
|
+
" • pip install / uv pip install\n"
|
|
180
|
+
" • ./configure / meson / bazel build / gradle build / mvn\n"
|
|
181
|
+
"\n"
|
|
182
|
+
"Use -v / -vv for verbose output, -vvv for raw (unfiltered).\n"
|
|
183
|
+
"Run /tracking gain to see token savings."
|
|
184
|
+
)
|
|
185
|
+
return True
|
|
186
|
+
|
|
187
|
+
emit_info(
|
|
188
|
+
f"Unknown /build-filter subcommand: {subcommand}\nTry /build-filter status"
|
|
189
|
+
)
|
|
190
|
+
return True
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# ---------------------------------------------------------------------------
|
|
194
|
+
# Register all callbacks
|
|
195
|
+
# ---------------------------------------------------------------------------
|
|
196
|
+
|
|
197
|
+
register_callback("run_shell_command", build_filter_callback)
|
|
198
|
+
register_callback("custom_command", _on_custom_command)
|
|
199
|
+
register_callback("custom_command_help", _on_custom_command_help)
|
|
200
|
+
|
|
201
|
+
logger.debug("Build Filter plugin callbacks registered")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Compression strategies for the build filter."""
|