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.
Files changed (394) hide show
  1. code_muse/__init__.py +26 -0
  2. code_muse/__main__.py +10 -0
  3. code_muse/agents/__init__.py +31 -0
  4. code_muse/agents/_builder.py +214 -0
  5. code_muse/agents/_compaction.py +506 -0
  6. code_muse/agents/_diagnostics.py +171 -0
  7. code_muse/agents/_history.py +382 -0
  8. code_muse/agents/_key_listeners.py +148 -0
  9. code_muse/agents/_non_streaming_render.py +148 -0
  10. code_muse/agents/_runtime.py +596 -0
  11. code_muse/agents/agent_creator_agent.py +603 -0
  12. code_muse/agents/agent_helios.py +47 -0
  13. code_muse/agents/agent_manager.py +740 -0
  14. code_muse/agents/agent_muse.py +78 -0
  15. code_muse/agents/agent_planning.py +44 -0
  16. code_muse/agents/agent_qa_melpomene.py +207 -0
  17. code_muse/agents/base_agent.py +194 -0
  18. code_muse/agents/event_stream_handler.py +361 -0
  19. code_muse/agents/json_agent.py +201 -0
  20. code_muse/agents/prompt_v3.py +521 -0
  21. code_muse/agents/subagent_stream_handler.py +273 -0
  22. code_muse/callbacks.py +941 -0
  23. code_muse/chatgpt_codex_client.py +333 -0
  24. code_muse/claude_cache_client.py +853 -0
  25. code_muse/cli_runner/__init__.py +319 -0
  26. code_muse/cli_runner/args.py +63 -0
  27. code_muse/cli_runner/loop.py +510 -0
  28. code_muse/cli_runner/resume.py +72 -0
  29. code_muse/cli_runner/runner.py +161 -0
  30. code_muse/command_line/__init__.py +1 -0
  31. code_muse/command_line/add_model_menu.py +1331 -0
  32. code_muse/command_line/agent_menu.py +674 -0
  33. code_muse/command_line/attachments.py +397 -0
  34. code_muse/command_line/autosave_menu.py +709 -0
  35. code_muse/command_line/clipboard.py +528 -0
  36. code_muse/command_line/colors_menu.py +530 -0
  37. code_muse/command_line/command_handler.py +262 -0
  38. code_muse/command_line/command_registry.py +150 -0
  39. code_muse/command_line/config_commands.py +711 -0
  40. code_muse/command_line/core_commands.py +740 -0
  41. code_muse/command_line/diff_menu.py +865 -0
  42. code_muse/command_line/file_path_completion.py +73 -0
  43. code_muse/command_line/load_context_completion.py +57 -0
  44. code_muse/command_line/model_picker_completion.py +512 -0
  45. code_muse/command_line/model_settings_menu.py +983 -0
  46. code_muse/command_line/onboarding_slides.py +162 -0
  47. code_muse/command_line/onboarding_wizard.py +337 -0
  48. code_muse/command_line/pagination.py +41 -0
  49. code_muse/command_line/pin_command_completion.py +329 -0
  50. code_muse/command_line/prompt_toolkit_completion.py +886 -0
  51. code_muse/command_line/session_commands.py +304 -0
  52. code_muse/command_line/shell_passthrough.py +145 -0
  53. code_muse/command_line/skills_completion.py +158 -0
  54. code_muse/command_line/types.py +18 -0
  55. code_muse/command_line/uc_menu.py +908 -0
  56. code_muse/command_line/utils.py +105 -0
  57. code_muse/command_line/wiggum_state.py +77 -0
  58. code_muse/config.py +1138 -0
  59. code_muse/config_agent.py +168 -0
  60. code_muse/config_appearance.py +241 -0
  61. code_muse/config_model.py +357 -0
  62. code_muse/config_security.py +73 -0
  63. code_muse/error_logging.py +132 -0
  64. code_muse/evals/__init__.py +35 -0
  65. code_muse/evals/eval_helpers.py +81 -0
  66. code_muse/evals/eval_runner.py +299 -0
  67. code_muse/evals/sample_evals/__init__.py +1 -0
  68. code_muse/evals/sample_evals/eval_frugal_reads.py +59 -0
  69. code_muse/evals/sample_evals/eval_memory_planning.py +31 -0
  70. code_muse/evals/sample_evals/eval_shell_efficiency.py +39 -0
  71. code_muse/evals/sample_evals/eval_tool_masking.py +33 -0
  72. code_muse/fs_scan_cache/__init__.py +31 -0
  73. code_muse/fs_scan_cache/invalidation_hooks.py +89 -0
  74. code_muse/fs_scan_cache/scan_cache_core.cpython-314-darwin.so +0 -0
  75. code_muse/fs_scan_cache/scan_cache_core.pyx +203 -0
  76. code_muse/fs_scan_cache/tool_integration.py +309 -0
  77. code_muse/fs_scan_cache/ttl_policy.py +44 -0
  78. code_muse/gemini_code_assist.py +383 -0
  79. code_muse/gemini_model.py +838 -0
  80. code_muse/hook_engine/README.md +105 -0
  81. code_muse/hook_engine/__init__.py +21 -0
  82. code_muse/hook_engine/aliases.py +153 -0
  83. code_muse/hook_engine/engine.py +221 -0
  84. code_muse/hook_engine/executor.py +347 -0
  85. code_muse/hook_engine/matcher.py +154 -0
  86. code_muse/hook_engine/models.py +245 -0
  87. code_muse/hook_engine/registry.py +114 -0
  88. code_muse/hook_engine/trust.py +268 -0
  89. code_muse/hook_engine/validator.py +144 -0
  90. code_muse/http_utils.py +360 -0
  91. code_muse/keymap.py +128 -0
  92. code_muse/list_filtering.py +26 -0
  93. code_muse/main.py +10 -0
  94. code_muse/messaging/__init__.py +259 -0
  95. code_muse/messaging/bus.py +621 -0
  96. code_muse/messaging/commands.py +166 -0
  97. code_muse/messaging/markdown_patches.py +57 -0
  98. code_muse/messaging/message_queue.py +397 -0
  99. code_muse/messaging/messages.py +591 -0
  100. code_muse/messaging/queue_console.py +269 -0
  101. code_muse/messaging/renderers.py +308 -0
  102. code_muse/messaging/rich_renderer.py +1158 -0
  103. code_muse/messaging/shimmer.py +154 -0
  104. code_muse/messaging/spinner/__init__.py +87 -0
  105. code_muse/messaging/spinner/console_spinner.py +250 -0
  106. code_muse/messaging/spinner/spinner_base.py +82 -0
  107. code_muse/messaging/subagent_console.py +458 -0
  108. code_muse/model_factory.py +1203 -0
  109. code_muse/model_switching.py +59 -0
  110. code_muse/model_utils.py +156 -0
  111. code_muse/models.json +66 -0
  112. code_muse/models_cache/__init__.py +26 -0
  113. code_muse/models_cache/blocking_lru_cache.py +98 -0
  114. code_muse/models_cache/cache_writer.py +86 -0
  115. code_muse/models_cache/sha256_hash.cpython-314-darwin.so +0 -0
  116. code_muse/models_cache/sha256_hash.pyx +34 -0
  117. code_muse/models_cache/startup_integration.py +75 -0
  118. code_muse/models_dev_api.json +1 -0
  119. code_muse/models_dev_parser.py +590 -0
  120. code_muse/motion.py +126 -0
  121. code_muse/plugins/__init__.py +471 -0
  122. code_muse/plugins/agent_skills/__init__.py +32 -0
  123. code_muse/plugins/agent_skills/config.py +176 -0
  124. code_muse/plugins/agent_skills/discovery.py +309 -0
  125. code_muse/plugins/agent_skills/downloader.py +389 -0
  126. code_muse/plugins/agent_skills/installer.py +19 -0
  127. code_muse/plugins/agent_skills/metadata.py +293 -0
  128. code_muse/plugins/agent_skills/prompt_builder.py +66 -0
  129. code_muse/plugins/agent_skills/register_callbacks.py +298 -0
  130. code_muse/plugins/agent_skills/remote_catalog.py +320 -0
  131. code_muse/plugins/agent_skills/skill_catalog.py +254 -0
  132. code_muse/plugins/agent_skills/skills_install_menu.py +690 -0
  133. code_muse/plugins/agent_skills/skills_menu.py +791 -0
  134. code_muse/plugins/autonomous_memory/__init__.py +39 -0
  135. code_muse/plugins/autonomous_memory/bm25_scorer.cpython-314-darwin.so +0 -0
  136. code_muse/plugins/autonomous_memory/bm25_scorer.cpython-314-x86_64-linux-gnu.so +0 -0
  137. code_muse/plugins/autonomous_memory/bm25_scorer.pyx +291 -0
  138. code_muse/plugins/autonomous_memory/consolidation.py +82 -0
  139. code_muse/plugins/autonomous_memory/extraction.py +382 -0
  140. code_muse/plugins/autonomous_memory/lease_lock.py +105 -0
  141. code_muse/plugins/autonomous_memory/memory_injection.py +59 -0
  142. code_muse/plugins/autonomous_memory/register_callbacks.py +268 -0
  143. code_muse/plugins/autonomous_memory/secret_scanner.py +62 -0
  144. code_muse/plugins/autonomous_memory/session_scanner.py +163 -0
  145. code_muse/plugins/aws_bedrock/__init__.py +14 -0
  146. code_muse/plugins/aws_bedrock/config.py +99 -0
  147. code_muse/plugins/aws_bedrock/register_callbacks.py +241 -0
  148. code_muse/plugins/aws_bedrock/utils.py +153 -0
  149. code_muse/plugins/azure_foundry/README.md +238 -0
  150. code_muse/plugins/azure_foundry/__init__.py +15 -0
  151. code_muse/plugins/azure_foundry/config.py +125 -0
  152. code_muse/plugins/azure_foundry/discovery.py +187 -0
  153. code_muse/plugins/azure_foundry/register_callbacks.py +495 -0
  154. code_muse/plugins/azure_foundry/token.py +180 -0
  155. code_muse/plugins/azure_foundry/utils.py +345 -0
  156. code_muse/plugins/build_filter/__init__.py +1 -0
  157. code_muse/plugins/build_filter/register_callbacks.py +201 -0
  158. code_muse/plugins/build_filter/strategies/__init__.py +1 -0
  159. code_muse/plugins/build_filter/strategies/build.py +397 -0
  160. code_muse/plugins/chatgpt_oauth/__init__.py +6 -0
  161. code_muse/plugins/chatgpt_oauth/config.py +52 -0
  162. code_muse/plugins/chatgpt_oauth/oauth_flow.py +338 -0
  163. code_muse/plugins/chatgpt_oauth/register_callbacks.py +172 -0
  164. code_muse/plugins/chatgpt_oauth/test_plugin.py +301 -0
  165. code_muse/plugins/chatgpt_oauth/utils.py +538 -0
  166. code_muse/plugins/checkpointing/__init__.py +29 -0
  167. code_muse/plugins/checkpointing/checkpoint_hook.py +51 -0
  168. code_muse/plugins/checkpointing/conversation_snapshots.py +117 -0
  169. code_muse/plugins/checkpointing/register_callbacks.py +51 -0
  170. code_muse/plugins/checkpointing/restore_command.py +263 -0
  171. code_muse/plugins/checkpointing/rewind_shortcut.py +88 -0
  172. code_muse/plugins/checkpointing/shadow_git.py +90 -0
  173. code_muse/plugins/claude_code_hooks/__init__.py +1 -0
  174. code_muse/plugins/claude_code_hooks/config.py +188 -0
  175. code_muse/plugins/claude_code_hooks/register_callbacks.py +208 -0
  176. code_muse/plugins/claude_code_oauth/README.md +167 -0
  177. code_muse/plugins/claude_code_oauth/SETUP.md +93 -0
  178. code_muse/plugins/claude_code_oauth/__init__.py +25 -0
  179. code_muse/plugins/claude_code_oauth/config.py +52 -0
  180. code_muse/plugins/claude_code_oauth/fast_mode.py +124 -0
  181. code_muse/plugins/claude_code_oauth/prompt_handler.py +63 -0
  182. code_muse/plugins/claude_code_oauth/register_callbacks.py +547 -0
  183. code_muse/plugins/claude_code_oauth/test_fast_mode.py +165 -0
  184. code_muse/plugins/claude_code_oauth/test_plugin.py +283 -0
  185. code_muse/plugins/claude_code_oauth/token_refresh_heartbeat.py +237 -0
  186. code_muse/plugins/claude_code_oauth/utils.py +664 -0
  187. code_muse/plugins/copilot_auth/__init__.py +11 -0
  188. code_muse/plugins/copilot_auth/config.py +91 -0
  189. code_muse/plugins/copilot_auth/reasoning_client.py +409 -0
  190. code_muse/plugins/copilot_auth/register_callbacks.py +461 -0
  191. code_muse/plugins/copilot_auth/utils.py +584 -0
  192. code_muse/plugins/custom_commands/__init__.py +14 -0
  193. code_muse/plugins/custom_commands/args_injection.py +82 -0
  194. code_muse/plugins/custom_commands/command_discovery.py +89 -0
  195. code_muse/plugins/custom_commands/command_toml_schema.py +71 -0
  196. code_muse/plugins/custom_commands/register_callbacks.py +176 -0
  197. code_muse/plugins/customizable_commands/__init__.py +0 -0
  198. code_muse/plugins/customizable_commands/register_callbacks.py +136 -0
  199. code_muse/plugins/destructive_command_guard/__init__.py +14 -0
  200. code_muse/plugins/destructive_command_guard/detector.py +375 -0
  201. code_muse/plugins/destructive_command_guard/register_callbacks.py +148 -0
  202. code_muse/plugins/example_custom_command/README.md +280 -0
  203. code_muse/plugins/example_custom_command/register_callbacks.py +51 -0
  204. code_muse/plugins/file_permission_handler/__init__.py +4 -0
  205. code_muse/plugins/file_permission_handler/register_callbacks.py +441 -0
  206. code_muse/plugins/filter_engine/__init__.py +30 -0
  207. code_muse/plugins/filter_engine/classifier.py +153 -0
  208. code_muse/plugins/filter_engine/content_detector.py +184 -0
  209. code_muse/plugins/filter_engine/dispatcher.py +244 -0
  210. code_muse/plugins/filter_engine/register_callbacks.py +188 -0
  211. code_muse/plugins/filter_engine/registry.py +279 -0
  212. code_muse/plugins/filter_engine/strategies/__init__.py +8 -0
  213. code_muse/plugins/filter_engine/strategies/ast_compressor.cpython-314-darwin.so +0 -0
  214. code_muse/plugins/filter_engine/strategies/ast_compressor.cpython-314-x86_64-linux-gnu.so +0 -0
  215. code_muse/plugins/filter_engine/strategies/ast_compressor.pyx +348 -0
  216. code_muse/plugins/filter_engine/strategies/ast_parser.py +167 -0
  217. code_muse/plugins/filter_engine/strategies/code.cpython-314-darwin.so +0 -0
  218. code_muse/plugins/filter_engine/strategies/code.cpython-314-x86_64-linux-gnu.so +0 -0
  219. code_muse/plugins/filter_engine/strategies/code.pyx +584 -0
  220. code_muse/plugins/filter_engine/strategies/git.cpython-314-darwin.so +0 -0
  221. code_muse/plugins/filter_engine/strategies/git.cpython-314-x86_64-linux-gnu.so +0 -0
  222. code_muse/plugins/filter_engine/strategies/git.pyx +438 -0
  223. code_muse/plugins/filter_engine/strategies/json_compressor.cpython-314-darwin.so +0 -0
  224. code_muse/plugins/filter_engine/strategies/json_compressor.pyx +253 -0
  225. code_muse/plugins/filter_engine/strategies/json_patterns.cpython-314-darwin.so +0 -0
  226. code_muse/plugins/filter_engine/strategies/json_patterns.pyx +178 -0
  227. code_muse/plugins/filter_engine/strategies/lint.cpython-314-darwin.so +0 -0
  228. code_muse/plugins/filter_engine/strategies/lint.cpython-314-x86_64-linux-gnu.so +0 -0
  229. code_muse/plugins/filter_engine/strategies/lint.pyx +626 -0
  230. code_muse/plugins/filter_engine/strategies/test.cpython-314-darwin.so +0 -0
  231. code_muse/plugins/filter_engine/strategies/test.cpython-314-x86_64-linux-gnu.so +0 -0
  232. code_muse/plugins/filter_engine/strategies/test.pyx +431 -0
  233. code_muse/plugins/filter_engine/verbosity.py +63 -0
  234. code_muse/plugins/force_push_guard/__init__.py +5 -0
  235. code_muse/plugins/force_push_guard/detector.py +96 -0
  236. code_muse/plugins/force_push_guard/register_callbacks.py +144 -0
  237. code_muse/plugins/force_push_guard/test_detector.py +143 -0
  238. code_muse/plugins/frontend_emitter/__init__.py +25 -0
  239. code_muse/plugins/frontend_emitter/emitter.py +121 -0
  240. code_muse/plugins/frontend_emitter/register_callbacks.py +259 -0
  241. code_muse/plugins/gac/__init__.py +4 -0
  242. code_muse/plugins/gac/git_ops.py +136 -0
  243. code_muse/plugins/gac/prompt.py +191 -0
  244. code_muse/plugins/gac/register_callbacks.py +82 -0
  245. code_muse/plugins/hook_creator/__init__.py +1 -0
  246. code_muse/plugins/hook_creator/register_callbacks.py +34 -0
  247. code_muse/plugins/hook_manager/__init__.py +1 -0
  248. code_muse/plugins/hook_manager/config.py +289 -0
  249. code_muse/plugins/hook_manager/hooks_menu.py +563 -0
  250. code_muse/plugins/hook_manager/register_callbacks.py +227 -0
  251. code_muse/plugins/hook_monitor/register_callbacks.py +36 -0
  252. code_muse/plugins/mindpack/__init__.py +0 -0
  253. code_muse/plugins/mindpack/factory.py +930 -0
  254. code_muse/plugins/mindpack/judge.py +573 -0
  255. code_muse/plugins/mindpack/memory.py +100 -0
  256. code_muse/plugins/mindpack/mindpack_menu.py +1552 -0
  257. code_muse/plugins/mindpack/orchestration.py +605 -0
  258. code_muse/plugins/mindpack/register_callbacks.py +175 -0
  259. code_muse/plugins/mindpack/schemas.py +358 -0
  260. code_muse/plugins/mindpack/tools.py +387 -0
  261. code_muse/plugins/oauth_muse_html.py +226 -0
  262. code_muse/plugins/ollama_setup/__init__.py +5 -0
  263. code_muse/plugins/ollama_setup/completer.py +36 -0
  264. code_muse/plugins/ollama_setup/register_callbacks.py +410 -0
  265. code_muse/plugins/plan_command/__init__.py +0 -0
  266. code_muse/plugins/plan_command/register_callbacks.py +206 -0
  267. code_muse/plugins/plan_mode/__init__.py +37 -0
  268. code_muse/plugins/plan_mode/mode_cycling.py +40 -0
  269. code_muse/plugins/plan_mode/plan_generation.py +68 -0
  270. code_muse/plugins/plan_mode/plan_hooks.py +74 -0
  271. code_muse/plugins/plan_mode/plan_mode_tools.py +138 -0
  272. code_muse/plugins/plan_mode/register_callbacks.py +121 -0
  273. code_muse/plugins/plugin_trust/register_callbacks.py +140 -0
  274. code_muse/plugins/policy_engine/__init__.py +46 -0
  275. code_muse/plugins/policy_engine/approval_flow_integration.py +59 -0
  276. code_muse/plugins/policy_engine/policy_evaluator.py +75 -0
  277. code_muse/plugins/policy_engine/policy_file_discovery.py +90 -0
  278. code_muse/plugins/policy_engine/policy_toml_schema.py +115 -0
  279. code_muse/plugins/policy_engine/register_callbacks.py +112 -0
  280. code_muse/plugins/pop_command/__init__.py +1 -0
  281. code_muse/plugins/pop_command/register_callbacks.py +189 -0
  282. code_muse/plugins/prompt_newline/__init__.py +13 -0
  283. code_muse/plugins/prompt_newline/config.py +19 -0
  284. code_muse/plugins/prompt_newline/register_callbacks.py +159 -0
  285. code_muse/plugins/safety_status/__init__.py +0 -0
  286. code_muse/plugins/safety_status/register_callbacks.py +113 -0
  287. code_muse/plugins/semantic_compression/__init__.py +6 -0
  288. code_muse/plugins/semantic_compression/compressor.py +295 -0
  289. code_muse/plugins/semantic_compression/config.py +123 -0
  290. code_muse/plugins/semantic_compression/register_callbacks.py +320 -0
  291. code_muse/plugins/shell_minimizer/__init__.py +50 -0
  292. code_muse/plugins/shell_minimizer/builtin_filters.toml +393 -0
  293. code_muse/plugins/shell_minimizer/pipeline.py +556 -0
  294. code_muse/plugins/shell_minimizer/primitives.py +482 -0
  295. code_muse/plugins/shell_minimizer/register_callbacks.py +276 -0
  296. code_muse/plugins/shell_safety/__init__.py +6 -0
  297. code_muse/plugins/shell_safety/agent_shell_safety.py +69 -0
  298. code_muse/plugins/shell_safety/command_cache.py +149 -0
  299. code_muse/plugins/shell_safety/register_callbacks.py +202 -0
  300. code_muse/plugins/synthetic_status/__init__.py +1 -0
  301. code_muse/plugins/synthetic_status/register_callbacks.py +128 -0
  302. code_muse/plugins/synthetic_status/status_api.py +145 -0
  303. code_muse/plugins/token_caching/__init__.py +21 -0
  304. code_muse/plugins/token_caching/cache_hit_tracking.py +128 -0
  305. code_muse/plugins/token_caching/cacheable_prefix_detection.py +28 -0
  306. code_muse/plugins/token_caching/register_callbacks.py +54 -0
  307. code_muse/plugins/token_caching/stats_display.py +35 -0
  308. code_muse/plugins/token_tracking/__init__.py +26 -0
  309. code_muse/plugins/token_tracking/database.py +381 -0
  310. code_muse/plugins/token_tracking/edit_analyzer.py +97 -0
  311. code_muse/plugins/token_tracking/record.py +55 -0
  312. code_muse/plugins/token_tracking/register_callbacks.py +277 -0
  313. code_muse/plugins/token_tracking/reports.py +329 -0
  314. code_muse/plugins/universal_constructor/__init__.py +13 -0
  315. code_muse/plugins/universal_constructor/models.py +136 -0
  316. code_muse/plugins/universal_constructor/register_callbacks.py +47 -0
  317. code_muse/plugins/universal_constructor/registry.py +390 -0
  318. code_muse/plugins/universal_constructor/runner.py +474 -0
  319. code_muse/plugins/universal_constructor/safety.py +440 -0
  320. code_muse/plugins/universal_constructor/sandbox.py +584 -0
  321. code_muse/provider_identity.py +105 -0
  322. code_muse/pydantic_patches.py +410 -0
  323. code_muse/reopenable_async_client.py +233 -0
  324. code_muse/round_robin_model.py +151 -0
  325. code_muse/secret_storage.py +74 -0
  326. code_muse/security/__init__.py +1 -0
  327. code_muse/security/redaction.cpython-314-darwin.so +0 -0
  328. code_muse/security/redaction.cpython-314-x86_64-linux-gnu.so +0 -0
  329. code_muse/security/redaction.pyx +135 -0
  330. code_muse/session_storage.py +565 -0
  331. code_muse/status_display.py +261 -0
  332. code_muse/stream_parser/__init__.py +76 -0
  333. code_muse/stream_parser/assistant_text_parser.py +90 -0
  334. code_muse/stream_parser/citation_parser.py +76 -0
  335. code_muse/stream_parser/inline_hidden_tag_parser.py +236 -0
  336. code_muse/stream_parser/proposed_plan_parser.py +158 -0
  337. code_muse/stream_parser/stream_text_chunk.py +23 -0
  338. code_muse/stream_parser/stream_text_parser.py +27 -0
  339. code_muse/stream_parser/tagged_line_parser.cpython-314-darwin.so +0 -0
  340. code_muse/stream_parser/tagged_line_parser.pyx +251 -0
  341. code_muse/stream_parser/utf8_stream_parser.cpython-314-darwin.so +0 -0
  342. code_muse/stream_parser/utf8_stream_parser.pyx +206 -0
  343. code_muse/summarization_agent.py +308 -0
  344. code_muse/terminal_utils.cpython-314-darwin.so +0 -0
  345. code_muse/terminal_utils.cpython-314-x86_64-linux-gnu.so +0 -0
  346. code_muse/terminal_utils.pyx +483 -0
  347. code_muse/tools/__init__.py +459 -0
  348. code_muse/tools/agent_tools.py +613 -0
  349. code_muse/tools/ask_user_question/__init__.py +26 -0
  350. code_muse/tools/ask_user_question/constants.py +73 -0
  351. code_muse/tools/ask_user_question/demo_tui.py +55 -0
  352. code_muse/tools/ask_user_question/handler.py +232 -0
  353. code_muse/tools/ask_user_question/models.py +302 -0
  354. code_muse/tools/ask_user_question/registration.py +37 -0
  355. code_muse/tools/ask_user_question/renderers.py +336 -0
  356. code_muse/tools/ask_user_question/terminal_ui.py +327 -0
  357. code_muse/tools/ask_user_question/theme.py +156 -0
  358. code_muse/tools/ask_user_question/tui_loop.py +422 -0
  359. code_muse/tools/background_jobs.py +99 -0
  360. code_muse/tools/browser/__init__.py +37 -0
  361. code_muse/tools/browser/browser_control.py +289 -0
  362. code_muse/tools/browser/browser_interactions.py +545 -0
  363. code_muse/tools/browser/browser_locators.py +640 -0
  364. code_muse/tools/browser/browser_manager.py +376 -0
  365. code_muse/tools/browser/browser_navigation.py +251 -0
  366. code_muse/tools/browser/browser_screenshot.py +180 -0
  367. code_muse/tools/browser/browser_scripts.py +462 -0
  368. code_muse/tools/browser/browser_workflows.py +222 -0
  369. code_muse/tools/chrome_cdp/__init__.py +1070 -0
  370. code_muse/tools/chrome_cdp/register_callbacks.py +61 -0
  371. code_muse/tools/command_runner.py +1401 -0
  372. code_muse/tools/common.py +1407 -0
  373. code_muse/tools/display.py +87 -0
  374. code_muse/tools/file_modifications.py +1099 -0
  375. code_muse/tools/file_operations.py +860 -0
  376. code_muse/tools/image_tools.py +185 -0
  377. code_muse/tools/meetin_proxy/__init__.py +243 -0
  378. code_muse/tools/meetin_proxy/capture_addon.py +82 -0
  379. code_muse/tools/meetin_proxy/proxy_manager.py +326 -0
  380. code_muse/tools/meetin_proxy/register_callbacks.py +45 -0
  381. code_muse/tools/path_policy.py +219 -0
  382. code_muse/tools/skills_tools.py +586 -0
  383. code_muse/tools/subagent_context.py +158 -0
  384. code_muse/tools/tools_content.py +50 -0
  385. code_muse/tools/universal_constructor.py +965 -0
  386. code_muse/uvx_detection.py +241 -0
  387. code_muse/version_checker.py +86 -0
  388. code_muse-0.0.1.data/data/code_muse/models.json +66 -0
  389. code_muse-0.0.1.data/data/code_muse/models_dev_api.json +1 -0
  390. code_muse-0.0.1.dist-info/METADATA +845 -0
  391. code_muse-0.0.1.dist-info/RECORD +394 -0
  392. code_muse-0.0.1.dist-info/WHEEL +4 -0
  393. code_muse-0.0.1.dist-info/entry_points.txt +2 -0
  394. code_muse-0.0.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,279 @@
