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,203 @@
1
+ # cython: language_level=3
2
+ """ScanCache core — thread-safe LRU cache for filesystem scan results."""
3
+
4
+ import logging
5
+ import threading
6
+ import time
7
+ from collections import OrderedDict
8
+ from collections.abc import Callable
9
+ from dataclasses import dataclass
10
+ from pathlib import Path
11
+
12
+ from code_muse.fs_scan_cache.ttl_policy import is_fresh
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ @dataclass
18
+ class GlobMatch:
19
+ """A single filesystem entry returned by a scan."""
20
+
21
+ path: str
22
+ file_type: str # "file" | "dir" | "symlink"
23
+ mtime: float
24
+ size: int
25
+
26
+
27
+ @dataclass
28
+ class ScanEntry:
29
+ """Internal cached scan result with timestamp."""
30
+
31
+ entries: list[GlobMatch]
32
+ created_at: float
33
+
34
+
35
+ @dataclass
36
+ class CacheStats:
37
+ """Hit/miss/eviction statistics."""
38
+
39
+ hits: int = 0
40
+ misses: int = 0
41
+ evictions: int = 0
42
+ size: int = 0
43
+
44
+
45
+ class ScanCache:
46
+ """Thread-safe LRU cache for filesystem scan results.
47
+
48
+ Keyed by a hashable partition tuple (typically ``(root, hidden, gitignore,
49
+ node_modules)``). Max 16 entries, LRU eviction. TTL-based freshness with
50
+ separate fast-recheck for empty results.
51
+ """
52
+
53
+ def __init__(self, max_entries: int = 16) -> None:
54
+ if max_entries < 1:
55
+ raise ValueError("max_entries must be positive")
56
+ self.max_entries = max_entries
57
+ # FREE-THREADED: Generic scan cache — may be accessed from sync or async code.
58
+ # Keep threading.Lock; migrate to asyncio.Lock only if all callers are async.
59
+ self._lock = threading.Lock()
60
+ self._cache: OrderedDict[tuple, ScanEntry] = OrderedDict()
61
+ self._stats = CacheStats()
62
+
63
+ def get_or_scan(
64
+ self,
65
+ key: tuple,
66
+ scanner_fn: Callable[[], list[GlobMatch]],
67
+ ) -> tuple[list[GlobMatch], float]:
68
+ """Return cached entries if fresh, otherwise call *scanner_fn*.
69
+
70
+ The scanner function is invoked **outside** the lock to avoid holding
71
+ it during I/O. A double-check is performed after re-acquiring the lock.
72
+
73
+ Returns:
74
+ ``(entries, cache_age_ms)`` — *cache_age_ms* is ``0.0`` for a
75
+ fresh insertion, otherwise the monotonic age of the cached entry.
76
+ """
77
+ cdef double now = time.monotonic()
78
+ cdef double age_ms
79
+ cdef double created
80
+ cdef object entry
81
+ cdef list scanned
82
+ cdef int evict_count
83
+ cdef object new_entry
84
+
85
+ with self._lock:
86
+ if key in self._cache:
87
+ entry = self._cache[key]
88
+ if is_fresh(entry, now):
89
+ self._cache.move_to_end(key)
90
+ age_ms = (now - entry.created_at) * 1000.0
91
+ self._stats.hits += 1
92
+ self._stats.size = len(self._cache)
93
+ return (entry.entries, age_ms)
94
+ # Stale — remove now so we don't return stale data later
95
+ del self._cache[key]
96
+
97
+ # Slow path: scan outside the lock
98
+ scanned = scanner_fn()
99
+
100
+ with self._lock:
101
+ # Double-check: another thread may have populated while we scanned
102
+ if key in self._cache:
103
+ entry = self._cache[key]
104
+ if is_fresh(entry, now):
105
+ self._cache.move_to_end(key)
106
+ age_ms = (now - entry.created_at) * 1000.0
107
+ self._stats.hits += 1
108
+ self._stats.size = len(self._cache)
109
+ return (entry.entries, age_ms)
110
+ del self._cache[key]
111
+
112
+ # Evict oldest if at capacity
113
+ evict_count = 0
114
+ while len(self._cache) >= self.max_entries:
115
+ self._cache.popitem(last=False)
116
+ evict_count += 1
117
+ if evict_count:
118
+ self._stats.evictions += evict_count
119
+
120
+ created = time.monotonic()
121
+ new_entry = ScanEntry(entries=scanned, created_at=created)
122
+ self._cache[key] = new_entry
123
+ self._stats.misses += 1
124
+ self._stats.size = len(self._cache)
125
+ return (new_entry.entries, 0.0)
126
+
127
+ def invalidate(self, root: str | None = None) -> None:
128
+ """Remove cache entries affected by *root*.
129
+
130
+ If *root* is ``None``, clear the entire cache. Otherwise remove any
131
+ entry whose cached root is an ancestor of *root* or vice versa.
132
+ """
133
+ cdef list keys_to_remove
134
+ cdef tuple key
135
+ cdef object target
136
+ cdef object cached_root
137
+ cdef bint cached_is_ancestor
138
+ cdef bint target_is_ancestor
139
+
140
+ with self._lock:
141
+ if root is None:
142
+ self._cache.clear()
143
+ self._stats.size = 0
144
+ logger.debug("ScanCache cleared entirely")
145
+ return
146
+
147
+ target = Path(root).resolve()
148
+ keys_to_remove = []
149
+ for key in list(self._cache.keys()):
150
+ cached_root = Path(key[0]).resolve()
151
+ # Ancestor check in both directions
152
+ try:
153
+ cached_is_ancestor = target.is_relative_to(cached_root)
154
+ except AttributeError:
155
+ # Python < 3.12 fallback
156
+ try:
157
+ cached_is_ancestor = (
158
+ target == cached_root or cached_root in target.parents
159
+ )
160
+ except ValueError:
161
+ cached_is_ancestor = False
162
+
163
+ try:
164
+ target_is_ancestor = cached_root.is_relative_to(target)
165
+ except AttributeError:
166
+ try:
167
+ target_is_ancestor = (
168
+ cached_root == target or target in cached_root.parents
169
+ )
170
+ except ValueError:
171
+ target_is_ancestor = False
172
+
173
+ if cached_is_ancestor or target_is_ancestor:
174
+ keys_to_remove.append(key)
175
+
176
+ for key in keys_to_remove:
177
+ del self._cache[key]
178
+ logger.debug(f"ScanCache invalidated key {key}")
179
+
180
+ self._stats.size = len(self._cache)
181
+
182
+ def invalidate_for_path(self, path: str) -> None:
183
+ """Invalidate cache entries related to *path*.
184
+
185
+ Convenience wrapper around :meth:`invalidate` that accepts a file
186
+ or directory path directly.
187
+ """
188
+ self.invalidate(path)
189
+
190
+ def clear(self) -> None:
191
+ """Remove all entries."""
192
+ self.invalidate(None)
193
+
194
+ @property
195
+ def stats(self) -> CacheStats:
196
+ """Return a snapshot of cache statistics."""
197
+ with self._lock:
198
+ return CacheStats(
199
+ hits=self._stats.hits,
200
+ misses=self._stats.misses,
201
+ evictions=self._stats.evictions,
202
+ size=self._stats.size,
203
+ )
@@ -0,0 +1,309 @@
1
+ """Cached wrappers around glob, grep, and find operations."""
2
+
3
+ import fnmatch
4
+ import os
5
+ import re
6
+ from pathlib import Path
7
+
8
+ from code_muse.fs_scan_cache.scan_cache_core import GlobMatch, ScanCache
9
+
10
+
11
+ def _resolve_root(root: str) -> Path:
12
+ return Path(root).expanduser().resolve()
13
+
14
+
15
+ def _is_hidden(path: Path) -> bool:
16
+ """Return True if any component of *path* starts with '.'."""
17
+ return any(
18
+ part.startswith(".") for part in path.parts if part not in (".", "..", os.sep)
19
+ )
20
+
21
+
22
+ def _should_skip(
23
+ path: Path,
24
+ *,
25
+ include_hidden: bool,
26
+ use_gitignore: bool,
27
+ skip_node_modules: bool,
28
+ ) -> bool:
29
+ """Return True if *path* should be excluded from scan results."""
30
+ if not include_hidden and _is_hidden(path):
31
+ return True
32
+ if skip_node_modules and "node_modules" in path.parts:
33
+ return True
34
+ if use_gitignore:
35
+ # Lightweight approximation: skip `.git` directory
36
+ if ".git" in path.parts:
37
+ return True
38
+ return False
39
+
40
+
41
+ def _stat_entry(p: Path) -> tuple[str, float, int]:
42
+ """Return (file_type, mtime, size) for *p*, falling back gracefully."""
43
+ try:
44
+ st = p.stat(follow_symlinks=False)
45
+ if p.is_symlink():
46
+ return "symlink", st.st_mtime, 0
47
+ if p.is_dir():
48
+ return "dir", st.st_mtime, 0
49
+ return "file", st.st_mtime, st.st_size
50
+ except OSError, ValueError:
51
+ return "file", 0.0, 0
52
+
53
+
54
+ def _glob_scanner(
55
+ pattern: str,
56
+ root: str,
57
+ *,
58
+ hidden: bool,
59
+ gitignore: bool,
60
+ node_modules: bool,
61
+ ) -> list[GlobMatch]:
62
+ """Perform a filesystem glob and return filtered GlobMatch entries."""
63
+ base = _resolve_root(root)
64
+ results: list[GlobMatch] = []
65
+
66
+ if "**" in pattern:
67
+ # Recursive glob via rglob
68
+ raw_pattern = pattern.replace("**/", "").replace("**", "")
69
+ # If pattern is just '**', match everything
70
+ if raw_pattern in {"", "*"}:
71
+ iterator = base.rglob("*")
72
+ else:
73
+ iterator = base.rglob(raw_pattern)
74
+ else:
75
+ iterator = base.glob(pattern)
76
+
77
+ for p in iterator:
78
+ try:
79
+ relative = p.relative_to(base)
80
+ except ValueError:
81
+ relative = p
82
+ if _should_skip(
83
+ relative,
84
+ include_hidden=hidden,
85
+ use_gitignore=gitignore,
86
+ skip_node_modules=node_modules,
87
+ ):
88
+ continue
89
+ file_type, mtime, size = _stat_entry(p)
90
+ results.append(
91
+ GlobMatch(
92
+ path=str(p),
93
+ file_type=file_type,
94
+ mtime=mtime,
95
+ size=size,
96
+ )
97
+ )
98
+ return results
99
+
100
+
101
+ def _grep_scanner(
102
+ pattern: str,
103
+ root: str,
104
+ *,
105
+ hidden: bool,
106
+ gitignore: bool,
107
+ node_modules: bool,
108
+ ) -> list[GlobMatch]:
109
+ """Recursively search file contents with regex and return matching files."""
110
+ base = _resolve_root(root)
111
+ results: list[GlobMatch] = []
112
+ compiled = re.compile(pattern)
113
+ max_matches = 50
114
+
115
+ for p in base.rglob("*"):
116
+ try:
117
+ relative = p.relative_to(base)
118
+ except ValueError:
119
+ relative = p
120
+ if _should_skip(
121
+ relative,
122
+ include_hidden=hidden,
123
+ use_gitignore=gitignore,
124
+ skip_node_modules=node_modules,
125
+ ):
126
+ continue
127
+ if not p.is_file() or p.is_symlink():
128
+ continue
129
+ try:
130
+ # Skip binary / very large files
131
+ size = p.stat().st_size
132
+ if size > 5 * 1024 * 1024:
133
+ continue
134
+ text = p.read_text(encoding="utf-8", errors="replace")
135
+ except OSError, UnicodeDecodeError:
136
+ continue
137
+ if compiled.search(text):
138
+ file_type, mtime, fsize = _stat_entry(p)
139
+ results.append(
140
+ GlobMatch(
141
+ path=str(p),
142
+ file_type=file_type,
143
+ mtime=mtime,
144
+ size=fsize,
145
+ )
146
+ )
147
+ if len(results) >= max_matches:
148
+ break
149
+ return results
150
+
151
+
152
+ def _find_scanner(
153
+ name: str,
154
+ root: str,
155
+ *,
156
+ hidden: bool,
157
+ gitignore: bool,
158
+ node_modules: bool,
159
+ ) -> list[GlobMatch]:
160
+ """Recursively find files/directories whose basename matches *name*."""
161
+ base = _resolve_root(root)
162
+ results: list[GlobMatch] = []
163
+
164
+ for p in base.rglob("*"):
165
+ try:
166
+ relative = p.relative_to(base)
167
+ except ValueError:
168
+ relative = p
169
+ if _should_skip(
170
+ relative,
171
+ include_hidden=hidden,
172
+ use_gitignore=gitignore,
173
+ skip_node_modules=node_modules,
174
+ ):
175
+ continue
176
+ if not fnmatch.fnmatch(p.name, name):
177
+ continue
178
+ file_type, mtime, size = _stat_entry(p)
179
+ results.append(
180
+ GlobMatch(
181
+ path=str(p),
182
+ file_type=file_type,
183
+ mtime=mtime,
184
+ size=size,
185
+ )
186
+ )
187
+ return results
188
+
189
+
190
+ # Module-level default cache used by the cached_* helpers.
191
+ _default_cache: ScanCache | None = None
192
+
193
+
194
+ def _get_default_cache() -> ScanCache:
195
+ global _default_cache
196
+ if _default_cache is None:
197
+ _default_cache = ScanCache()
198
+ return _default_cache
199
+
200
+
201
+ def cached_glob(
202
+ pattern: str,
203
+ root: str = ".",
204
+ hidden: bool = False,
205
+ gitignore: bool = True,
206
+ node_modules: bool = True,
207
+ cache: bool = False,
208
+ ) -> tuple[list[GlobMatch], float | None]:
209
+ """Glob with optional scan caching.
210
+
211
+ Returns:
212
+ ``(entries, cache_age_ms)`` — *cache_age_ms* is ``None`` when
213
+ *cache* is ``False``.
214
+ """
215
+ if not cache:
216
+ return (
217
+ _glob_scanner(
218
+ pattern,
219
+ root,
220
+ hidden=hidden,
221
+ gitignore=gitignore,
222
+ node_modules=node_modules,
223
+ ),
224
+ None,
225
+ )
226
+
227
+ key = (root, hidden, gitignore, node_modules, pattern)
228
+ sc = _get_default_cache()
229
+ entries, age = sc.get_or_scan(
230
+ key,
231
+ lambda: _glob_scanner(
232
+ pattern, root, hidden=hidden, gitignore=gitignore, node_modules=node_modules
233
+ ),
234
+ )
235
+ return (entries, age)
236
+
237
+
238
+ def cached_grep(
239
+ pattern: str,
240
+ root: str = ".",
241
+ hidden: bool = False,
242
+ gitignore: bool = True,
243
+ node_modules: bool = True,
244
+ cache: bool = False,
245
+ ) -> tuple[list[GlobMatch], float | None]:
246
+ """Grep with optional scan caching.
247
+
248
+ Returns:
249
+ ``(entries, cache_age_ms)`` — *cache_age_ms* is ``None`` when
250
+ *cache* is ``False``.
251
+ """
252
+ if not cache:
253
+ return (
254
+ _grep_scanner(
255
+ pattern,
256
+ root,
257
+ hidden=hidden,
258
+ gitignore=gitignore,
259
+ node_modules=node_modules,
260
+ ),
261
+ None,
262
+ )
263
+
264
+ key = (root, hidden, gitignore, node_modules, pattern)
265
+ sc = _get_default_cache()
266
+ entries, age = sc.get_or_scan(
267
+ key,
268
+ lambda: _grep_scanner(
269
+ pattern, root, hidden=hidden, gitignore=gitignore, node_modules=node_modules
270
+ ),
271
+ )
272
+ return (entries, age)
273
+
274
+
275
+ def cached_find(
276
+ name: str,
277
+ root: str = ".",
278
+ hidden: bool = False,
279
+ gitignore: bool = True,
280
+ node_modules: bool = True,
281
+ cache: bool = False,
282
+ ) -> tuple[list[GlobMatch], float | None]:
283
+ """Filename search with optional scan caching.
284
+
285
+ Returns:
286
+ ``(entries, cache_age_ms)`` — *cache_age_ms* is ``None`` when
287
+ *cache* is ``False``.
288
+ """
289
+ if not cache:
290
+ return (
291
+ _find_scanner(
292
+ name,
293
+ root,
294
+ hidden=hidden,
295
+ gitignore=gitignore,
296
+ node_modules=node_modules,
297
+ ),
298
+ None,
299
+ )
300
+
301
+ key = (root, hidden, gitignore, node_modules, name)
302
+ sc = _get_default_cache()
303
+ entries, age = sc.get_or_scan(
304
+ key,
305
+ lambda: _find_scanner(
306
+ name, root, hidden=hidden, gitignore=gitignore, node_modules=node_modules
307
+ ),
308
+ )
309
+ return (entries, age)
@@ -0,0 +1,44 @@
1
+ """TTL policy for ScanCache entries."""
2
+
3
+ import os
4
+ import typing
5
+
6
+ if typing.TYPE_CHECKING:
7
+ from code_muse.fs_scan_cache.scan_cache_core import ScanEntry
8
+
9
+
10
+ def env_uint(name: str, default: int) -> int:
11
+ """Read an unsigned integer from an environment variable.
12
+
13
+ Returns *default* if the variable is missing, empty, or not a valid
14
+ non-negative integer.
15
+ """
16
+ raw = os.environ.get(name)
17
+ if raw is None:
18
+ return default
19
+ try:
20
+ value = int(raw)
21
+ except ValueError:
22
+ return default
23
+ return value if value >= 0 else default
24
+
25
+
26
+ CACHE_TTL_MS: int = env_uint("FS_SCAN_CACHE_TTL_MS", 1000)
27
+ EMPTY_RECHECK_MS: int = env_uint("FS_SCAN_EMPTY_RECHECK_MS", 200)
28
+
29
+
30
+ def is_fresh(entry: ScanEntry, now: float) -> bool:
31
+ """Return ``True`` if *entry* has not exceeded its TTL.
32
+
33
+ Rules:
34
+ * If ``CACHE_TTL_MS == 0``: always stale (cache bypass).
35
+ * If *entry* has no items: age must be < ``EMPTY_RECHECK_MS``.
36
+ * If *entry* has items: age must be < ``CACHE_TTL_MS``.
37
+ """
38
+ if CACHE_TTL_MS == 0:
39
+ return False
40
+
41
+ age_ms = (now - entry.created_at) * 1000.0
42
+ if not entry.entries:
43
+ return age_ms < EMPTY_RECHECK_MS
44
+ return age_ms < CACHE_TTL_MS