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,136 @@
1
+ """Pydantic models for Universal Constructor tools and responses.
2
+
3
+ This module defines the data structures used throughout the UC plugin
4
+ for representing tool metadata, tool information, and operation responses.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from pydantic import BaseModel, Field
10
+
11
+
12
+ class ToolMeta(BaseModel):
13
+ """Metadata for a UC tool.
14
+
15
+ This is the structure expected in the TOOL_META dictionary
16
+ at the top of each tool file.
17
+ """
18
+
19
+ name: str = Field(..., description="Human-readable tool name")
20
+ namespace: str = Field(
21
+ default="", description="Namespace for the tool (from subdirectory path)"
22
+ )
23
+ description: str = Field(..., description="What the tool does")
24
+ enabled: bool = Field(default=True, description="Whether the tool is active")
25
+ version: str = Field(default="1.0.0", description="Semantic version of the tool")
26
+ author: str = Field(default="", description="Tool author or creator")
27
+ created_at: str | None = Field(
28
+ default=None, description="When the tool was created (ISO format string)"
29
+ )
30
+
31
+ model_config = {"extra": "allow"} # Allow additional metadata fields
32
+
33
+
34
+ class UCToolInfo(BaseModel):
35
+ """Full information about a UC tool.
36
+
37
+ Combines metadata with runtime information like function signature
38
+ and source file location.
39
+ """
40
+
41
+ meta: ToolMeta = Field(..., description="Tool metadata")
42
+ signature: str = Field(..., description="Function signature string")
43
+ source_path: str = Field(..., description="Path to the tool source file")
44
+ function_name: str = Field(default="", description="Name of the callable function")
45
+ docstring: str | None = Field(default=None, description="Function docstring")
46
+
47
+ model_config = {"arbitrary_types_allowed": True}
48
+
49
+ @property
50
+ def full_name(self) -> str:
51
+ """Get the fully qualified tool name including namespace."""
52
+ if self.meta.namespace:
53
+ return f"{self.meta.namespace}.{self.meta.name}"
54
+ return self.meta.name
55
+
56
+
57
+ # Response models for UC operations
58
+
59
+
60
+ class UCListOutput(BaseModel):
61
+ """Response model for listing UC tools."""
62
+
63
+ tools: list[UCToolInfo] = Field(
64
+ default_factory=list, description="List of available tools"
65
+ )
66
+ total_count: int = Field(default=0, description="Total number of tools")
67
+ enabled_count: int = Field(default=0, description="Number of enabled tools")
68
+ error: str | None = Field(default=None, description="Error message if any")
69
+
70
+ model_config = {"arbitrary_types_allowed": True}
71
+
72
+
73
+ class UCCallOutput(BaseModel):
74
+ """Response model for calling a UC tool."""
75
+
76
+ success: bool = Field(..., description="Whether the call succeeded")
77
+ tool_name: str = Field(..., description="Name of the tool that was called")
78
+ result: Any = Field(default=None, description="Return value from the tool")
79
+ error: str | None = Field(default=None, description="Error message if failed")
80
+ execution_time: float | None = Field(
81
+ default=None, description="Execution time in seconds"
82
+ )
83
+ source_preview: str | None = Field(
84
+ default=None, description="Preview of the tool's source code that was executed"
85
+ )
86
+
87
+
88
+ class UCCreateOutput(BaseModel):
89
+ """Response model for creating a UC tool."""
90
+
91
+ success: bool = Field(..., description="Whether creation succeeded")
92
+ tool_name: str = Field(default="", description="Name of the created tool")
93
+ source_path: str | None = Field(
94
+ default=None, description="Path where tool was saved"
95
+ )
96
+ preview: str | None = Field(
97
+ default=None, description="Preview of the first 10 lines of source code"
98
+ )
99
+ error: str | None = Field(default=None, description="Error message if failed")
100
+ validation_warnings: list[str] = Field(
101
+ default_factory=list, description="Non-fatal validation warnings"
102
+ )
103
+
104
+ model_config = {"arbitrary_types_allowed": True}
105
+
106
+
107
+ class UCUpdateOutput(BaseModel):
108
+ """Response model for updating a UC tool."""
109
+
110
+ success: bool = Field(..., description="Whether update succeeded")
111
+ tool_name: str = Field(default="", description="Name of the updated tool")
112
+ source_path: str | None = Field(
113
+ default=None, description="Path to the updated tool"
114
+ )
115
+ preview: str | None = Field(
116
+ default=None, description="Preview of the first 10 lines of updated source code"
117
+ )
118
+ error: str | None = Field(default=None, description="Error message if failed")
119
+ changes_applied: list[str] = Field(
120
+ default_factory=list, description="List of changes that were applied"
121
+ )
122
+
123
+ model_config = {"arbitrary_types_allowed": True}
124
+
125
+
126
+ class UCInfoOutput(BaseModel):
127
+ """Response model for getting info about a specific UC tool."""
128
+
129
+ success: bool = Field(..., description="Whether lookup succeeded")
130
+ tool: UCToolInfo | None = Field(
131
+ default=None, description="Tool information if found"
132
+ )
133
+ source_code: str | None = Field(default=None, description="Source code of the tool")
134
+ error: str | None = Field(default=None, description="Error message if failed")
135
+
136
+ model_config = {"arbitrary_types_allowed": True}
@@ -0,0 +1,47 @@
1
+ """Callback registration for the Universal Constructor plugin.
2
+
3
+ This module registers callbacks to integrate UC with the rest of
4
+ Muse. It ensures the plugin is properly loaded and initialized.
5
+ """
6
+
7
+ import logging
8
+
9
+ from code_muse.callbacks import register_callback
10
+
11
+ from . import USER_UC_DIR
12
+ from .registry import get_registry
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ def _on_startup() -> None:
18
+ """Initialize UC plugin on application startup."""
19
+ from code_muse.config import get_universal_constructor_enabled
20
+
21
+ # Skip initialization if UC is disabled
22
+ if not get_universal_constructor_enabled():
23
+ logger.debug("Universal Constructor is disabled, skipping initialization")
24
+ return
25
+
26
+ logger.debug("Universal Constructor plugin initializing...")
27
+
28
+ # Ensure the user tools directory exists
29
+ USER_UC_DIR.mkdir(parents=True, exist_ok=True)
30
+
31
+ # Do an initial scan of tools (lazy - will happen on first access)
32
+ registry = get_registry()
33
+ logger.debug(f"UC registry initialized, tools dir: {registry._tools_dir}")
34
+
35
+ # Log plugin info at startup
36
+ tools = registry.list_tools(include_disabled=True)
37
+ enabled = [t for t in tools if t.meta.enabled]
38
+ logger.debug(
39
+ f"UC plugin loaded: {len(enabled)}/{len(tools)} tools enabled "
40
+ f"from {USER_UC_DIR}"
41
+ )
42
+
43
+
44
+ # Register startup callback
45
+ register_callback("startup", _on_startup)
46
+
47
+ logger.debug("Universal Constructor plugin callbacks registered")
@@ -0,0 +1,390 @@
1
+ """UC Tool Registry - discovers and manages user-created tools.
2
+
3
+ This module provides the core registry that scans the user's UC directory,
4
+ loads tool metadata, extracts function signatures, and provides access
5
+ to enabled tools for the LLM.
6
+
7
+ Hardened to parse TOOL_META via AST before importing, and to skip
8
+ disabled or untrusted tools during scan.
9
+ """
10
+
11
+ import ast
12
+ import importlib.util
13
+ import inspect
14
+ import logging
15
+ import sys
16
+ from collections.abc import Callable
17
+ from datetime import datetime
18
+ from pathlib import Path
19
+ from types import ModuleType
20
+
21
+ from . import USER_UC_DIR
22
+ from .models import ToolMeta, UCToolInfo
23
+ from .safety import (
24
+ UCApprovalStore,
25
+ check_code_safety,
26
+ is_path_within_uc_dir,
27
+ validate_full_tool_name,
28
+ )
29
+
30
+ logger = logging.getLogger(__name__)
31
+
32
+
33
+ class UCRegistry:
34
+ """Registry for discovering and managing UC tools.
35
+
36
+ Scans the user's UC directory recursively, loading tool metadata
37
+ and providing access to enabled tools. Supports namespacing via
38
+ subdirectories (e.g., api/weather.py → "api.weather").
39
+ """
40
+
41
+ def __init__(self, tools_dir: Path | None = None):
42
+ """Initialize the registry.
43
+
44
+ Args:
45
+ tools_dir: Directory to scan for tools. Defaults to USER_UC_DIR.
46
+ """
47
+ self._tools_dir = tools_dir or USER_UC_DIR
48
+ self._tools: dict[str, UCToolInfo] = {}
49
+ self._modules: dict[str, ModuleType] = {}
50
+ self._last_scan: datetime | None = None
51
+
52
+ def ensure_tools_dir(self) -> Path:
53
+ """Ensure the tools directory exists.
54
+
55
+ Returns:
56
+ Path to the tools directory.
57
+ """
58
+ self._tools_dir.mkdir(parents=True, exist_ok=True)
59
+ return self._tools_dir
60
+
61
+ def scan(self) -> int:
62
+ """Scan the tools directory and load all tools.
63
+
64
+ Returns:
65
+ Number of tools found.
66
+ """
67
+ self._tools.clear()
68
+ self._modules.clear()
69
+
70
+ if not self._tools_dir.exists():
71
+ logger.debug(f"Tools directory does not exist: {self._tools_dir}")
72
+ return 0
73
+
74
+ # Find all Python files recursively
75
+ tool_files = list(self._tools_dir.rglob("*.py"))
76
+
77
+ for tool_file in tool_files:
78
+ # Skip __init__.py and hidden files
79
+ if tool_file.name.startswith("_") or tool_file.name.startswith("."):
80
+ continue
81
+
82
+ try:
83
+ tool_info = self._load_tool_file(tool_file)
84
+ if tool_info:
85
+ self._tools[tool_info.full_name] = tool_info
86
+ logger.debug(f"Loaded tool: {tool_info.full_name}")
87
+ except Exception as e:
88
+ logger.warning(f"Failed to load tool from {tool_file}: {e}")
89
+
90
+ self._last_scan = datetime.now()
91
+ logger.info(f"Scanned {len(self._tools)} tools from {self._tools_dir}")
92
+ return len(self._tools)
93
+
94
+ def _load_tool_file(self, file_path: Path) -> UCToolInfo | None:
95
+ """Load a tool from a Python file.
96
+
97
+ Hardened flow:
98
+ 1. Parse TOOL_META via AST before importing the module.
99
+ 2. Validate tool name for path traversal / reserved names.
100
+ 3. Skip disabled tools (no import needed).
101
+ 4. For enabled tools with dangerous code, require approval.
102
+ 5. Only import if the tool passes safety and trust checks.
103
+
104
+ Args:
105
+ file_path: Path to the Python file.
106
+
107
+ Returns:
108
+ UCToolInfo if valid tool, None otherwise.
109
+ """
110
+ # Safety: file must be within tools directory
111
+ if not is_path_within_uc_dir(file_path, self._tools_dir):
112
+ logger.warning(f"Tool file outside UC directory: {file_path}")
113
+ return None
114
+
115
+ # Calculate namespace from relative path
116
+ try:
117
+ rel_path = file_path.relative_to(self._tools_dir)
118
+ namespace_parts = list(rel_path.parent.parts)
119
+ namespace = ".".join(namespace_parts) if namespace_parts else ""
120
+ except ValueError:
121
+ namespace = ""
122
+
123
+ # Step 1: Parse TOOL_META via AST without importing
124
+ try:
125
+ code = file_path.read_text(encoding="utf-8")
126
+ tree = ast.parse(code)
127
+ except (SyntaxError, OSError) as e:
128
+ logger.warning(f"Cannot parse {file_path}: {e}")
129
+ return None
130
+
131
+ raw_meta = self._extract_tool_meta_from_ast(tree)
132
+ if raw_meta is None:
133
+ logger.debug(f"No TOOL_META found in {file_path}")
134
+ return None
135
+ if not isinstance(raw_meta, dict):
136
+ logger.warning(f"TOOL_META is not a dict in {file_path}")
137
+ return None
138
+
139
+ # Set namespace from directory structure
140
+ raw_meta["namespace"] = namespace
141
+
142
+ # Parse metadata
143
+ try:
144
+ meta = ToolMeta(**raw_meta)
145
+ except Exception as e:
146
+ logger.warning(f"Invalid TOOL_META in {file_path}: {e}")
147
+ return None
148
+
149
+ # Validate tool name
150
+ full_name = f"{namespace}.{meta.name}" if namespace else meta.name
151
+ name_error = validate_full_tool_name(full_name)
152
+ if name_error:
153
+ logger.warning(f"Invalid tool name '{full_name}': {name_error}")
154
+ return None
155
+
156
+ # Step 2: Skip disabled tools without importing
157
+ if not meta.enabled:
158
+ return UCToolInfo(
159
+ meta=meta,
160
+ signature=f"{meta.name}(...)",
161
+ source_path=str(file_path),
162
+ function_name=meta.name,
163
+ docstring=None,
164
+ )
165
+
166
+ # Step 3: Safety check for enabled tools
167
+ safety = check_code_safety(code)
168
+ if safety.blocked:
169
+ logger.warning(
170
+ f"Tool '{full_name}' blocked by safety check: {safety.errors}"
171
+ )
172
+ return UCToolInfo(
173
+ meta=meta,
174
+ signature=f"{meta.name}(...)",
175
+ source_path=str(file_path),
176
+ function_name=meta.name,
177
+ docstring=None,
178
+ )
179
+
180
+ if safety.requires_approval:
181
+ approval_store = UCApprovalStore()
182
+ if not approval_store.is_approved(full_name, safety.code_hash):
183
+ logger.warning(
184
+ f"Tool '{full_name}' requires approval (dangerous patterns). "
185
+ f"Run /approve-uc {full_name} to enable."
186
+ )
187
+ return UCToolInfo(
188
+ meta=meta,
189
+ signature=f"{meta.name}(...)",
190
+ source_path=str(file_path),
191
+ function_name=meta.name,
192
+ docstring=None,
193
+ )
194
+
195
+ # Step 4: Only import if we passed safety/trust
196
+ module = self._load_module(file_path)
197
+ if module is None:
198
+ return None
199
+
200
+ # Find the callable function
201
+ func, func_name = self._find_tool_function(module, meta.name)
202
+ if func is None:
203
+ logger.warning(f"No callable function found in {file_path}")
204
+ return None
205
+
206
+ # Extract signature
207
+ try:
208
+ sig = inspect.signature(func)
209
+ signature_str = f"{func_name}{sig}"
210
+ except ValueError, TypeError:
211
+ signature_str = f"{func_name}(...)"
212
+
213
+ # Extract docstring
214
+ docstring = inspect.getdoc(func)
215
+
216
+ # Store module reference for later calls
217
+ self._modules[full_name] = module
218
+
219
+ return UCToolInfo(
220
+ meta=meta,
221
+ signature=signature_str,
222
+ source_path=str(file_path),
223
+ function_name=func_name,
224
+ docstring=docstring,
225
+ )
226
+
227
+ @staticmethod
228
+ def _extract_tool_meta_from_ast(tree: ast.AST) -> dict | None:
229
+ """Extract TOOL_META dict from an AST without executing code."""
230
+ for node in ast.walk(tree):
231
+ if isinstance(node, ast.Assign):
232
+ for target in node.targets:
233
+ if isinstance(target, ast.Name) and target.id == "TOOL_META":
234
+ if isinstance(node.value, ast.Dict):
235
+ try:
236
+ meta_str = ast.unparse(node.value)
237
+ return ast.literal_eval(meta_str)
238
+ except ValueError, SyntaxError:
239
+ return None
240
+ return None
241
+
242
+ def _load_module(self, file_path: Path) -> ModuleType | None:
243
+ """Load a Python module from a file path.
244
+
245
+ Args:
246
+ file_path: Path to the Python file.
247
+
248
+ Returns:
249
+ Loaded module or None if failed.
250
+ """
251
+ module_name = f"uc_tool_{file_path.stem}_{hash(str(file_path))}"
252
+
253
+ try:
254
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
255
+ if spec is None or spec.loader is None:
256
+ return None
257
+
258
+ module = importlib.util.module_from_spec(spec)
259
+ sys.modules[module_name] = module
260
+ spec.loader.exec_module(module)
261
+ return module
262
+ except Exception:
263
+ return None
264
+
265
+ def _find_tool_function(
266
+ self, module: ModuleType, tool_name: str
267
+ ) -> tuple[Callable | None, str]:
268
+ """Find the callable function in a tool module.
269
+
270
+ Looks for:
271
+ 1. A function with the same name as the tool
272
+ 2. A function named 'run'
273
+ 3. A function named 'execute'
274
+ 4. Any public function (not starting with _)
275
+
276
+ Args:
277
+ module: The loaded module.
278
+ tool_name: The tool name from metadata.
279
+
280
+ Returns:
281
+ Tuple of (function, function_name) or (None, "") if not found.
282
+ """
283
+ # Priority order for finding the function
284
+ candidates = [tool_name, "run", "execute"]
285
+
286
+ for name in candidates:
287
+ if hasattr(module, name):
288
+ func = getattr(module, name)
289
+ if callable(func) and not isinstance(func, type):
290
+ return func, name
291
+
292
+ # Fall back to first public callable
293
+ for name in dir(module):
294
+ if name.startswith("_"):
295
+ continue
296
+ obj = getattr(module, name)
297
+ if callable(obj) and not isinstance(obj, type):
298
+ return obj, name
299
+
300
+ return None, ""
301
+
302
+ def list_tools(self, include_disabled: bool = False) -> list[UCToolInfo]:
303
+ """List all discovered tools.
304
+
305
+ Args:
306
+ include_disabled: Whether to include disabled tools.
307
+
308
+ Returns:
309
+ List of tool info objects.
310
+ """
311
+ if not self._tools:
312
+ self.scan()
313
+
314
+ tools = list(self._tools.values())
315
+ if not include_disabled:
316
+ tools = [t for t in tools if t.meta.enabled]
317
+
318
+ return sorted(tools, key=lambda t: t.full_name)
319
+
320
+ def get_tool(self, name: str) -> UCToolInfo | None:
321
+ """Get a specific tool by name.
322
+
323
+ Args:
324
+ name: Full tool name (including namespace).
325
+
326
+ Returns:
327
+ Tool info or None if not found.
328
+ """
329
+ if not self._tools:
330
+ self.scan()
331
+
332
+ return self._tools.get(name)
333
+
334
+ def get_tool_function(self, name: str) -> Callable | None:
335
+ """Get the callable function for a tool.
336
+
337
+ Args:
338
+ name: Full tool name (including namespace).
339
+
340
+ Returns:
341
+ Callable function or None if not found.
342
+ """
343
+ tool = self.get_tool(name)
344
+ if tool is None:
345
+ return None
346
+
347
+ module = self._modules.get(name)
348
+ if module is None:
349
+ return None
350
+
351
+ func, _ = self._find_tool_function(module, tool.meta.name)
352
+ return func
353
+
354
+ def load_tool_module(self, name: str) -> ModuleType | None:
355
+ """Get the loaded module for a tool.
356
+
357
+ Args:
358
+ name: Full tool name (including namespace).
359
+
360
+ Returns:
361
+ Module or None if not found.
362
+ """
363
+ if not self._tools:
364
+ self.scan()
365
+
366
+ return self._modules.get(name)
367
+
368
+ def reload(self) -> int:
369
+ """Force a rescan of all tools.
370
+
371
+ Returns:
372
+ Number of tools found.
373
+ """
374
+ return self.scan()
375
+
376
+
377
+ # Global registry instance
378
+ _registry: UCRegistry | None = None
379
+
380
+
381
+ def get_registry() -> UCRegistry:
382
+ """Get the global UC registry instance.
383
+
384
+ Returns:
385
+ The global UCRegistry instance.
386
+ """
387
+ global _registry
388
+ if _registry is None:
389
+ _registry = UCRegistry()
390
+ return _registry