1
+ """Strategy registry for the filter engine.
2
+
3
+ Maps command categories to compression strategy functions. Handles
4
+ registration, duplicate detection, and priority-based overrides.
5
+ """
6
+
7
+ import json
8
+ import logging
9
+ import re
10
+ from collections.abc import Callable
11
+ from typing import Any
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+
16
+ class StrategyRegistry:
17
+ """Registry mapping category names to compression strategy functions."""
18
+
19
+ def __init__(self) -> None:
20
+ """Initialize the registry with the built-in ``unknown`` passthrough."""
21
+ self._strategies: dict[str, tuple[Callable, int]] = {}
22
+ self._register_passthrough()
23
+
24
+ def _register_passthrough(self) -> None:
25
+ """Register the built-in passthrough strategy for ``unknown``."""
26
+
27
+ def _passthrough(
28
+ command: str,
29
+ stdout: str,
30
+ stderr: str,
31
+ exit_code: int,
32
+ verbosity: Any, # noqa: ANN401
33
+ ) -> Any: # noqa: ANN401
34
+ """Return None to signal that normal execution should proceed."""
35
+ return None
36
+
37
+ self._strategies["unknown"] = (_passthrough, -1)
38
+
39
+ def register(
40
+ self,
41
+ category: str,
42
+ strategy_fn: Callable,
43
+ priority: int = 0,
44
+ ) -> None:
45
+ """Register a strategy function for a category.
46
+
47
+ If a strategy is already registered for the category, the new one
48
+ wins only when *priority* is greater than the existing priority.
49
+ A warning is logged on collision regardless.
50
+
51
+ Args:
52
+ category: The command category (e.g. ``"git"``).
53
+ strategy_fn: Callable that accepts
54
+ ``(command, stdout, stderr, exit_code, verbosity)`` and returns
55
+ a ``ShellCommandOutput`` or ``None``.
56
+ priority: Higher values win on collision. Defaults to ``0``.
57
+ """
58
+ existing = self._strategies.get(category)
59
+ if existing is not None:
60
+ _, existing_priority = existing
61
+ if priority > existing_priority:
62
+ logger.warning(
63
+ "StrategyRegistry: overriding '%s' strategy (priority %d > %d)",
64
+ category,
65
+ priority,
66
+ existing_priority,
67
+ )
68
+ self._strategies[category] = (strategy_fn, priority)
69
+ else:
70
+ logger.warning(
71
+ "StrategyRegistry: ignoring '%s' strategy registration "
72
+ "(priority %d <= %d)",
73
+ category,
74
+ priority,
75
+ existing_priority,
76
+ )
77
+ else:
78
+ self._strategies[category] = (strategy_fn, priority)
79
+
80
+ def get_strategy(self, category: str) -> Callable | None:
81
+ """Return the strategy function for *category*, or ``None``.
82
+
83
+ The built-in ``unknown`` passthrough always returns a callable that
84
+ itself returns ``None``.
85
+ """
86
+ entry = self._strategies.get(category)
87
+ if entry is None:
88
+ return None
89
+ return entry[0]
90
+
91
+ def list_categories(self) -> list[str]:
92
+ """Return a sorted list of all registered category names."""
93
+ return sorted(self._strategies.keys())
94
+
95
+
96
+ # Module-level singleton instance
97
+ _registry_instance: StrategyRegistry | None = None
98
+
99
+
100
+ def get_registry() -> StrategyRegistry:
101
+ """Return the module-level singleton registry."""
102
+ global _registry_instance
103
+ if _registry_instance is None:
104
+ _registry_instance = StrategyRegistry()
105
+ return _registry_instance
106
+
107
+
108
+ # ---------------------------------------------------------------------------
109
+ # Content-type stub strategies (filled by Epics 020–021)
110
+ # ---------------------------------------------------------------------------
111
+
112
+
113
+ def _register_content_stubs() -> None:
114
+ """Register passthrough stubs for content-type strategies."""
115
+ registry = get_registry()
116
+
117
+ def _json_smartcrusher(
118
+ command: str,
119
+ stdout: str,
120
+ stderr: str,
121
+ exit_code: int,
122
+ verbosity: Any, # noqa: ANN401
123
+ ) -> Any: # noqa: ANN401
124
+ """SmartCrusher JSON compression strategy."""
125
+ if not stdout or not stdout.strip():
126
+ return None
127
+ try:
128
+ data = json.loads(stdout)
129
+ except ValueError:
130
+ # Not valid JSON — let passthrough handle it
131
+ return None
132
+
133
+ from code_muse.plugins.filter_engine.strategies.json_compressor import (
134
+ compress_json,
135
+ )
136
+
137
+ compressed = compress_json(data, verbosity)
138
+
139
+ from code_muse.tools.command_runner import ShellCommandOutput
140
+
141
+ return ShellCommandOutput(
142
+ success=True,
143
+ command=command,
144
+ stdout=compressed,
145
+ stderr=stderr,
146
+ exit_code=exit_code,
147
+ execution_time=0.0,
148
+ )
149
+
150
+ def _diff_stub(
151
+ command: str,
152
+ stdout: str,
153
+ stderr: str,
154
+ exit_code: int,
155
+ verbosity: Any, # noqa: ANN401
156
+ ) -> Any: # noqa: ANN401
157
+ """Stub — basic diff compaction, keeps headers only."""
158
+ lines = stdout.splitlines()
159
+ header_lines = [
160
+ line
161
+ for line in lines
162
+ if line.startswith("@@")
163
+ or line.startswith("diff ")
164
+ or line.startswith("---")
165
+ or line.startswith("+++")
166
+ ]
167
+ if not header_lines:
168
+ return None
169
+ from code_muse.tools.command_runner import ShellCommandOutput
170
+
171
+ return ShellCommandOutput(
172
+ success=True,
173
+ command=command,
174
+ stdout="\n".join(header_lines) + f"\n[{len(lines)} lines in full diff]",
175
+ stderr=stderr,
176
+ exit_code=exit_code,
177
+ execution_time=0.0,
178
+ )
179
+
180
+ def _log_stub(
181
+ command: str,
182
+ stdout: str,
183
+ stderr: str,
184
+ exit_code: int,
185
+ verbosity: Any, # noqa: ANN401
186
+ ) -> Any: # noqa: ANN401
187
+ """Stub — basic log dedup, groups repeated lines."""
188
+ lines = stdout.splitlines()
189
+ if len(lines) < 10:
190
+ return None
191
+ # Simple: just count unique patterns
192
+ from collections import Counter
193
+
194
+ # Keep first 3 and last 3 lines, dedup middle
195
+ if len(lines) <= 6:
196
+ return None
197
+ head = lines[:3]
198
+ tail = lines[-3:]
199
+ middle_patterns = Counter(re.sub(r"\d+", "<N>", line) for line in lines[3:-3])
200
+ compact = (
201
+ head
202
+ + [f"[{len(lines) - 6} lines, {len(middle_patterns)} unique patterns]"]
203
+ + tail
204
+ )
205
+ from code_muse.tools.command_runner import ShellCommandOutput
206
+
207
+ return ShellCommandOutput(
208
+ success=True,
209
+ command=command,
210
+ stdout="\n".join(compact),
211
+ stderr=stderr,
212
+ exit_code=exit_code,
213
+ execution_time=0.0,
214
+ )
215
+
216
+ def _html_stub(
217
+ command: str,
218
+ stdout: str,
219
+ stderr: str,
220
+ exit_code: int,
221
+ verbosity: Any, # noqa: ANN401
222
+ ) -> Any: # noqa: ANN401
223
+ """Stub — basic HTML tag strip."""
224
+ # Strip all tags, keep text content
225
+ text = re.sub(r"<[^>]+>", " ", stdout)
226
+ text = re.sub(r"\s+", " ", text).strip()
227
+ if not text or len(text) < 10:
228
+ return None
229
+ from code_muse.tools.command_runner import ShellCommandOutput
230
+
231
+ return ShellCommandOutput(
232
+ success=True,
233
+ command=command,
234
+ stdout=text[:2000] + ("..." if len(text) > 2000 else ""),
235
+ stderr=stderr,
236
+ exit_code=exit_code,
237
+ execution_time=0.0,
238
+ )
239
+
240
+ def _search_stub(
241
+ command: str,
242
+ stdout: str,
243
+ stderr: str,
244
+ exit_code: int,
245
+ verbosity: Any, # noqa: ANN401
246
+ ) -> Any: # noqa: ANN401
247
+ """Stub — basic search result compaction."""
248
+ # Keep only filename:line:match lines, drop context
249
+ lines = stdout.splitlines()
250
+ match_lines = [
251
+ line
252
+ for line in lines
253
+ if re.match(r"^\S+\.\w+:\d+:", line) or line.startswith("Found ")
254
+ ]
255
+ if not match_lines and lines:
256
+ match_lines = lines[:10] # keep first 10 if no matches identified
257
+ from code_muse.tools.command_runner import ShellCommandOutput
258
+
259
+ return ShellCommandOutput(
260
+ success=True,
261
+ command=command,
262
+ stdout="\n".join(match_lines)
263
+ + (
264
+ f"\n[{len(lines)} total lines]" if len(lines) > len(match_lines) else ""
265
+ ),
266
+ stderr=stderr,
267
+ exit_code=exit_code,
268
+ execution_time=0.0,
269
+ )
270
+
271
+ registry.register("json", _json_smartcrusher, priority=10)
272
+ registry.register("diff", _diff_stub, priority=10)
273
+ registry.register("log", _log_stub, priority=10)
274
+ registry.register("html", _html_stub, priority=10)
275
+ registry.register("search", _search_stub, priority=10)
276
+
277
+
278
+ # Call at module load time
279
+ _register_content_stubs()
@@ -0,0 +1,8 @@
1
+ """Compression strategies for the filter engine."""
2
+
3
+ try:
4
+ import pyximport
5
+
6
+ pyximport.install(language_level=3, build_in_temp=True, inplace=True)
7
+ except Exception:
8
+ pass # Cython not installed or pyximport unavailable — pure Python fallback
@@ -0,0 +1,348 @@
1
+ """AST-aware code compressors for Python, JavaScript, and Go.
2
+
3
+ Keeps semantic essentials (signatures, imports, error paths), drops
4
+ bodies, docstrings, and whitespace.
5
+ """
6
+
7
+ import bisect
8
+ import logging
9
+ from typing import Any
10
+
11
+ from code_muse.plugins.filter_engine.strategies.ast_parser import (
12
+ ASTNode,
13
+ CodeLanguage,
14
+ LanguageParser,
15
+ )
16
+ from code_muse.plugins.filter_engine.verbosity import VerbosityLevel
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ # ---------------------------------------------------------------------------
22
+ # Node importance classification
23
+ # ---------------------------------------------------------------------------
24
+
25
+ # Python node types to KEEP (structural/signature)
26
+ PYTHON_KEEP_TYPES: set[str] = {
27
+ "function_definition",
28
+ "class_definition",
29
+ "import_statement",
30
+ "import_from_statement",
31
+ "try_statement",
32
+ "except_clause",
33
+ "raise_statement",
34
+ "return_statement",
35
+ "decorated_definition",
36
+ "parameters",
37
+ "lambda",
38
+ }
39
+
40
+ # JavaScript/TypeScript node types to KEEP
41
+ JS_KEEP_TYPES: set[str] = {
42
+ "function_declaration",
43
+ "method_definition",
44
+ "class_declaration",
45
+ "export_statement",
46
+ "import_statement",
47
+ "try_statement",
48
+ "catch_clause",
49
+ "throw_statement",
50
+ "return_statement",
51
+ "arrow_function",
52
+ "variable_declarator",
53
+ "lexical_declaration",
54
+ "interface_declaration",
55
+ "type_alias_declaration",
56
+ }
57
+
58
+ # Go node types to KEEP
59
+ GO_KEEP_TYPES: set[str] = {
60
+ "function_declaration",
61
+ "method_declaration",
62
+ "type_declaration",
63
+ "import_declaration",
64
+ "return_statement",
65
+ "if_statement",
66
+ "for_statement",
67
+ "call_expression",
68
+ }
69
+
70
+
71
+ # ---------------------------------------------------------------------------
72
+ # Line-collection helpers
73
+ # ---------------------------------------------------------------------------
74
+
75
+
76
+ def _build_line_map(source: str) -> list[int]:
77
+ """Return a list of byte offsets for the start of every line."""
78
+ offsets = [0]
79
+ for i, ch in enumerate(source):
80
+ if ch == "\n":
81
+ offsets.append(i + 1)
82
+ return offsets
83
+
84
+
85
+ def _byte_to_line(byte_offset: int, line_map: list[int]) -> int:
86
+ """Return the 0-based line number for a given byte offset."""
87
+ return bisect.bisect_right(line_map, byte_offset) - 1
88
+
89
+
90
+ cdef int _byte_to_line_c(int byte_offset, list line_map):
91
+ """Cython-typed binary search — logic identical to _byte_to_line."""
92
+ cdef int lo = 0
93
+ cdef int hi = len(line_map)
94
+ cdef int mid
95
+ while lo < hi:
96
+ mid = (lo + hi) // 2
97
+ if line_map[mid] <= byte_offset:
98
+ lo = mid + 1
99
+ else:
100
+ hi = mid
101
+ return lo - 1
102
+
103
+
104
+ def _walk_cython(
105
+ object node,
106
+ int depth,
107
+ object keep_types,
108
+ int level,
109
+ list lines,
110
+ set kept_lines,
111
+ list line_map,
112
+ object extra_handler,
113
+ ):
114
+ """Cython-typed AST walker — logic identical to the pure-Python _walk."""
115
+ cdef str node_type
116
+ cdef int start_line
117
+ cdef int end_line
118
+ cdef int i
119
+ cdef int j
120
+ cdef int n_lines = len(lines)
121
+
122
+ node_type = node.type
123
+ start_line = _byte_to_line_c(node.start_byte, line_map)
124
+ end_line = _byte_to_line_c(node.end_byte, line_map)
125
+
126
+ if node_type in keep_types:
127
+ for i in range(start_line, min(end_line + 1, n_lines)):
128
+ if node_type == "function_definition" and i == start_line:
129
+ kept_lines.add(i)
130
+ if level >= 3:
131
+ for j in range(start_line + 1, min(start_line + 4, n_lines)):
132
+ kept_lines.add(j)
133
+ elif level >= 1:
134
+ kept_lines.add(start_line + 1)
135
+ break
136
+ elif node_type in ("class_definition", "decorated_definition"):
137
+ kept_lines.add(i)
138
+ if level >= 2:
139
+ for j in range(start_line + 1, min(start_line + 3, n_lines)):
140
+ kept_lines.add(j)
141
+ break
142
+ elif (
143
+ node_type in ("import_statement", "import_from_statement")
144
+ or node_type == "try_statement"
145
+ or node_type == "except_clause"
146
+ or node_type == "raise_statement"
147
+ or node_type == "return_statement"
148
+ ):
149
+ kept_lines.add(i)
150
+ else:
151
+ kept_lines.add(i)
152
+
153
+ if extra_handler is not None:
154
+ extra_handler(node, start_line, end_line, kept_lines, lines, level)
155
+
156
+ for child in node.children:
157
+ _walk_cython(child, depth + 1, keep_types, level, lines, kept_lines, line_map, extra_handler)
158
+
159
+
160
+ def _collect_lines(
161
+ source: str,
162
+ ast: ASTNode,
163
+ keep_types: set[str],
164
+ level: int,
165
+ extra_handler: Any | None = None,
166
+ ) -> set[int]:
167
+ """Walk an AST and collect line numbers to keep."""
168
+ lines = source.split("\n")
169
+ kept_lines: set[int] = set()
170
+ line_map = _build_line_map(source)
171
+
172
+ _walk_cython(ast, 0, keep_types, level, lines, kept_lines, line_map, extra_handler)
173
+ return kept_lines
174
+
175
+
176
+ def _build_output(source: str, kept_lines: set[int], comment_prefix: str = "#") -> str:
177
+ """Build compressed output from kept line numbers."""
178
+ lines = source.split("\n")
179
+ if not kept_lines:
180
+ return source[:200] + "..." if len(source) > 200 else source
181
+
182
+ result_lines: list[str] = []
183
+ last_kept = -1
184
+ for i in sorted(kept_lines):
185
+ if i >= len(lines):
186
+ continue
187
+ if last_kept >= 0 and i > last_kept + 1:
188
+ gap = i - last_kept - 1
189
+ result_lines.append(f"{comment_prefix} ... {gap} lines omitted ...")
190
+ result_lines.append(lines[i])
191
+ last_kept = i
192
+
193
+ if last_kept < len(lines) - 1:
194
+ remaining = len(lines) - 1 - last_kept
195
+ if remaining > 1:
196
+ result_lines.append(f"{comment_prefix} ... {remaining} lines omitted ...")
197
+ elif remaining == 1:
198
+ result_lines.append(lines[-1])
199
+
200
+ return "\n".join(result_lines)
201
+
202
+
203
+ # ---------------------------------------------------------------------------
204
+ # Compressors
205
+ # ---------------------------------------------------------------------------
206
+
207
+
208
+ def compress_python(
209
+ source: str, verbosity: VerbosityLevel | int = VerbosityLevel.COMPACT
210
+ ) -> str:
211
+ """Compress Python source code — keep signatures, drop bodies.
212
+
213
+ Args:
214
+ source: Python source code string.
215
+ verbosity: 0 = signatures only, 4 = keep brief bodies.
216
+
217
+ Returns:
218
+ Compressed Python code.
219
+ """
220
+ level = verbosity.value if isinstance(verbosity, VerbosityLevel) else verbosity
221
+
222
+ ast = LanguageParser.parse(source, CodeLanguage.PYTHON)
223
+ if ast is None:
224
+ return _fallback_compress(source)
225
+
226
+ kept_lines = _collect_lines(source, ast, PYTHON_KEEP_TYPES, level)
227
+ return _build_output(source, kept_lines, comment_prefix="#")
228
+
229
+
230
+ def compress_javascript(
231
+ source: str, verbosity: VerbosityLevel | int = VerbosityLevel.COMPACT
232
+ ) -> str:
233
+ """Compress JavaScript/TypeScript — keep signatures, drop bodies."""
234
+ level = verbosity.value if isinstance(verbosity, VerbosityLevel) else verbosity
235
+
236
+ lang = LanguageParser.detect_language(source)
237
+ ast = LanguageParser.parse(source, lang)
238
+ if ast is None:
239
+ return _fallback_compress(source)
240
+
241
+ lines = source.split("\n")
242
+ kept_lines: set[int] = set()
243
+ line_map = _build_line_map(source)
244
+
245
+ def _walk(node: ASTNode, depth: int = 0) -> None:
246
+ start_line = _byte_to_line(node.start_byte, line_map)
247
+
248
+ if node.type in JS_KEEP_TYPES:
249
+ for i in range(start_line, min(start_line + 1, len(lines))):
250
+ kept_lines.add(i)
251
+ if level >= 3:
252
+ for j in range(start_line + 1, min(start_line + 3, len(lines))):
253
+ kept_lines.add(j)
254
+
255
+ for child in node.children:
256
+ _walk(child, depth + 1)
257
+
258
+ _walk(ast)
259
+ return _build_output(source, kept_lines, comment_prefix="//")
260
+
261
+
262
+ def compress_go(
263
+ source: str, verbosity: VerbosityLevel | int = VerbosityLevel.COMPACT
264
+ ) -> str:
265
+ """Compress Go source — keep func/method/type signatures, drop bodies."""
266
+ level = verbosity.value if isinstance(verbosity, VerbosityLevel) else verbosity
267
+
268
+ ast = LanguageParser.parse(source, CodeLanguage.GO)
269
+ if ast is None:
270
+ return _fallback_compress(source)
271
+
272
+ kept_lines: set[int] = set()
273
+
274
+ def _extra_handler(
275
+ node: ASTNode,
276
+ start_line: int,
277
+ end_line: int,
278
+ kept: set[int],
279
+ lines: list[str],
280
+ level: int,
281
+ ) -> None:
282
+ if node.type in ("function_declaration", "method_declaration"):
283
+ for i in range(start_line, min(start_line + 2, len(lines))):
284
+ kept.add(i)
285
+ for i in range(start_line, min(end_line + 1, len(lines))):
286
+ if "{" in lines[i]:
287
+ kept.add(i)
288
+ break
289
+ if level >= 3:
290
+ for j in range(start_line + 1, min(start_line + 4, len(lines))):
291
+ kept.add(j)
292
+
293
+ kept_lines = _collect_lines(
294
+ source, ast, GO_KEEP_TYPES, level, extra_handler=_extra_handler
295
+ )
296
+ return _build_output(source, kept_lines, comment_prefix="//")
297
+
298
+
299
+ def _fallback_compress(source: str) -> str:
300
+ """Fallback: strip comments when AST parsing fails."""
301
+ lines = source.split("\n")
302
+ result: list[str] = []
303
+ for line in lines:
304
+ stripped = line.strip()
305
+ if stripped.startswith("#") or stripped.startswith("//"):
306
+ continue
307
+ if "#" in line and not line.startswith("#"):
308
+ line = line[: line.index("#")].rstrip()
309
+ if "//" in line and not line.startswith("//"):
310
+ line = line[: line.index("//")].rstrip()
311
+ result.append(line)
312
+ return "\n".join(result)
313
+
314
+
315
+ def compress_ast_code(
316
+ source: str,
317
+ language: CodeLanguage | None = None,
318
+ verbosity: VerbosityLevel | int = VerbosityLevel.COMPACT,
319
+ filename: str | None = None,
320
+ ) -> str:
321
+ """Compress source code using the appropriate language compressor.
322
+
323
+ Args:
324
+ source: Source code string.
325
+ language: Optional pre-detected language.
326
+ verbosity: Compression level.
327
+ filename: Optional filename for language detection.
328
+
329
+ Returns:
330
+ Compressed source code.
331
+ """
332
+ if language is None and filename:
333
+ language = LanguageParser.detect_language(source, filename)
334
+ elif language is None:
335
+ language = LanguageParser.detect_language(source)
336
+
337
+ compressors = {
338
+ CodeLanguage.PYTHON: compress_python,
339
+ CodeLanguage.JAVASCRIPT: compress_javascript,
340
+ CodeLanguage.TYPESCRIPT: compress_javascript,
341
+ CodeLanguage.GO: compress_go,
342
+ }
343
+
344
+ compressor = compressors.get(language)
345
+ if compressor:
346
+ return compressor(source, verbosity)
347
+
348
+ return _fallback_compress(source)