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,397 @@
1
+ """Helpers for parsing file attachments from interactive prompts."""
2
+
3
+ import mimetypes
4
+ import os
5
+ import shlex
6
+ from collections.abc import Iterable, Sequence
7
+ from dataclasses import dataclass
8
+ from pathlib import Path
9
+
10
+ from pydantic_ai import BinaryContent, DocumentUrl, ImageUrl
11
+
12
+ SUPPORTED_INLINE_SCHEMES = {"http", "https"}
13
+
14
+ # Maximum path length to consider - conservative limit to avoid OS errors
15
+ # Most OS have limits around 4096, but we set lower to catch garbage early
16
+ MAX_PATH_LENGTH = 1024
17
+
18
+ # Allow common extensions people drag in the terminal.
19
+ DEFAULT_ACCEPTED_IMAGE_EXTENSIONS = {
20
+ ".png",
21
+ ".jpg",
22
+ ".jpeg",
23
+ ".gif",
24
+ ".bmp",
25
+ ".webp",
26
+ ".tiff",
27
+ }
28
+ DEFAULT_ACCEPTED_DOCUMENT_EXTENSIONS = set()
29
+
30
+
31
+ @dataclass
32
+ class PromptAttachment:
33
+ """Represents a binary attachment parsed from the input prompt."""
34
+
35
+ placeholder: str
36
+ content: BinaryContent
37
+
38
+
39
+ @dataclass
40
+ class PromptLinkAttachment:
41
+ """Represents a URL attachment supported by pydantic-ai."""
42
+
43
+ placeholder: str
44
+ url_part: ImageUrl | DocumentUrl
45
+
46
+
47
+ @dataclass
48
+ class ProcessedPrompt:
49
+ """Container for parsed input prompt and attachments."""
50
+
51
+ prompt: str
52
+ attachments: list[PromptAttachment]
53
+ link_attachments: list[PromptLinkAttachment]
54
+ warnings: list[str]
55
+
56
+
57
+ class AttachmentParsingError(RuntimeError):
58
+ """Raised when we fail to load a user-provided attachment."""
59
+
60
+
61
+ def _is_probable_path(token: str) -> bool:
62
+ """Heuristically determine whether a token is a local filesystem path."""
63
+
64
+ if not token:
65
+ return False
66
+ # Reject absurdly long tokens before any processing to avoid OS errors
67
+ if len(token) > MAX_PATH_LENGTH:
68
+ return False
69
+ if token.startswith("#"):
70
+ return False
71
+ # Windows drive letters or Unix absolute/relative paths
72
+ if token.startswith(("/", "~", "./", "../")):
73
+ return True
74
+ if len(token) >= 2 and token[1] == ":":
75
+ return True
76
+ # Things like `path/to/file.png`
77
+ return os.sep in token or '"' in token
78
+
79
+
80
+ def _unescape_dragged_path(token: str) -> str:
81
+ """Convert backslash-escaped spaces used by drag-and-drop to literal spaces."""
82
+ # Shell/terminal escaping typically produces '\ ' sequences
83
+ return token.replace(r"\ ", " ")
84
+
85
+
86
+ def _normalise_path(token: str) -> Path:
87
+ """Expand user shortcuts and resolve relative components without touching fs."""
88
+ # First unescape any drag-and-drop backslash spaces before other expansions
89
+ unescaped = _unescape_dragged_path(token)
90
+ try:
91
+ expanded = Path(unescaped).expanduser()
92
+ except (RuntimeError, OSError) as exc:
93
+ raise AttachmentParsingError(f"Invalid path '{token}': {exc}") from exc
94
+ try:
95
+ # This will not resolve against symlinks because we do not call resolve()
96
+ return expanded.absolute()
97
+ except Exception as exc:
98
+ raise AttachmentParsingError(f"Invalid path '{token}': {exc}") from exc
99
+
100
+
101
+ def _determine_media_type(path: Path) -> str:
102
+ """Best-effort media type detection for images only."""
103
+
104
+ mime, _ = mimetypes.guess_type(path.name)
105
+ if mime:
106
+ return mime
107
+ if path.suffix.lower() in DEFAULT_ACCEPTED_IMAGE_EXTENSIONS:
108
+ return "image/png"
109
+ return "application/octet-stream"
110
+
111
+
112
+ def _load_binary(path: Path) -> bytes:
113
+ try:
114
+ return path.read_bytes()
115
+ except FileNotFoundError as exc:
116
+ raise AttachmentParsingError(f"Attachment not found: {path}") from exc
117
+ except PermissionError as exc:
118
+ raise AttachmentParsingError(
119
+ f"Cannot read attachment (permission denied): {path}"
120
+ ) from exc
121
+ except OSError as exc:
122
+ raise AttachmentParsingError(
123
+ f"Failed to read attachment {path}: {exc}"
124
+ ) from exc
125
+
126
+
127
+ def _tokenise(prompt: str) -> Iterable[str]:
128
+ """Split the prompt preserving quoted segments using shell-like semantics."""
129
+
130
+ if not prompt:
131
+ return []
132
+ try:
133
+ # On Windows, avoid POSIX escaping so backslashes are preserved
134
+ posix_mode = os.name != "nt"
135
+ return shlex.split(prompt, posix=posix_mode)
136
+ except ValueError:
137
+ # Fallback naive split when shlex fails (e.g. unmatched quotes)
138
+ return prompt.split()
139
+
140
+
141
+ def _strip_attachment_token(token: str) -> str:
142
+ """Trim surrounding whitespace/punctuation terminals tack onto paths."""
143
+
144
+ return token.strip().strip(",;:()[]{}")
145
+
146
+
147
+ def _candidate_paths(
148
+ tokens: Sequence[str],
149
+ start: int,
150
+ max_span: int = 5,
151
+ ) -> Iterable[tuple[str, int]]:
152
+ """Yield space-joined token slices to reconstruct paths with spaces."""
153
+
154
+ collected: list[str] = []
155
+ for offset, raw in enumerate(tokens[start : start + max_span]):
156
+ collected.append(raw)
157
+ yield " ".join(collected), start + offset + 1
158
+
159
+
160
+ def _is_supported_extension(path: Path) -> bool:
161
+ suffix = path.suffix.lower()
162
+ return (
163
+ suffix
164
+ in DEFAULT_ACCEPTED_IMAGE_EXTENSIONS | DEFAULT_ACCEPTED_DOCUMENT_EXTENSIONS
165
+ )
166
+
167
+
168
+ def _parse_link(token: str) -> PromptLinkAttachment | None:
169
+ """URL parsing disabled: no URLs are treated as attachments."""
170
+ return None
171
+
172
+
173
+ @dataclass
174
+ class _DetectedPath:
175
+ placeholder: str
176
+ path: Path | None
177
+ start_index: int
178
+ consumed_until: int
179
+ unsupported: bool = False
180
+ link: PromptLinkAttachment | None = None
181
+
182
+ def has_path(self) -> bool:
183
+ return self.path is not None and not self.unsupported
184
+
185
+
186
+ def _detect_path_tokens(prompt: str) -> tuple[list[_DetectedPath], list[str]]:
187
+ # Preserve backslash-spaces from drag-and-drop before shlex tokenization
188
+ # Replace '\ ' with a marker that shlex won't split, then restore later
189
+ ESCAPE_MARKER = "\u0000ESCAPED_SPACE\u0000"
190
+ masked_prompt = prompt.replace(r"\ ", ESCAPE_MARKER)
191
+ tokens = list(_tokenise(masked_prompt))
192
+ # Restore escaped spaces in individual tokens
193
+ tokens = [t.replace(ESCAPE_MARKER, " ") for t in tokens]
194
+
195
+ detections: list[_DetectedPath] = []
196
+ warnings: list[str] = []
197
+
198
+ index = 0
199
+ while index < len(tokens):
200
+ token = tokens[index]
201
+
202
+ link_attachment = _parse_link(token)
203
+ if link_attachment:
204
+ detections.append(
205
+ _DetectedPath(
206
+ placeholder=token,
207
+ path=None,
208
+ start_index=index,
209
+ consumed_until=index + 1,
210
+ link=link_attachment,
211
+ )
212
+ )
213
+ index += 1
214
+ continue
215
+
216
+ stripped_token = _strip_attachment_token(token)
217
+ if not _is_probable_path(stripped_token):
218
+ index += 1
219
+ continue
220
+
221
+ # Additional guard: skip if stripped token exceeds reasonable path length
222
+ if len(stripped_token) > MAX_PATH_LENGTH:
223
+ index += 1
224
+ continue
225
+
226
+ start_index = index
227
+ consumed_until = index + 1
228
+ candidate_path_token = stripped_token
229
+ # For placeholder: try to reconstruct escaped representation; if none, use raw token
230
+ original_tokens_for_slice = list(_tokenise(masked_prompt))[index:consumed_until]
231
+ candidate_placeholder = "".join(
232
+ ot.replace(ESCAPE_MARKER, r"\ ") if ESCAPE_MARKER in ot else ot
233
+ for ot in original_tokens_for_slice
234
+ )
235
+ # If placeholder seems identical to raw token, just use the raw token
236
+ if candidate_placeholder == token.replace(" ", r"\ "):
237
+ candidate_placeholder = token
238
+
239
+ try:
240
+ path = _normalise_path(candidate_path_token)
241
+ except AttachmentParsingError:
242
+ # tilde-expansion failures (e.g. Elixir HEEx sigils in diffs)
243
+ # are not actionable file-path errors — skip silently.
244
+ index = consumed_until
245
+ continue
246
+
247
+ # Guard filesystem operations against OS errors (ENAMETOOLONG, etc.)
248
+ try:
249
+ path_exists = path.exists()
250
+ path_is_file = path.is_file() if path_exists else False
251
+ except OSError:
252
+ # Skip this token if filesystem check fails (path too long, etc.)
253
+ index = consumed_until
254
+ continue
255
+
256
+ if not path_exists or not path_is_file:
257
+ found_span = False
258
+ last_path = path
259
+ for joined, end_index in _candidate_paths(tokens, index):
260
+ stripped_joined = _strip_attachment_token(joined)
261
+ if not _is_probable_path(stripped_joined):
262
+ continue
263
+ candidate_path_token = stripped_joined
264
+ candidate_placeholder = joined
265
+ consumed_until = end_index
266
+ if len(candidate_path_token) > MAX_PATH_LENGTH:
267
+ continue
268
+ try:
269
+ last_path = _normalise_path(candidate_path_token)
270
+ except AttachmentParsingError:
271
+ # Suppress warnings for non-file spans; just skip quietly
272
+ found_span = False
273
+ break
274
+ try:
275
+ if last_path.exists() and last_path.is_file():
276
+ path = last_path
277
+ found_span = True
278
+ # We'll rebuild escaped placeholder after this block
279
+ break
280
+ except OSError:
281
+ continue
282
+ if not found_span:
283
+ # Quietly skip tokens that are not files
284
+ index += 1
285
+ continue
286
+ # Reconstruct escaped placeholder for multi-token paths
287
+ original_tokens_for_path = tokens[index:consumed_until]
288
+ escaped_placeholder = " ".join(original_tokens_for_path).replace(" ", r"\ ")
289
+ candidate_placeholder = escaped_placeholder
290
+ if not _is_supported_extension(path):
291
+ detections.append(
292
+ _DetectedPath(
293
+ placeholder=candidate_placeholder,
294
+ path=path,
295
+ start_index=start_index,
296
+ consumed_until=consumed_until,
297
+ unsupported=True,
298
+ )
299
+ )
300
+ index = consumed_until
301
+ continue
302
+
303
+ # Reconstruct escaped placeholder for exact replacement later
304
+ # For unquoted spaces, keep the original literal token from the prompt
305
+ # so replacement matches precisely
306
+ escaped_placeholder = candidate_placeholder
307
+
308
+ detections.append(
309
+ _DetectedPath(
310
+ placeholder=candidate_placeholder,
311
+ path=path,
312
+ start_index=start_index,
313
+ consumed_until=consumed_until,
314
+ )
315
+ )
316
+ index = consumed_until
317
+
318
+ return detections, warnings
319
+
320
+
321
+ def parse_prompt_attachments(prompt: str) -> ProcessedPrompt:
322
+ """Extract attachments from the prompt returning cleaned text and metadata."""
323
+
324
+ attachments: list[PromptAttachment] = []
325
+
326
+ detections, detection_warnings = _detect_path_tokens(prompt)
327
+ warnings: list[str] = list(detection_warnings)
328
+
329
+ link_attachments = [d.link for d in detections if d.link is not None]
330
+
331
+ for detection in detections:
332
+ if detection.link is not None and detection.path is None:
333
+ continue
334
+ if detection.path is None:
335
+ continue
336
+ if detection.unsupported:
337
+ # Skip unsupported attachments without warning noise
338
+ continue
339
+
340
+ try:
341
+ media_type = _determine_media_type(detection.path)
342
+ data = _load_binary(detection.path)
343
+ except AttachmentParsingError:
344
+ # Silently ignore unreadable attachments to reduce prompt noise
345
+ continue
346
+ attachments.append(
347
+ PromptAttachment(
348
+ placeholder=detection.placeholder,
349
+ content=BinaryContent(data=data, media_type=media_type),
350
+ )
351
+ )
352
+
353
+ # Rebuild cleaned_prompt by skipping tokens consumed as file paths.
354
+ # This preserves original punctuation and spacing for non-attachment tokens.
355
+ ESCAPE_MARKER = "\u0000ESCAPED_SPACE\u0000"
356
+ masked = prompt.replace(r"\ ", ESCAPE_MARKER)
357
+ tokens = list(_tokenise(masked))
358
+
359
+ # Build exact token spans for file attachments (supported or unsupported)
360
+ # Skip spans for: supported files (path present and not unsupported) and links.
361
+ spans = [
362
+ (d.start_index, d.consumed_until)
363
+ for d in detections
364
+ if (d.path is not None and not d.unsupported)
365
+ or (d.link is not None and d.path is None)
366
+ ]
367
+ cleaned_parts: list[str] = []
368
+ i = 0
369
+ while i < len(tokens):
370
+ span = next((s for s in spans if s[0] <= i < s[1]), None)
371
+ if span is not None:
372
+ i = span[1]
373
+ continue
374
+ cleaned_parts.append(tokens[i].replace(ESCAPE_MARKER, " "))
375
+ i += 1
376
+
377
+ cleaned_prompt = " ".join(cleaned_parts).strip()
378
+ cleaned_prompt = " ".join(cleaned_prompt.split())
379
+
380
+ if cleaned_prompt == "" and attachments:
381
+ cleaned_prompt = "Describe the attached files in detail."
382
+
383
+ return ProcessedPrompt(
384
+ prompt=cleaned_prompt,
385
+ attachments=attachments,
386
+ link_attachments=link_attachments,
387
+ warnings=warnings,
388
+ )
389
+
390
+
391
+ __all__ = [
392
+ "ProcessedPrompt",
393
+ "PromptAttachment",
394
+ "PromptLinkAttachment",
395
+ "AttachmentParsingError",
396
+ "parse_prompt_attachments",
397
+ ]