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,387 @@
|
|
|
1
|
+
"""MindPack tools — ask_mindpack tool and orchestrator wiring.
|
|
2
|
+
|
|
3
|
+
Initialises a singleton MindPackOrchestrator with the five default
|
|
4
|
+
experts and registers the advisory deep-solve tool via the plugin
|
|
5
|
+
hook system. Data models live in ``schemas.py`` to avoid circular
|
|
6
|
+
imports between this module and ``orchestration.py``.
|
|
7
|
+
|
|
8
|
+
Nested-workflow safety (Epic 5 & 6):
|
|
9
|
+
- ``MindPackInvocationContext`` tracks per-prompt call counts and depth.
|
|
10
|
+
- ``ask_mindpack`` cannot be called recursively (max_depth defaults to 1).
|
|
11
|
+
- ``max_calls_per_prompt`` prevents execution loops.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import logging
|
|
15
|
+
from contextvars import ContextVar
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from typing import Literal
|
|
18
|
+
|
|
19
|
+
from pydantic_ai import RunContext
|
|
20
|
+
|
|
21
|
+
from code_muse.plugins.mindpack.orchestration import MindPackOrchestrator
|
|
22
|
+
from code_muse.plugins.mindpack.schemas import (
|
|
23
|
+
AskMindPackInput,
|
|
24
|
+
AskMindPackOutput,
|
|
25
|
+
ExpertDescriptor,
|
|
26
|
+
MindPackNestedConfig,
|
|
27
|
+
MindPackRankedOption,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# Backward-compatible re-exports — external code importing from
|
|
31
|
+
# ``tools`` still works, but canonical location is ``schemas``.
|
|
32
|
+
__all__ = [
|
|
33
|
+
"AskMindPackInput",
|
|
34
|
+
"AskMindPackOutput",
|
|
35
|
+
"ExpertDescriptor",
|
|
36
|
+
"MindPackRankedOption",
|
|
37
|
+
"MindPackInvocationContext",
|
|
38
|
+
"register_ask_mindpack",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
logger = logging.getLogger(__name__)
|
|
42
|
+
|
|
43
|
+
# ---------------------------------------------------------------------------
|
|
44
|
+
# INI config helpers (local copy to avoid cross-module import cycles)
|
|
45
|
+
# ---------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def _get_config_str(key: str, default: str) -> str:
|
|
49
|
+
from code_muse.config import get_value
|
|
50
|
+
|
|
51
|
+
return get_value(key) or default
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _get_config_int(key: str, default: int) -> int:
|
|
55
|
+
from code_muse.config import get_value
|
|
56
|
+
|
|
57
|
+
val = get_value(key)
|
|
58
|
+
if val is None:
|
|
59
|
+
return default
|
|
60
|
+
try:
|
|
61
|
+
return int(val)
|
|
62
|
+
except ValueError, TypeError:
|
|
63
|
+
return default
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _get_config_bool(key: str, default: bool) -> bool:
|
|
67
|
+
from code_muse.config import get_value
|
|
68
|
+
|
|
69
|
+
val = get_value(key)
|
|
70
|
+
if val is None:
|
|
71
|
+
return default
|
|
72
|
+
return str(val).lower() in ("1", "true", "yes", "on")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def load_nested_config_from_ini() -> MindPackNestedConfig:
|
|
76
|
+
"""Build a ``MindPackNestedConfig`` from INI settings.
|
|
77
|
+
|
|
78
|
+
Reads ``packmind_nested_enabled``, ``packmind_nested_max_depth``,
|
|
79
|
+
``packmind_nested_max_calls_per_prompt``, and
|
|
80
|
+
``packmind_nested_timeout_sec`` from the Muse INI config.
|
|
81
|
+
"""
|
|
82
|
+
return MindPackNestedConfig(
|
|
83
|
+
enabled=_get_config_bool("packmind_nested_enabled", True),
|
|
84
|
+
max_depth=_get_config_int("packmind_nested_max_depth", 1),
|
|
85
|
+
max_calls_per_prompt=_get_config_int("packmind_nested_max_calls_per_prompt", 2),
|
|
86
|
+
timeout_sec=_get_config_int("packmind_nested_timeout_sec", 90),
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# ---------------------------------------------------------------------------
|
|
91
|
+
# MindPackInvocationContext — nested-workflow guardrails
|
|
92
|
+
# ---------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@dataclass
|
|
96
|
+
class MindPackInvocationContext:
|
|
97
|
+
"""Runtime context for a single MindPack invocation.
|
|
98
|
+
|
|
99
|
+
Tracks nesting depth (to prevent recursive ``ask_mindpack`` calls)
|
|
100
|
+
and the number of invocations already made in the current prompt
|
|
101
|
+
(to enforce ``max_calls_per_prompt``).
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
nested_depth: int = 0
|
|
105
|
+
max_depth: int = 1
|
|
106
|
+
max_calls_per_prompt: int = 2
|
|
107
|
+
session_id: str | None = None
|
|
108
|
+
call_count: int = field(default=0, repr=False)
|
|
109
|
+
|
|
110
|
+
def is_recursion_blocked(self) -> bool:
|
|
111
|
+
"""True if we are already inside a MindPack call (depth ≥ 1)."""
|
|
112
|
+
return self.nested_depth >= self.max_depth
|
|
113
|
+
|
|
114
|
+
def is_call_limit_reached(self) -> bool:
|
|
115
|
+
"""True if the per-prompt call cap has been exceeded."""
|
|
116
|
+
return self.call_count >= self.max_calls_per_prompt
|
|
117
|
+
|
|
118
|
+
def increment_call(self) -> None:
|
|
119
|
+
self.call_count += 1
|
|
120
|
+
self.nested_depth += 1
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# ContextVar tracking the *current* invocation (None when outside ask_mindpack)
|
|
124
|
+
_mindpack_ctx_var: ContextVar[MindPackInvocationContext | None] = ContextVar(
|
|
125
|
+
"mindpack_ctx", default=None
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# ContextVar tracking how many times ask_mindpack has been called in this prompt
|
|
129
|
+
_mindpack_call_count_var: ContextVar[int] = ContextVar("mindpack_call_count", default=0)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _check_and_increment_call(
|
|
133
|
+
nested_config: MindPackNestedConfig,
|
|
134
|
+
) -> MindPackInvocationContext:
|
|
135
|
+
"""Validate recursion / call-count guardrails and return a fresh context.
|
|
136
|
+
|
|
137
|
+
Raises:
|
|
138
|
+
RuntimeError: with an explicit rejection message if recursion limits
|
|
139
|
+
or the per-prompt call cap are exceeded.
|
|
140
|
+
"""
|
|
141
|
+
# 1. Check if we are already inside a MindPack invocation (recursion)
|
|
142
|
+
existing_ctx = _mindpack_ctx_var.get()
|
|
143
|
+
if existing_ctx is not None:
|
|
144
|
+
raise RuntimeError(
|
|
145
|
+
"❌ MindPack recursion blocked: ask_mindpack cannot be called recursively. "
|
|
146
|
+
f"Current nested_depth={existing_ctx.nested_depth}, max_depth={existing_ctx.max_depth}. "
|
|
147
|
+
"Experts are already running in advisory mode; invoking another MindPack panel "
|
|
148
|
+
"inside an active consultation would create an infinite loop."
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# 2. Check per-prompt call count
|
|
152
|
+
current_calls = _mindpack_call_count_var.get()
|
|
153
|
+
if current_calls >= nested_config.max_calls_per_prompt:
|
|
154
|
+
raise RuntimeError(
|
|
155
|
+
"❌ MindPack call-limit reached: ask_mindpack has already been invoked "
|
|
156
|
+
f"{current_calls} time(s) in this prompt (max_calls_per_prompt="
|
|
157
|
+
f"{nested_config.max_calls_per_prompt}). To prevent execution loops, "
|
|
158
|
+
"further MindPack calls are blocked for the remainder of this turn."
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
# 3. Increment counters and build a new context
|
|
162
|
+
call_token = _mindpack_call_count_var.set(current_calls + 1)
|
|
163
|
+
new_ctx = MindPackInvocationContext(
|
|
164
|
+
nested_depth=1,
|
|
165
|
+
max_depth=nested_config.max_depth,
|
|
166
|
+
max_calls_per_prompt=nested_config.max_calls_per_prompt,
|
|
167
|
+
call_count=current_calls + 1,
|
|
168
|
+
)
|
|
169
|
+
ctx_token = _mindpack_ctx_var.set(new_ctx)
|
|
170
|
+
|
|
171
|
+
# Return tokens so the caller can reset them in a finally block
|
|
172
|
+
new_ctx._call_token = call_token # type: ignore[attr-defined]
|
|
173
|
+
new_ctx._ctx_token = ctx_token # type: ignore[attr-defined]
|
|
174
|
+
return new_ctx
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _reset_context(ctx: MindPackInvocationContext) -> None:
|
|
178
|
+
"""Reset ContextVars after a MindPack invocation finishes."""
|
|
179
|
+
try:
|
|
180
|
+
_mindpack_ctx_var.reset(ctx._ctx_token) # type: ignore[attr-defined]
|
|
181
|
+
except Exception:
|
|
182
|
+
pass
|
|
183
|
+
try:
|
|
184
|
+
_mindpack_call_count_var.reset(ctx._call_token) # type: ignore[attr-defined]
|
|
185
|
+
except Exception:
|
|
186
|
+
pass
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# ---------------------------------------------------------------------------
|
|
190
|
+
# Singleton orchestrator + default expert registration
|
|
191
|
+
# ---------------------------------------------------------------------------
|
|
192
|
+
|
|
193
|
+
orchestrator = MindPackOrchestrator()
|
|
194
|
+
|
|
195
|
+
_DEFAULT_EXPERTS: list[ExpertDescriptor] = [
|
|
196
|
+
ExpertDescriptor(
|
|
197
|
+
name="Scout",
|
|
198
|
+
speciality="codebase exploration & context gathering",
|
|
199
|
+
model="fast",
|
|
200
|
+
system_prompt_fragment=(
|
|
201
|
+
"You are Scout, the codebase explorer. Your job is to quickly "
|
|
202
|
+
"scan relevant files, trace dependencies, and surface the "
|
|
203
|
+
"context needed to understand a problem. Focus on what exists "
|
|
204
|
+
"and how it connects."
|
|
205
|
+
),
|
|
206
|
+
),
|
|
207
|
+
ExpertDescriptor(
|
|
208
|
+
name="Architect",
|
|
209
|
+
speciality="design & architecture decisions",
|
|
210
|
+
model="strong",
|
|
211
|
+
system_prompt_fragment=(
|
|
212
|
+
"You are Architect, the design thinker. Your job is to "
|
|
213
|
+
"propose clean structural solutions, weigh trade-offs, "
|
|
214
|
+
"and ensure the plan fits the existing codebase architecture."
|
|
215
|
+
),
|
|
216
|
+
),
|
|
217
|
+
ExpertDescriptor(
|
|
218
|
+
name="Strategic Architect",
|
|
219
|
+
speciality="big-picture architecture & long-term vision",
|
|
220
|
+
model="strong",
|
|
221
|
+
system_prompt_fragment=(
|
|
222
|
+
"You are Strategic Architect, the big-picture thinker. Your job is to "
|
|
223
|
+
"step back and design the long-term architecture — system boundaries, "
|
|
224
|
+
"module ownership, technology choices, and how the plan fits the "
|
|
225
|
+
"project's 6-month roadmap. Think in terms of maintainability, "
|
|
226
|
+
"scalability, and technical debt avoidance. Propose the ideal end-state "
|
|
227
|
+
"and work backwards to a phased delivery plan."
|
|
228
|
+
),
|
|
229
|
+
),
|
|
230
|
+
ExpertDescriptor(
|
|
231
|
+
name="Systems Architect",
|
|
232
|
+
speciality="component integration & data flow design",
|
|
233
|
+
model="strong",
|
|
234
|
+
system_prompt_fragment=(
|
|
235
|
+
"You are Systems Architect, the integration specialist. Your job is to "
|
|
236
|
+
"design how components communicate — API contracts, data models, event "
|
|
237
|
+
"flows, and service boundaries. Focus on the seams between modules: "
|
|
238
|
+
"what data moves where, what interfaces need to change, and how to "
|
|
239
|
+
"minimize coupling. Your plans should make the integration surface "
|
|
240
|
+
"explicit and testable."
|
|
241
|
+
),
|
|
242
|
+
),
|
|
243
|
+
ExpertDescriptor(
|
|
244
|
+
name="Pragmatic Architect",
|
|
245
|
+
speciality="incremental delivery & risk-aware planning",
|
|
246
|
+
model="strong",
|
|
247
|
+
system_prompt_fragment=(
|
|
248
|
+
"You are Pragmatic Architect, the delivery-focused planner. Your job is "
|
|
249
|
+
"to find the smallest viable change that moves the needle. You balance "
|
|
250
|
+
"idealism with reality — prefer incremental refactors over rewrites, "
|
|
251
|
+
"identify what can be deferred, and always have a rollback strategy. "
|
|
252
|
+
"Your plans prioritize developer velocity, reversibility, and "
|
|
253
|
+
"shipping value early."
|
|
254
|
+
),
|
|
255
|
+
),
|
|
256
|
+
ExpertDescriptor(
|
|
257
|
+
name="Watchdog",
|
|
258
|
+
speciality="risk assessment & edge-case analysis",
|
|
259
|
+
model="medium",
|
|
260
|
+
system_prompt_fragment=(
|
|
261
|
+
"You are Watchdog, the risk analyst. Your job is to "
|
|
262
|
+
"identify failure modes, security concerns, edge cases, "
|
|
263
|
+
"and anything that could go wrong with a proposed plan."
|
|
264
|
+
),
|
|
265
|
+
),
|
|
266
|
+
ExpertDescriptor(
|
|
267
|
+
name="Test Planner",
|
|
268
|
+
speciality="validation strategy & test design",
|
|
269
|
+
model="medium",
|
|
270
|
+
system_prompt_fragment=(
|
|
271
|
+
"You are Test Planner, the validation strategist. Your job is "
|
|
272
|
+
"to design the smallest effective test suite that confirms "
|
|
273
|
+
"the plan works and catches regressions."
|
|
274
|
+
),
|
|
275
|
+
),
|
|
276
|
+
ExpertDescriptor(
|
|
277
|
+
name="Challenger",
|
|
278
|
+
speciality="adversarial review & assumption questioning",
|
|
279
|
+
model="strong",
|
|
280
|
+
system_prompt_fragment=(
|
|
281
|
+
"You are Challenger, the adversarial reviewer. Your job is "
|
|
282
|
+
"to poke holes in every proposal, question assumptions, "
|
|
283
|
+
"and argue for simpler alternatives when they exist."
|
|
284
|
+
),
|
|
285
|
+
),
|
|
286
|
+
]
|
|
287
|
+
|
|
288
|
+
orchestrator.register_experts(_DEFAULT_EXPERTS)
|
|
289
|
+
orchestrator.load_experts() # Load any custom experts from disk
|
|
290
|
+
orchestrator.load_profiles() # Load profiles (seeds defaults on first run)
|
|
291
|
+
|
|
292
|
+
logger.info(
|
|
293
|
+
"MindPack orchestrator initialised with %d default expert(s): %s",
|
|
294
|
+
len(_DEFAULT_EXPERTS),
|
|
295
|
+
[e.name for e in _DEFAULT_EXPERTS],
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
# ---------------------------------------------------------------------------
|
|
299
|
+
# Tool registration
|
|
300
|
+
# ---------------------------------------------------------------------------
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def register_ask_mindpack(agent):
|
|
304
|
+
"""Register the ask_mindpack tool on the given agent."""
|
|
305
|
+
|
|
306
|
+
@agent.tool
|
|
307
|
+
async def ask_mindpack(
|
|
308
|
+
context: RunContext,
|
|
309
|
+
problem_statement: str,
|
|
310
|
+
current_goal: str,
|
|
311
|
+
current_plan: str | None = None,
|
|
312
|
+
what_has_been_tried: list[str] | None = None,
|
|
313
|
+
relevant_files: list[str] | None = None,
|
|
314
|
+
observed_errors: list[str] | None = None,
|
|
315
|
+
uncertainty: str | None = None,
|
|
316
|
+
desired_output: Literal[
|
|
317
|
+
"plan",
|
|
318
|
+
"review",
|
|
319
|
+
"debug_strategy",
|
|
320
|
+
"architecture_decision",
|
|
321
|
+
"test_strategy",
|
|
322
|
+
"compare_options",
|
|
323
|
+
] = "plan",
|
|
324
|
+
max_experts: int | None = None,
|
|
325
|
+
) -> AskMindPackOutput:
|
|
326
|
+
"""Request a deep advisory analysis from the MindPack expert pool.
|
|
327
|
+
|
|
328
|
+
Use this tool when you encounter a problem that needs deeper
|
|
329
|
+
reasoning, multiple expert perspectives, or comparison of
|
|
330
|
+
approaches. MindPack runs in nested advisory mode: experts
|
|
331
|
+
are read-only, make no file edits, and cannot call ask_mindpack
|
|
332
|
+
recursively.
|
|
333
|
+
|
|
334
|
+
Do NOT call this for simple edits or direct user requests
|
|
335
|
+
that require only a single obvious action.
|
|
336
|
+
|
|
337
|
+
Args:
|
|
338
|
+
problem_statement: The specific problem to solve.
|
|
339
|
+
current_goal: What you are currently trying to achieve.
|
|
340
|
+
current_plan: Your current plan, if any.
|
|
341
|
+
what_has_been_tried: Approaches already attempted.
|
|
342
|
+
relevant_files: File paths relevant to the problem.
|
|
343
|
+
observed_errors: Error messages or unexpected behaviours.
|
|
344
|
+
uncertainty: What you are uncertain about.
|
|
345
|
+
desired_output: Kind of advisory output you want.
|
|
346
|
+
max_experts: Cap on number of experts to consult.
|
|
347
|
+
"""
|
|
348
|
+
nested_config = load_nested_config_from_ini()
|
|
349
|
+
|
|
350
|
+
# Epic 5 & 6 — enforce nested-workflow guardrails
|
|
351
|
+
invocation_ctx = _check_and_increment_call(nested_config)
|
|
352
|
+
try:
|
|
353
|
+
logger.info(
|
|
354
|
+
"ask_mindpack invoked: desired_output=%s, problem=%s "
|
|
355
|
+
"depth=%d/%d calls=%d/%d",
|
|
356
|
+
desired_output,
|
|
357
|
+
problem_statement[:120],
|
|
358
|
+
invocation_ctx.nested_depth,
|
|
359
|
+
invocation_ctx.max_depth,
|
|
360
|
+
invocation_ctx.call_count,
|
|
361
|
+
invocation_ctx.max_calls_per_prompt,
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
request = AskMindPackInput(
|
|
365
|
+
problem_statement=problem_statement,
|
|
366
|
+
current_goal=current_goal,
|
|
367
|
+
current_plan=current_plan,
|
|
368
|
+
what_has_been_tried=what_has_been_tried or [],
|
|
369
|
+
relevant_files=relevant_files or [],
|
|
370
|
+
observed_errors=observed_errors or [],
|
|
371
|
+
uncertainty=uncertainty,
|
|
372
|
+
desired_output=desired_output,
|
|
373
|
+
max_experts=max_experts,
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
# Run orchestration with invocation context so the orchestrator
|
|
377
|
+
# knows it is inside a nested workflow (e.g., for timeout caps).
|
|
378
|
+
raw_output = await orchestrator.consult(
|
|
379
|
+
request,
|
|
380
|
+
invocation_context=invocation_ctx,
|
|
381
|
+
nested_config=nested_config,
|
|
382
|
+
)
|
|
383
|
+
return raw_output
|
|
384
|
+
finally:
|
|
385
|
+
_reset_context(invocation_ctx)
|
|
386
|
+
|
|
387
|
+
return ask_mindpack
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"""Shared HTML templates for OAuth result pages with clean colored status indicators."""
|
|
2
|
+
|
|
3
|
+
CLAUDE_LOGO_URL = "https://voideditor.com/claude-icon.png"
|
|
4
|
+
CHATGPT_LOGO_URL = (
|
|
5
|
+
"https://freelogopng.com/images/all_img/1681038325chatgpt-logo-transparent.png"
|
|
6
|
+
)
|
|
7
|
+
GEMINI_LOGO_URL = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Google_Gemini_logo.svg/512px-Google_Gemini_logo.svg.png"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def oauth_success_html(service_name: str, extra_message: str | None = None) -> str:
|
|
11
|
+
"""Return a clean OAuth success HTML page with colored status indicators."""
|
|
12
|
+
clean_service = service_name.strip() or "OAuth"
|
|
13
|
+
detail = f"<p class='detail'>{extra_message}</p>" if extra_message else ""
|
|
14
|
+
projectile, rival_url, rival_alt, target_modifier = _service_targets(clean_service)
|
|
15
|
+
target_classes = "target" if not target_modifier else f"target {target_modifier}"
|
|
16
|
+
return (
|
|
17
|
+
"<!DOCTYPE html>"
|
|
18
|
+
"<html lang='en'><head><meta charset='utf-8'>"
|
|
19
|
+
"<title>Auth Complete</title>"
|
|
20
|
+
"<style>"
|
|
21
|
+
"html,body{margin:0;padding:0;height:100%;overflow:hidden;font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:linear-gradient(135deg,#0f172a 0%,#111827 45%,#1f2937 100%);color:#e5e7eb;}"
|
|
22
|
+
"body{display:flex;align-items:center;justify-content:center;}"
|
|
23
|
+
".panel{position:relative;width:90%;max-width:880px;padding:60px;background:rgba(15,23,42,0.72);border-radius:32px;backdrop-filter:blur(14px);box-shadow:0 30px 90px rgba(8,11,18,0.7);text-align:center;border:1px solid rgba(148,163,184,0.25);}"
|
|
24
|
+
"h1{font-size:3.4em;margin:0;color:#f1f5f9;text-shadow:0 14px 40px rgba(8,11,18,0.55);letter-spacing:1px;}"
|
|
25
|
+
"p{font-size:1.25em;margin:16px 0;color:#cbd5f5;}"
|
|
26
|
+
".detail{font-size:1.1em;opacity:0.9;}"
|
|
27
|
+
".mega{display:inline-block;font-size:1.35em;margin-top:14px;color:#f97316;}"
|
|
28
|
+
".confetti{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:200%;height:200%;pointer-events:none;mix-blend-mode:screen;}"
|
|
29
|
+
".confetti span{position:absolute;font-size:3.4em;animation:floaty 6s ease-in-out infinite;}"
|
|
30
|
+
".confetti span.ok{color:#4ade80;}"
|
|
31
|
+
".confetti span.warn{color:#facc15;}"
|
|
32
|
+
".confetti span.info{color:#60a5fa;}"
|
|
33
|
+
"@keyframes floaty{0%,100%{transform:translate3d(0,0,0) rotate(0deg);}35%{transform:translate3d(0,-70px,0) rotate(10deg);}65%{transform:translate3d(0,-90px,0) rotate(-12deg);}90%{transform:translate3d(0,-60px,0) rotate(6deg);}}"
|
|
34
|
+
".confetti span:nth-child(odd){animation-duration:7.2s;}"
|
|
35
|
+
".confetti span:nth-child(3n){animation-duration:8.6s;}"
|
|
36
|
+
".confetti span:nth-child(4n){animation-duration:5.9s;}"
|
|
37
|
+
".confetti span:nth-child(5n){animation-duration:9.4s;}"
|
|
38
|
+
".artillery{position:absolute;bottom:12%;left:0;width:100%;max-width:1100px;height:240px;pointer-events:none;overflow:visible;}"
|
|
39
|
+
".artillery .cannon{position:absolute;bottom:0;font-size:3.4em;filter:drop-shadow(0 12px 32px rgba(249,115,22,0.45));}"
|
|
40
|
+
".artillery .cannon.left{left:4%;color:#4ade80;}"
|
|
41
|
+
".artillery .cannon.right{left:12%;transform:rotate(-4deg);color:#f87171;}"
|
|
42
|
+
".artillery .shell{position:absolute;left:10%;font-size:2.6em;animation:strafe 2.6s ease-out infinite;color:#facc15;text-shadow:0 0 14px rgba(250,204,21,0.45);}"
|
|
43
|
+
"@keyframes strafe{0%{left:10%;opacity:1;}60%{left:72%;opacity:1;}100%{left:82%;opacity:0;}}"
|
|
44
|
+
".target{position:absolute;top:175px;right:-10%;width:220px;filter:drop-shadow(0 24px 46px rgba(8,11,18,0.72));animation:targetShake 1.9s ease-in-out infinite;}"
|
|
45
|
+
".target img{width:200px;height:auto;border-radius:18px;background:#0f172a;padding:16px;border:1px solid rgba(148,163,184,0.35);}"
|
|
46
|
+
".target.invert img{filter:brightness(1.2) saturate(1.15);background:rgba(15,23,42,0.9);}"
|
|
47
|
+
"@keyframes targetShake{0%,100%{transform:rotate(0deg) scale(1);}30%{transform:rotate(-4deg) scale(1.05);}60%{transform:rotate(3deg) scale(0.97);}85%{transform:rotate(-2deg) scale(1.04);}}"
|
|
48
|
+
".target::after{content:'';position:absolute;top:50%;left:50%;width:220px;height:220px;border-radius:50%;background:radial-gradient(circle,rgba(74,222,128,0.35)0%,rgba(74,222,128,0)70%);transform:translate(-50%,-50%) scale(0);animation:impact 2.6s ease-out infinite;opacity:0;mix-blend-mode:screen;}"
|
|
49
|
+
"@keyframes impact{0%,60%{transform:translate(-50%,-50%) scale(0);opacity:0;}70%{transform:translate(-50%,-50%) scale(1.2);opacity:1;}100%{transform:translate(-50%,-50%) scale(1.5);opacity:0;}}"
|
|
50
|
+
"</style>"
|
|
51
|
+
"</head><body>"
|
|
52
|
+
"<div class='panel'>"
|
|
53
|
+
"<div class='confetti'>"
|
|
54
|
+
+ "".join(
|
|
55
|
+
f"<span class='{cls}' style='left:{left}%;top:{top}%;animation-delay:{delay}s;'>{token}</span>"
|
|
56
|
+
for left, top, delay, token, cls in _SUCCESS_TOKENS
|
|
57
|
+
)
|
|
58
|
+
+ "</div>"
|
|
59
|
+
f"<h1>[Done] {clean_service} Auth Complete</h1>"
|
|
60
|
+
"<p class='mega'>Authentication complete. Token delivered.</p>"
|
|
61
|
+
f"{detail}"
|
|
62
|
+
f"<p>Token payload delivered to {rival_alt}.</p>"
|
|
63
|
+
"<p>This window will auto-close shortly.</p>"
|
|
64
|
+
"<p class='mega'>Return to your session.</p>"
|
|
65
|
+
f"<div class='{target_classes}'><img src='{rival_url}' alt='{rival_alt}'></div>"
|
|
66
|
+
"<div class='artillery'>" + _build_artillery(projectile) + "</div>"
|
|
67
|
+
"</div>"
|
|
68
|
+
"<script>setTimeout(()=>window.close(),3500);</script>"
|
|
69
|
+
"</body></html>"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def oauth_failure_html(service_name: str, reason: str) -> str:
|
|
74
|
+
"""Return a clean OAuth failure HTML page with colored status indicators."""
|
|
75
|
+
clean_service = service_name.strip() or "OAuth"
|
|
76
|
+
clean_reason = reason.strip() or "Authentication failed"
|
|
77
|
+
projectile, rival_url, rival_alt, target_modifier = _service_targets(clean_service)
|
|
78
|
+
target_classes = "target" if not target_modifier else f"target {target_modifier}"
|
|
79
|
+
return (
|
|
80
|
+
"<!DOCTYPE html>"
|
|
81
|
+
"<html lang='en'><head><meta charset='utf-8'>"
|
|
82
|
+
"<title>Auth Failed</title>"
|
|
83
|
+
"<style>"
|
|
84
|
+
"html,body{margin:0;padding:0;height:100%;overflow:hidden;font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:linear-gradient(160deg,#101827 0%,#0b1120 100%);color:#e2e8f0;}"
|
|
85
|
+
"body{display:flex;align-items:center;justify-content:center;}"
|
|
86
|
+
".panel{position:relative;width:90%;max-width:780px;padding:55px;background:rgba(10,13,23,0.78);border-radius:30px;box-shadow:0 26px 80px rgba(2,6,23,0.78);text-align:center;border:1px solid rgba(71,85,105,0.35);}"
|
|
87
|
+
"h1{font-size:3em;margin:0 0 14px;text-shadow:0 16px 36px rgba(15,23,42,0.7);color:#f87171;}"
|
|
88
|
+
"p{font-size:1.2em;margin:14px 0;line-height:1.6;color:#cbd5f5;}"
|
|
89
|
+
".alert{font-size:1.35em;margin:18px 0;color:#fda4af;}"
|
|
90
|
+
".tearstorm{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:190%;height:190%;pointer-events:none;mix-blend-mode:screen;}"
|
|
91
|
+
".tearstorm span{position:absolute;font-size:3.2em;animation:weep 4.8s ease-in-out infinite;}"
|
|
92
|
+
".tearstorm span.fail{color:#f87171;}"
|
|
93
|
+
".tearstorm span.warn{color:#fbbf24;}"
|
|
94
|
+
".tearstorm span.info{color:#60a5fa;}"
|
|
95
|
+
"@keyframes weep{0%{transform:translate3d(0,-10px,0) rotate(-6deg);opacity:0.85;}35%{transform:translate3d(-20px,18px,0) rotate(8deg);opacity:1;}65%{transform:translate3d(25px,28px,0) rotate(-12deg);opacity:0.8;}100%{transform:translate3d(0,60px,0) rotate(0deg);opacity:0;}}"
|
|
96
|
+
".tearstorm span:nth-child(odd){animation-duration:5.8s;}"
|
|
97
|
+
".tearstorm span:nth-child(3n){animation-duration:6.4s;}"
|
|
98
|
+
".tearstorm span:nth-child(4n){animation-duration:7.3s;}"
|
|
99
|
+
".buttons{margin-top:26px;}"
|
|
100
|
+
".buttons a{display:inline-block;margin:6px 12px;padding:12px 28px;border-radius:999px;background:rgba(59,130,246,0.16);color:#bfdbfe;text-decoration:none;font-weight:600;border:1px solid rgba(96,165,250,0.4);transition:all 0.3s;}"
|
|
101
|
+
".buttons a:hover{background:rgba(96,165,250,0.28);transform:translateY(-2px);}"
|
|
102
|
+
".battlefield{position:absolute;bottom:-25px;left:0;width:100%;max-width:960px;height:220px;pointer-events:none;}"
|
|
103
|
+
".battlefield .shell{position:absolute;left:10%;font-size:2.4em;color:#38bdf8;text-shadow:0 0 12px rgba(56,189,248,0.45);animation:strafeSad 3s ease-out infinite;}"
|
|
104
|
+
"@keyframes strafeSad{0%{left:10%;opacity:1;}65%{left:70%;opacity:1;}100%{left:80%;opacity:0;}}"
|
|
105
|
+
".battlefield .target{position:absolute;top:16px;right:6%;width:220px;filter:drop-shadow(0 20px 44px rgba(2,6,23,0.78));animation:sway 2s ease-in-out infinite;}"
|
|
106
|
+
".battlefield .target img{width:200px;height:auto;border-radius:18px;background:#0b1120;padding:16px;border:1px solid rgba(96,165,250,0.4);}"
|
|
107
|
+
".battlefield .target.invert img{filter:brightness(1.2) saturate(1.15);background:rgba(15,23,42,0.9);}"
|
|
108
|
+
"@keyframes sway{0%,100%{transform:rotate(0deg);}40%{transform:rotate(-6deg);}70%{transform:rotate(5deg);}}"
|
|
109
|
+
"</style>"
|
|
110
|
+
"</head><body>"
|
|
111
|
+
"<div class='panel'>"
|
|
112
|
+
"<div class='tearstorm'>"
|
|
113
|
+
+ "".join(
|
|
114
|
+
f"<span class='{cls}' style='left:{left}%;top:{top}%;animation-delay:{delay}s;'>{token}</span>"
|
|
115
|
+
for left, top, delay, token, cls in _FAILURE_TOKENS
|
|
116
|
+
)
|
|
117
|
+
+ "</div>"
|
|
118
|
+
f"<h1>[Fail] {clean_service} Auth Failed</h1>"
|
|
119
|
+
"<p class='alert'>Authentication failed.</p>"
|
|
120
|
+
f"<p>{clean_reason}</p>"
|
|
121
|
+
"<p>Retry from Muse.</p>"
|
|
122
|
+
f"<p>Re-attempt authentication with {rival_alt}.</p>"
|
|
123
|
+
"<div class='buttons'>"
|
|
124
|
+
"<a href='https://muse.dev' target='_blank'>Documentation</a>"
|
|
125
|
+
"<a href='https://github.com/asx8678/muse' target='_blank'>GitHub</a>"
|
|
126
|
+
"</div>"
|
|
127
|
+
"<div class='battlefield'>"
|
|
128
|
+
+ _build_artillery(projectile, shells_only=True)
|
|
129
|
+
+ f"<div class='{target_classes}'><img src='{rival_url}' alt='{rival_alt}'></div>"
|
|
130
|
+
+ "</div>"
|
|
131
|
+
"</div>"
|
|
132
|
+
"</body></html>"
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
_SUCCESS_TOKENS = (
|
|
137
|
+
(5, 12, 0.0, "[Done]", "ok"),
|
|
138
|
+
(18, 28, 0.2, "[Done]", "ok"),
|
|
139
|
+
(32, 6, 1.1, "[OK]", "ok"),
|
|
140
|
+
(46, 18, 0.5, "[Done]", "ok"),
|
|
141
|
+
(62, 9, 0.8, "[OK]", "ok"),
|
|
142
|
+
(76, 22, 1.3, "[Done]", "ok"),
|
|
143
|
+
(88, 14, 0.4, "[OK]", "ok"),
|
|
144
|
+
(12, 48, 0.6, "[Run]", "info"),
|
|
145
|
+
(28, 58, 1.7, "[>>]", "info"),
|
|
146
|
+
(44, 42, 0.9, "[Run]", "info"),
|
|
147
|
+
(58, 52, 1.5, "[>>]", "info"),
|
|
148
|
+
(72, 46, 0.3, "[Run]", "info"),
|
|
149
|
+
(86, 54, 1.1, "[>>]", "info"),
|
|
150
|
+
(8, 72, 0.7, "[Done]", "ok"),
|
|
151
|
+
(24, 80, 1.2, "[OK]", "ok"),
|
|
152
|
+
(40, 74, 0.2, "[Done]", "ok"),
|
|
153
|
+
(56, 66, 1.6, "[Run]", "info"),
|
|
154
|
+
(70, 78, 1.0, "[>>]", "info"),
|
|
155
|
+
(84, 70, 1.4, "[Run]", "info"),
|
|
156
|
+
(16, 90, 0.5, "[Done]", "ok"),
|
|
157
|
+
(32, 92, 1.9, "[OK]", "ok"),
|
|
158
|
+
(48, 88, 1.1, "[Run]", "info"),
|
|
159
|
+
(64, 94, 1.8, "[>>]", "info"),
|
|
160
|
+
(78, 88, 0.6, "[Done]", "ok"),
|
|
161
|
+
(90, 82, 1.3, "[OK]", "ok"),
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
_FAILURE_TOKENS = (
|
|
165
|
+
(8, 6, 0.0, "[Fail]", "fail"),
|
|
166
|
+
(22, 18, 0.3, "[!!]", "fail"),
|
|
167
|
+
(36, 10, 0.6, "[Fail]", "fail"),
|
|
168
|
+
(50, 20, 0.9, "[!!]", "fail"),
|
|
169
|
+
(64, 8, 1.2, "[Fail]", "fail"),
|
|
170
|
+
(78, 16, 1.5, "[!!]", "fail"),
|
|
171
|
+
(12, 38, 0.4, "[Warn]", "warn"),
|
|
172
|
+
(28, 44, 0.7, "[??]", "warn"),
|
|
173
|
+
(42, 34, 1.0, "[Warn]", "warn"),
|
|
174
|
+
(58, 46, 1.3, "[??]", "warn"),
|
|
175
|
+
(72, 36, 1.6, "[Warn]", "warn"),
|
|
176
|
+
(86, 40, 1.9, "[??]", "warn"),
|
|
177
|
+
(16, 64, 0.5, "[Fail]", "fail"),
|
|
178
|
+
(32, 70, 0.8, "[!!]", "fail"),
|
|
179
|
+
(48, 60, 1.1, "[Fail]", "fail"),
|
|
180
|
+
(62, 74, 1.4, "[!!]", "fail"),
|
|
181
|
+
(78, 68, 1.7, "[Fail]", "fail"),
|
|
182
|
+
(90, 72, 2.0, "[!!]", "fail"),
|
|
183
|
+
(20, 88, 0.6, "[Warn]", "warn"),
|
|
184
|
+
(36, 92, 0.9, "[??]", "warn"),
|
|
185
|
+
(52, 86, 1.2, "[Warn]", "warn"),
|
|
186
|
+
(68, 94, 1.5, "[??]", "warn"),
|
|
187
|
+
(82, 90, 1.8, "[Warn]", "warn"),
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
_STRAFE_SHELLS: tuple[tuple[float, float], ...] = (
|
|
191
|
+
(22.0, 0.0),
|
|
192
|
+
(28.0, 0.35),
|
|
193
|
+
(34.0, 0.7),
|
|
194
|
+
(26.0, 0.2),
|
|
195
|
+
(32.0, 0.55),
|
|
196
|
+
(24.0, 0.9),
|
|
197
|
+
(30.0, 1.25),
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def _build_artillery(projectile: str, *, shells_only: bool = False) -> str:
|
|
202
|
+
"""Return HTML spans for artillery shells (and cannons when desired)."""
|
|
203
|
+
shell_markup = []
|
|
204
|
+
for index, (top, delay) in enumerate(_STRAFE_SHELLS):
|
|
205
|
+
duration = 2.3 + (index % 3) * 0.25
|
|
206
|
+
shell_markup.append(
|
|
207
|
+
f"<span class='shell' style='top:{top}%;animation-delay:-{delay}s;animation-duration:{duration}s;'>{projectile}</span>"
|
|
208
|
+
)
|
|
209
|
+
shells = "".join(shell_markup)
|
|
210
|
+
if shells_only:
|
|
211
|
+
return shells
|
|
212
|
+
|
|
213
|
+
cannons = "<span class='cannon left'>[Launch]</span><span class='cannon right'>[Fire]</span>"
|
|
214
|
+
return cannons + shells
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def _service_targets(service_name: str) -> tuple[str, str, str, str]:
|
|
218
|
+
"""Map service names to projectile label and rival logo metadata."""
|
|
219
|
+
normalized = service_name.lower()
|
|
220
|
+
if "anthropic" in normalized or "claude" in normalized:
|
|
221
|
+
return "[Launch]", CLAUDE_LOGO_URL, "Claude logo", ""
|
|
222
|
+
if "chat" in normalized or "gpt" in normalized:
|
|
223
|
+
return "[Fire]", CHATGPT_LOGO_URL, "ChatGPT logo", "invert"
|
|
224
|
+
if "gemini" in normalized or "google" in normalized:
|
|
225
|
+
return "[Auth]", GEMINI_LOGO_URL, "Gemini logo", ""
|
|
226
|
+
return "[Fire]", CHATGPT_LOGO_URL, "service logo", "invert"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Tab-completion for ``/ollama-setup <model>``."""
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable
|
|
4
|
+
|
|
5
|
+
from prompt_toolkit.completion import Completer, Completion
|
|
6
|
+
from prompt_toolkit.document import Document
|
|
7
|
+
|
|
8
|
+
from code_muse.plugins.ollama_setup.register_callbacks import CLOUD_MODELS
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class OllamaSetupCompleter(Completer):
|
|
12
|
+
"""Completes cloud model names after ``/ollama-setup ``."""
|
|
13
|
+
|
|
14
|
+
trigger = "/ollama-setup"
|
|
15
|
+
|
|
16
|
+
def get_completions(
|
|
17
|
+
self, document: Document, complete_event: object
|
|
18
|
+
) -> Iterable[Completion]:
|
|
19
|
+
text = document.text_before_cursor.lstrip()
|
|
20
|
+
|
|
21
|
+
if not text.startswith(self.trigger + " "):
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
# Everything after "/ollama-setup "
|
|
25
|
+
after = text[len(self.trigger) + 1 :]
|
|
26
|
+
partial = after.strip().lower()
|
|
27
|
+
start_pos = -len(after) if after else 0
|
|
28
|
+
|
|
29
|
+
for tag, meta in CLOUD_MODELS.items():
|
|
30
|
+
if not partial or tag.lower().startswith(partial):
|
|
31
|
+
yield Completion(
|
|
32
|
+
tag,
|
|
33
|
+
start_position=start_pos,
|
|
34
|
+
display=tag,
|
|
35
|
+
display_meta=meta["description"],
|
|
36
|
+
)
|