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,166 @@
1
+ """Command models for User → Agent communication in Muse's messaging system.
2
+
3
+ This module defines Pydantic models for commands that flow FROM the UI TO the Agent.
4
+ This is the opposite direction of messages.py (which flows Agent → UI).
5
+
6
+ Commands are used for:
7
+ - Controlling agent execution (cancel, interrupt)
8
+ - Responding to agent requests for user input
9
+ - Providing confirmations and selections
10
+
11
+ The UI layer creates these commands and sends them to the agent/runtime.
12
+ The agent processes them and may emit messages in response.
13
+
14
+ ┌─────────┐ Commands ┌─────────┐
15
+ │ UI │ ────────────> │ Agent │
16
+ │ (User) │ │ │
17
+ │ │ <──────────── │ │
18
+ └─────────┘ Messages └─────────┘
19
+
20
+ NO Rich markup or formatting should be embedded in any string fields.
21
+ """
22
+
23
+ from datetime import UTC, datetime
24
+ from uuid import uuid4
25
+
26
+ from pydantic import BaseModel, Field
27
+
28
+ # =============================================================================
29
+ # Base Command
30
+ # =============================================================================
31
+
32
+
33
+ class BaseCommand(BaseModel):
34
+ """Base class for all commands with auto-generated id and timestamp."""
35
+
36
+ id: str = Field(
37
+ default_factory=lambda: str(uuid4()),
38
+ description="Unique identifier for this command instance",
39
+ )
40
+ timestamp: datetime = Field(
41
+ default_factory=lambda: datetime.now(UTC),
42
+ description="When this command was created (UTC)",
43
+ )
44
+
45
+ model_config = {"frozen": False, "extra": "forbid"}
46
+
47
+
48
+ # =============================================================================
49
+ # Agent Control Commands
50
+ # =============================================================================
51
+
52
+
53
+ class CancelAgentCommand(BaseCommand):
54
+ """Signals the agent to stop current execution gracefully.
55
+
56
+ The agent should finish any in-progress atomic operation, clean up,
57
+ and return control to the user. This is a soft cancellation.
58
+ """
59
+
60
+ reason: str | None = Field(
61
+ default=None,
62
+ description="Optional reason for cancellation (for logging/debugging)",
63
+ )
64
+
65
+
66
+ class InterruptShellCommand(BaseCommand):
67
+ """Signals to interrupt a currently running shell command.
68
+
69
+ This is equivalent to pressing Ctrl+C in a terminal. The shell process
70
+ should receive SIGINT and terminate. Use this when a command is taking
71
+ too long or producing unwanted output.
72
+ """
73
+
74
+ command_id: str | None = Field(
75
+ default=None,
76
+ description="ID of the specific shell command to interrupt (None = current)",
77
+ )
78
+
79
+
80
+ # =============================================================================
81
+ # User Interaction Responses
82
+ # =============================================================================
83
+
84
+
85
+ class UserInputResponse(BaseCommand):
86
+ """Response to a UserInputRequest from the agent.
87
+
88
+ The prompt_id must match the prompt_id from the original UserInputRequest
89
+ so the agent can correlate the response with the request.
90
+ """
91
+
92
+ prompt_id: str = Field(
93
+ description="ID of the prompt this responds to (must match request)"
94
+ )
95
+ value: str = Field(description="The user's input value")
96
+
97
+
98
+ class ConfirmationResponse(BaseCommand):
99
+ """Response to a ConfirmationRequest from the agent.
100
+
101
+ The user can confirm or deny, and optionally provide feedback text
102
+ if the original request had allow_feedback=True.
103
+ """
104
+
105
+ prompt_id: str = Field(
106
+ description="ID of the prompt this responds to (must match request)"
107
+ )
108
+ confirmed: bool = Field(
109
+ description="Whether the user confirmed (True) or denied (False)"
110
+ )
111
+ feedback: str | None = Field(
112
+ default=None,
113
+ description="Optional feedback text from the user",
114
+ )
115
+
116
+
117
+ class SelectionResponse(BaseCommand):
118
+ """Response to a SelectionRequest from the agent.
119
+
120
+ Contains both the index and the value for convenience and validation.
121
+ The agent can verify that selected_value matches options[selected_index].
122
+ """
123
+
124
+ prompt_id: str = Field(
125
+ description="ID of the prompt this responds to (must match request)"
126
+ )
127
+ selected_index: int = Field(
128
+ ge=0,
129
+ description="Zero-based index of the selected option",
130
+ )
131
+ selected_value: str = Field(description="The value of the selected option")
132
+
133
+
134
+ # =============================================================================
135
+ # Union Type for Type Checking
136
+ # =============================================================================
137
+
138
+
139
+ # All concrete command types (excludes BaseCommand itself)
140
+ AnyCommand = (
141
+ CancelAgentCommand
142
+ | InterruptShellCommand
143
+ | UserInputResponse
144
+ | ConfirmationResponse
145
+ | SelectionResponse
146
+ )
147
+ """Union of all command types for type checking."""
148
+
149
+
150
+ # =============================================================================
151
+ # Export all public symbols
152
+ # =============================================================================
153
+
154
+ __all__ = [
155
+ # Base
156
+ "BaseCommand",
157
+ # Agent control
158
+ "CancelAgentCommand",
159
+ "InterruptShellCommand",
160
+ # User interaction responses
161
+ "UserInputResponse",
162
+ "ConfirmationResponse",
163
+ "SelectionResponse",
164
+ # Union type
165
+ "AnyCommand",
166
+ ]
@@ -0,0 +1,57 @@
1
+ """Patches for Rich's Markdown rendering.
2
+
3
+ This module provides customizations to Rich's default Markdown rendering,
4
+ particularly for header justification which is hardcoded to center in Rich.
5
+ """
6
+
7
+ from rich import box
8
+ from rich.markdown import Heading, Markdown
9
+ from rich.panel import Panel
10
+ from rich.text import Text
11
+
12
+
13
+ class LeftJustifiedHeading(Heading):
14
+ """A heading that left-justifies text instead of centering.
15
+
16
+ Rich's default Heading class hardcodes `text.justify = 'center'`,
17
+ which can look odd in a CLI context. This subclass overrides that
18
+ to use left justification instead.
19
+ """
20
+
21
+ def __rich_console__(self, console, options):
22
+ """Render the heading with left justification."""
23
+ text = self.text
24
+ text.justify = "left" # Override Rich's default 'center'
25
+
26
+ if self.tag == "h1":
27
+ # Draw a border around h1s (same as Rich default)
28
+ yield Panel(
29
+ text,
30
+ box=box.HEAVY,
31
+ style="markdown.h1.border",
32
+ )
33
+ else:
34
+ # Styled text for h2 and beyond (same as Rich default)
35
+ if self.tag == "h2":
36
+ yield Text("")
37
+ yield text
38
+
39
+
40
+ _patched = False
41
+
42
+
43
+ def patch_markdown_headings():
44
+ """Patch Rich's Markdown to use left-justified headings.
45
+
46
+ This function is idempotent - calling it multiple times has no effect
47
+ after the first call.
48
+ """
49
+ global _patched
50
+ if _patched:
51
+ return
52
+
53
+ Markdown.elements["heading_open"] = LeftJustifiedHeading
54
+ _patched = True
55
+
56
+
57
+ __all__ = ["patch_markdown_headings", "LeftJustifiedHeading"]
@@ -0,0 +1,397 @@
1
+ """
2
+ Message queue system for decoupling Rich console output from renderers.
3
+
4
+ This allows interactive mode to consume messages and render them appropriately.
5
+ """
6
+
7
+ import asyncio
8
+ import logging
9
+ import queue
10
+ import threading
11
+ from dataclasses import dataclass
12
+ from datetime import UTC, datetime
13
+ from enum import Enum
14
+ from typing import Any
15
+
16
+ from rich.text import Text
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ class MessageType(Enum):
22
+ """Types of messages that can be sent through the queue."""
23
+
24
+ # Basic content types
25
+ INFO = "info"
26
+ SUCCESS = "success"
27
+ WARNING = "warning"
28
+ ERROR = "error"
29
+ DIVIDER = "divider"
30
+
31
+ # Tool-specific types
32
+ TOOL_OUTPUT = "tool_output"
33
+ COMMAND_OUTPUT = "command_output"
34
+ FILE_OPERATION = "file_operation"
35
+
36
+ # Agent-specific types
37
+ AGENT_REASONING = "agent_reasoning"
38
+ PLANNED_NEXT_STEPS = "planned_next_steps"
39
+ AGENT_RESPONSE = "agent_response"
40
+ AGENT_STATUS = "agent_status"
41
+
42
+ # Human interaction types
43
+ HUMAN_INPUT_REQUEST = "human_input_request"
44
+
45
+ # System types
46
+ SYSTEM = "system"
47
+ DEBUG = "debug"
48
+
49
+
50
+ @dataclass
51
+ class UIMessage:
52
+ """A message to be displayed in the UI."""
53
+
54
+ type: MessageType
55
+ content: str | Text | Any # Can be Rich Text, Table, Markdown, etc.
56
+ timestamp: datetime = None
57
+ metadata: dict[str, Any] = None
58
+
59
+ def __post_init__(self):
60
+ if self.timestamp is None:
61
+ self.timestamp = datetime.now(UTC)
62
+ if self.metadata is None:
63
+ self.metadata = {}
64
+
65
+
66
+ class MessageQueue:
67
+ """Thread-safe message queue for UI messages."""
68
+
69
+ def __init__(self, maxsize: int = 1000):
70
+ self._queue = queue.Queue(maxsize=maxsize)
71
+ self._async_queue = None # Will be created when needed
72
+ self._async_queue_maxsize = maxsize
73
+ self._listeners = []
74
+ self._running = False
75
+ self._thread = None
76
+ self._startup_buffer = [] # Buffer messages before any renderer starts
77
+ self._has_active_renderer = False
78
+ self._event_loop = None # Store reference to the event loop
79
+ self._prompt_responses = {} # Store responses to human input requests
80
+ self._prompt_events = {} # threading.Event per prompt_id
81
+ self._prompt_id_counter = 0 # Counter for unique prompt IDs
82
+
83
+ def start(self):
84
+ """Start the queue processing."""
85
+ if self._running:
86
+ return
87
+
88
+ self._running = True
89
+ self._thread = threading.Thread(target=self._process_messages, daemon=True)
90
+ self._thread.start()
91
+
92
+ def get_buffered_messages(self):
93
+ """Get all currently buffered messages without waiting."""
94
+ # First get any startup buffered messages
95
+ messages = list(self._startup_buffer)
96
+
97
+ # Then get any queued messages
98
+ while True:
99
+ try:
100
+ message = self._queue.get_nowait()
101
+ messages.append(message)
102
+ except queue.Empty:
103
+ break
104
+ return messages
105
+
106
+ def clear_startup_buffer(self):
107
+ """Clear the startup buffer after processing."""
108
+ self._startup_buffer.clear()
109
+
110
+ def stop(self):
111
+ """Stop the queue processing."""
112
+ self._running = False
113
+ if self._thread and self._thread.is_alive():
114
+ self._thread.join(timeout=1.0)
115
+
116
+ def emit(self, message: UIMessage):
117
+ """Emit a message to the queue."""
118
+ # If no renderer is active yet, buffer the message for startup
119
+ if not self._has_active_renderer:
120
+ self._startup_buffer.append(message)
121
+ return
122
+
123
+ try:
124
+ self._queue.put_nowait(message)
125
+ except queue.Full:
126
+ # Drop oldest message to make room
127
+ try:
128
+ self._queue.get_nowait()
129
+ self._queue.put_nowait(message)
130
+ except queue.Empty:
131
+ pass
132
+
133
+ def emit_simple(self, message_type: MessageType, content: Any, **metadata):
134
+ """Emit a simple message with just type and content."""
135
+ msg = UIMessage(type=message_type, content=content, metadata=metadata)
136
+ self.emit(msg)
137
+
138
+ def get_nowait(self) -> UIMessage | None:
139
+ """Get a message without blocking."""
140
+ try:
141
+ return self._queue.get_nowait()
142
+ except queue.Empty:
143
+ return None
144
+
145
+ def drain(self, timeout: float = 1.0) -> bool:
146
+ """Best-effort wait for queued messages to render.
147
+
148
+ Call this immediately before reading from stdin (input(), safe_input,
149
+ prompt_toolkit, etc.) so that any previously-emitted emit_info /
150
+ emit_warning text has a chance to actually appear on screen
151
+ before the prompt steals the terminal. Without this, a prompt label
152
+ can show up *above* the message that was meant to introduce it.
153
+
154
+ Args:
155
+ timeout: Maximum seconds to wait for the queue to empty.
156
+
157
+ Returns:
158
+ True if the queue drained within the timeout, False otherwise.
159
+ """
160
+ import time
161
+
162
+ # Fast path: queue already empty. Do one short paint-pause so the
163
+ # daemon thread can finish rendering whatever it just dequeued.
164
+ if self._queue.empty():
165
+ time.sleep(0.05)
166
+ return True
167
+
168
+ deadline = time.monotonic() + max(0.0, timeout)
169
+ while time.monotonic() < deadline:
170
+ if self._queue.empty():
171
+ time.sleep(0.05)
172
+ return True
173
+ time.sleep(0.02)
174
+ return False
175
+
176
+ async def get_async(self) -> UIMessage:
177
+ """Get a message asynchronously."""
178
+ # Lazy initialization of async queue and store event loop reference
179
+ if self._async_queue is None:
180
+ self._async_queue = asyncio.Queue(maxsize=self._async_queue_maxsize)
181
+ self._event_loop = asyncio.get_running_loop()
182
+ return await self._async_queue.get()
183
+
184
+ def _process_messages(self):
185
+ """Process messages from sync to async queue."""
186
+ while self._running:
187
+ try:
188
+ message = self._queue.get(timeout=0.1)
189
+
190
+ # Try to put in async queue if we have an event loop reference
191
+ if self._event_loop is not None and self._async_queue is not None:
192
+ # Use thread-safe call to put message in async queue
193
+ # Create a bound method to avoid closure issues
194
+ try:
195
+ self._event_loop.call_soon_threadsafe(
196
+ self._async_queue.put_nowait, message
197
+ )
198
+ except Exception as e:
199
+ logger.debug("Failed to enqueue message to async queue: %s", e)
200
+
201
+ # Notify listeners immediately for sync processing
202
+ for listener in self._listeners:
203
+ try:
204
+ listener(message)
205
+ except Exception as e:
206
+ logger.debug("Listener error in message queue: %s", e)
207
+
208
+ except queue.Empty:
209
+ continue
210
+
211
+ def add_listener(self, callback):
212
+ """Add a listener for messages (for direct sync consumption)."""
213
+ self._listeners.append(callback)
214
+ # Mark that we have an active renderer
215
+ self._has_active_renderer = True
216
+
217
+ def remove_listener(self, callback):
218
+ """Remove a listener."""
219
+ if callback in self._listeners:
220
+ self._listeners.remove(callback)
221
+ # If no more listeners, mark as no active renderer
222
+ if not self._listeners:
223
+ self._has_active_renderer = False
224
+
225
+ def mark_renderer_active(self):
226
+ """Mark that a renderer is now active and consuming messages."""
227
+ self._has_active_renderer = True
228
+
229
+ def mark_renderer_inactive(self):
230
+ """Mark that no renderer is currently active."""
231
+ self._has_active_renderer = False
232
+
233
+ def create_prompt_request(self, prompt_text: str) -> str:
234
+ """Create a human input request and return its unique ID."""
235
+ self._prompt_id_counter += 1
236
+ prompt_id = f"prompt_{self._prompt_id_counter}"
237
+
238
+ # Create event for this prompt
239
+ self._prompt_events[prompt_id] = threading.Event()
240
+
241
+ # Emit the human input request message
242
+ message = UIMessage(
243
+ type=MessageType.HUMAN_INPUT_REQUEST,
244
+ content=prompt_text,
245
+ metadata={"prompt_id": prompt_id},
246
+ )
247
+ self.emit(message)
248
+
249
+ return prompt_id
250
+
251
+ def wait_for_prompt_response(self, prompt_id: str, timeout: float = None) -> str:
252
+ """Wait for a response to a human input request."""
253
+ # If response is already available, return immediately
254
+ if prompt_id in self._prompt_responses:
255
+ self._prompt_events.pop(prompt_id, None)
256
+ return self._prompt_responses.pop(prompt_id)
257
+
258
+ event = self._prompt_events.get(prompt_id)
259
+ if event is None:
260
+ # Fallback: create event if not already present
261
+ event = threading.Event()
262
+ self._prompt_events[prompt_id] = event
263
+
264
+ signaled = event.wait(timeout=timeout)
265
+
266
+ # Clean up the event
267
+ self._prompt_events.pop(prompt_id, None)
268
+
269
+ if not signaled:
270
+ raise TimeoutError(f"No response for prompt {prompt_id} within {timeout}s")
271
+
272
+ return self._prompt_responses.pop(prompt_id)
273
+
274
+ def provide_prompt_response(self, prompt_id: str, response: str):
275
+ """Provide a response to a human input request."""
276
+ self._prompt_responses[prompt_id] = response
277
+ event = self._prompt_events.get(prompt_id)
278
+ if event is not None:
279
+ event.set()
280
+
281
+
282
+ # Global message queue instance
283
+ _global_queue: MessageQueue | None = None
284
+ # FREE-THREADED: _queue_lock guards sync-only singleton creation.
285
+ _queue_lock = threading.Lock()
286
+
287
+
288
+ def get_global_queue() -> MessageQueue:
289
+ """Get or create the global message queue."""
290
+ global _global_queue
291
+
292
+ with _queue_lock:
293
+ if _global_queue is None:
294
+ _global_queue = MessageQueue()
295
+ _global_queue.start()
296
+
297
+ return _global_queue
298
+
299
+
300
+ def get_buffered_startup_messages():
301
+ """Get any messages that were buffered before renderers started."""
302
+ queue = get_global_queue()
303
+ # Only return startup buffer messages, don't clear them yet
304
+ messages = list(queue._startup_buffer)
305
+ return messages
306
+
307
+
308
+ def emit_message(message_type: MessageType, content: Any, **metadata):
309
+ """Convenience function to emit a message to the global queue."""
310
+ queue = get_global_queue()
311
+ queue.emit_simple(message_type, content, **metadata)
312
+
313
+
314
+ def emit_info(content: Any, **metadata):
315
+ """Emit an info message."""
316
+ emit_message(MessageType.INFO, content, **metadata)
317
+
318
+
319
+ def emit_success(content: Any, **metadata):
320
+ """Emit a success message."""
321
+ emit_message(MessageType.SUCCESS, content, **metadata)
322
+
323
+
324
+ def emit_warning(content: Any, **metadata):
325
+ """Emit a warning message."""
326
+ emit_message(MessageType.WARNING, content, **metadata)
327
+
328
+
329
+ def emit_error(content: Any, **metadata):
330
+ """Emit an error message."""
331
+ emit_message(MessageType.ERROR, content, **metadata)
332
+
333
+
334
+ def emit_tool_output(content: Any, tool_name: str = None, **metadata):
335
+ """Emit tool output."""
336
+ if tool_name:
337
+ metadata["tool_name"] = tool_name
338
+ emit_message(MessageType.TOOL_OUTPUT, content, **metadata)
339
+
340
+
341
+ def emit_command_output(content: Any, command: str = None, **metadata):
342
+ """Emit command output."""
343
+ if command:
344
+ metadata["command"] = command
345
+ emit_message(MessageType.COMMAND_OUTPUT, content, **metadata)
346
+
347
+
348
+ def emit_agent_reasoning(content: Any, **metadata):
349
+ """Emit agent reasoning."""
350
+ emit_message(MessageType.AGENT_REASONING, content, **metadata)
351
+
352
+
353
+ def emit_planned_next_steps(content: Any, **metadata):
354
+ """Emit planned_next_steps"""
355
+ emit_message(MessageType.PLANNED_NEXT_STEPS, content, **metadata)
356
+
357
+
358
+ def emit_agent_response(content: Any, **metadata):
359
+ """Emit agent_response"""
360
+ emit_message(MessageType.AGENT_RESPONSE, content, **metadata)
361
+
362
+
363
+ def emit_system_message(content: Any, **metadata):
364
+ """Emit a system message."""
365
+ emit_message(MessageType.SYSTEM, content, **metadata)
366
+
367
+
368
+ def emit_divider(content: str = "─" * 100 + "\n", **metadata):
369
+ """Emit a divider line"""
370
+ # TUI mode has been removed, always emit dividers
371
+ emit_message(MessageType.DIVIDER, content, **metadata)
372
+
373
+
374
+ def emit_prompt(prompt_text: str, timeout: float = None) -> str:
375
+ """Emit a human input request and wait for response.
376
+
377
+ Uses safe_input for cross-platform compatibility, especially on Windows
378
+ where raw input() can fail after prompt_toolkit Applications.
379
+
380
+ The drain() inside safe_input ensures the prompt_text we just enqueued
381
+ actually renders before stdin is read -- otherwise input() would race
382
+ ahead and the user would see a bare prompt with no question above it.
383
+ """
384
+ from code_muse.command_line.utils import safe_input
385
+ from code_muse.messaging import emit_info
386
+
387
+ emit_info(prompt_text)
388
+
389
+ # Use safe_input which resets Windows console state before reading
390
+ response = safe_input(">>> ")
391
+ return response
392
+
393
+
394
+ def provide_prompt_response(prompt_id: str, response: str):
395
+ """Provide a response to a human input request."""
396
+ queue = get_global_queue()
397
+ queue.provide_prompt_response(prompt_id, response)