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,162 @@
1
+ """Slide content for the onboarding wizard.
2
+
3
+ Lean, mean, ADHD-friendly slides. 5 slides max!
4
+ """
5
+
6
+
7
+ # ============================================================================
8
+ # Slide Data Constants
9
+ # ============================================================================
10
+
11
+ # Model subscription options
12
+ MODEL_OPTIONS: list[tuple[str, str, str]] = [
13
+ ("chatgpt", "ChatGPT Plus/Pro/Max", "OAuth login - no API key needed"),
14
+ ("claude", "Claude Code Pro/Max", "OAuth login - no API key needed"),
15
+ ("api_keys", "API Keys", "OpenAI, Anthropic, Google, etc."),
16
+ ("openrouter", "OpenRouter", "Single key for 100+ models"),
17
+ ("skip", "Skip for now", "Configure later with /set or /add_model"),
18
+ ]
19
+
20
+
21
+ # ============================================================================
22
+ # Navigation Footer (shown on ALL slides)
23
+ # ============================================================================
24
+
25
+
26
+ def get_nav_footer() -> str:
27
+ """Navigation hints shown at bottom of every slide."""
28
+ return (
29
+ "\n[dim]─────────────────────────────────────[/dim]\n"
30
+ "[green]→/l[/green] Next "
31
+ "[green]←/h[/green] Back "
32
+ "[green]↑↓/jk[/green] Options "
33
+ "[green]Enter[/green] Select "
34
+ "[yellow]ESC[/yellow] Skip"
35
+ )
36
+
37
+
38
+ # ============================================================================
39
+ # Gradient Banner
40
+ # ============================================================================
41
+
42
+
43
+ def get_gradient_banner() -> str:
44
+ """Generate the gradient CODE PUPPY banner."""
45
+ try:
46
+ import pyfiglet
47
+
48
+ lines = pyfiglet.figlet_format("CODE PUPPY", font="ansi_shadow").split("\n")
49
+ colors = ["bright_blue", "bright_cyan", "bright_green"]
50
+ result = []
51
+ for i, line in enumerate(lines):
52
+ if line.strip():
53
+ color = colors[min(i // 2, len(colors) - 1)]
54
+ result.append(f"[{color}]{line}[/{color}]")
55
+ return "\n".join(result)
56
+ except ImportError:
57
+ return "[bold bright_cyan]═══ CODE PUPPY ═══[/bold bright_cyan]"
58
+
59
+
60
+ # ============================================================================
61
+ # Slide Content (5 slides total)
62
+ # ============================================================================
63
+
64
+
65
+ def slide_welcome() -> str:
66
+ """Slide 1: Welcome - quick intro."""
67
+ content = get_gradient_banner()
68
+ content += "\n\n"
69
+ content += "[bold white]Welcome.[/bold white]\n\n"
70
+ content += "[cyan]Quick setup:[/cyan]\n"
71
+ content += " 1. Pick your model provider\n"
72
+ content += " 2. Optional: External tools\n"
73
+ content += " 3. Learn when to use which agent\n"
74
+ content += " 4. Start coding!\n\n"
75
+ content += "[dim]Takes ~1 minute. Let's go![/dim]"
76
+ content += get_nav_footer()
77
+ return content
78
+
79
+
80
+ def slide_models(selected_option: int, options: list[tuple[str, str]]) -> str:
81
+ """Slide 2: Model selection."""
82
+ content = "[bold cyan]📦 Pick Your Models[/bold cyan]\n\n"
83
+ content += "[white]How do you want to access LLMs?[/white]\n\n"
84
+
85
+ for i, (_, label) in enumerate(options):
86
+ if i == selected_option:
87
+ content += f"[bold green]▶ {label}[/bold green]\n"
88
+ else:
89
+ content += f"[dim] {label}[/dim]\n"
90
+
91
+ content += "\n"
92
+
93
+ # Context based on selection
94
+ opt = options[selected_option][0] if options else None
95
+ if opt == "chatgpt":
96
+ content += "[yellow]💡 ChatGPT OAuth[/yellow]\n"
97
+ content += " Uses your existing subscription\n"
98
+ content += " GPT-5.2, GPT-5.2-codex\n"
99
+ elif opt == "claude":
100
+ content += "[yellow]💡 Claude OAuth[/yellow]\n"
101
+ content += " Uses your existing subscription\n"
102
+ content += " Opus/Sonnet/Haiku 4.5\n"
103
+ elif opt == "api_keys":
104
+ content += "[yellow]💡 API Keys[/yellow]\n"
105
+ content += " [cyan]/set OPENAI_API_KEY=sk-...[/cyan]\n"
106
+ content += " [cyan]/add_model[/cyan] to browse 1500+ models\n"
107
+ elif opt == "openrouter":
108
+ content += "[yellow]💡 OpenRouter[/yellow]\n"
109
+ content += " One API key, all providers\n"
110
+ content += " [cyan]/set OPENROUTER_API_KEY=...[/cyan]\n"
111
+ else:
112
+ content += "[dim]No worries! Use /set or /add_model later[/dim]\n"
113
+
114
+ content += get_nav_footer()
115
+ return content
116
+
117
+
118
+ def slide_use_cases() -> str:
119
+ """Slide 4: When to use which agent - THE IMPORTANT ONE."""
120
+ content = "[bold cyan]🎯 When to Use What[/bold cyan]\n\n"
121
+
122
+ content += "[bold yellow]Muse (default)[/bold yellow]\n"
123
+ content += " [green]USE FOR:[/green] Direct coding tasks\n"
124
+ content += " • Fix this bug\n"
125
+ content += " • Add a feature to this file\n"
126
+ content += " • Refactor this function\n"
127
+ content += " • Write tests for X\n\n"
128
+
129
+ content += "[bold yellow]📋 Planning Agent[/bold yellow]\n"
130
+ content += " [green]USE FOR:[/green] Complex multi-step projects\n"
131
+ content += " • Build me a REST API with auth\n"
132
+ content += " • Create a CLI tool from scratch\n"
133
+ content += " • Refactor entire codebase\n"
134
+ content += " • Multi-file architectural changes\n\n"
135
+
136
+ content += "[cyan]Switch: /agent planning-agent[/cyan]\n"
137
+ content += "[dim]Planning breaks big tasks into steps,[/dim]\n"
138
+ content += "[dim]then delegates to specialists.[/dim]"
139
+ content += get_nav_footer()
140
+ return content
141
+
142
+
143
+ def slide_done(trigger_oauth: str | None) -> str:
144
+ """Slide 5: You're ready!"""
145
+ content = "[bold green]🎉 Ready to Roll![/bold green]\n\n"
146
+ content += "[bold cyan]Essential commands:[/bold cyan]\n"
147
+ content += " [cyan]/model[/cyan] Switch models\n"
148
+ content += " [cyan]/agent[/cyan] Switch agents\n"
149
+ content += " [cyan]/help[/cyan] All commands\n\n"
150
+
151
+ content += "[bold yellow]Pro tips:[/bold yellow]\n"
152
+ content += " • Be specific in prompts\n"
153
+ content += " • Use Planning Agent for big tasks\n"
154
+ content += " • @ for file path completion\n\n"
155
+
156
+ if trigger_oauth:
157
+ content += f"[bold cyan]→ {trigger_oauth.title()} OAuth next![/bold cyan]\n\n"
158
+
159
+ content += "[dim]Re-run anytime: [/dim][cyan]/tutorial[/cyan]\n"
160
+ content += "\n[bold yellow]Press Enter to start.[/bold yellow]"
161
+ content += get_nav_footer()
162
+ return content
@@ -0,0 +1,337 @@
1
+ """Interactive TUI onboarding wizard for first-time Muse users.
2
+
3
+ Quick 5-slide tutorial. ADHD-friendly!
4
+
5
+ Usage:
6
+ from code_muse.command_line.onboarding_wizard import (
7
+ run_onboarding_wizard,
8
+ reset_onboarding,
9
+ )
10
+
11
+ result = await run_onboarding_wizard()
12
+ # result: "chatgpt", "claude", "completed", "skipped", or None
13
+ """
14
+
15
+ import asyncio
16
+ import io
17
+ import os
18
+ import sys
19
+
20
+ from prompt_toolkit import Application
21
+ from prompt_toolkit.formatted_text import ANSI
22
+ from prompt_toolkit.key_binding import KeyBindings
23
+ from prompt_toolkit.layout import Layout, Window
24
+ from prompt_toolkit.layout.controls import FormattedTextControl
25
+ from prompt_toolkit.widgets import Frame
26
+ from rich.console import Console
27
+
28
+ from code_muse.config import CONFIG_DIR
29
+
30
+ from .onboarding_slides import (
31
+ MODEL_OPTIONS,
32
+ slide_done,
33
+ slide_models,
34
+ slide_use_cases,
35
+ slide_welcome,
36
+ )
37
+
38
+ # ============================================================================
39
+ # State Tracking
40
+ # ============================================================================
41
+
42
+ ONBOARDING_COMPLETE_FILE = CONFIG_DIR / "onboarding_complete"
43
+
44
+
45
+ def has_completed_onboarding() -> bool:
46
+ """Check if the user has already completed onboarding."""
47
+ return ONBOARDING_COMPLETE_FILE.exists()
48
+
49
+
50
+ def mark_onboarding_complete() -> None:
51
+ """Mark onboarding as complete."""
52
+ ONBOARDING_COMPLETE_FILE.parent.mkdir(parents=True, exist_ok=True)
53
+ with open(ONBOARDING_COMPLETE_FILE, "w") as f:
54
+ f.write("completed\n")
55
+
56
+
57
+ def should_show_onboarding() -> bool:
58
+ """Determine if the onboarding wizard should be shown.
59
+
60
+ Returns False if:
61
+ - User has already completed onboarding
62
+ - MUSE_SKIP_TUTORIAL env var is set to '1' or 'true'
63
+ """
64
+ # Allow skipping tutorial via environment variable (useful for testing)
65
+ skip_env = os.environ.get("MUSE_SKIP_TUTORIAL", "").lower()
66
+ if skip_env in ("1", "true", "yes"):
67
+ return False
68
+ return not has_completed_onboarding()
69
+
70
+
71
+ def reset_onboarding() -> None:
72
+ """Reset onboarding state (for re-running with /tutorial)."""
73
+ if ONBOARDING_COMPLETE_FILE.exists():
74
+ ONBOARDING_COMPLETE_FILE.unlink()
75
+
76
+
77
+ # ============================================================================
78
+ # Onboarding Wizard Class
79
+ # ============================================================================
80
+
81
+
82
+ class OnboardingWizard:
83
+ """5-slide interactive tutorial.
84
+
85
+ Slides:
86
+ 0: Welcome
87
+ 1: Model selection
88
+ 2: Use cases (Planning vs Coding)
89
+ 3: Done!
90
+ """
91
+
92
+ TOTAL_SLIDES = 4
93
+
94
+ def __init__(self):
95
+ """Initialize wizard state."""
96
+ self.current_slide = 0
97
+ self.selected_option = 0
98
+ self.trigger_oauth: str | None = None
99
+ self.model_choice: str | None = None
100
+ self.result: str | None = None
101
+ self._should_exit = False
102
+
103
+ def get_progress_indicator(self) -> str:
104
+ """Progress dots: ● ○ ○ ○ ○"""
105
+ return " ".join(
106
+ "●" if i == self.current_slide else "○" for i in range(self.TOTAL_SLIDES)
107
+ )
108
+
109
+ def get_slide_content(self) -> str:
110
+ """Get content for current slide."""
111
+ if self.current_slide == 0:
112
+ return slide_welcome()
113
+ elif self.current_slide == 1:
114
+ options = self.get_options_for_slide()
115
+ return slide_models(self.selected_option, options)
116
+ elif self.current_slide == 2:
117
+ return slide_use_cases()
118
+ else: # slide 3
119
+ return slide_done(self.trigger_oauth)
120
+
121
+ def get_options_for_slide(self) -> list[tuple[str, str]]:
122
+ """Get selectable options for current slide."""
123
+ if self.current_slide == 1: # Model selection
124
+ return [(opt[0], opt[1]) for opt in MODEL_OPTIONS]
125
+ return []
126
+
127
+ def handle_option_select(self) -> None:
128
+ """Handle option selection."""
129
+ if self.current_slide == 1: # Model selection
130
+ options = self.get_options_for_slide()
131
+ if 0 <= self.selected_option < len(options):
132
+ choice_id = options[self.selected_option][0]
133
+ self.model_choice = choice_id
134
+ if choice_id == "chatgpt":
135
+ self.trigger_oauth = "chatgpt"
136
+ elif choice_id == "claude":
137
+ self.trigger_oauth = "claude"
138
+
139
+ def next_slide(self) -> bool:
140
+ """Move to next slide."""
141
+ if self.current_slide < self.TOTAL_SLIDES - 1:
142
+ self.current_slide += 1
143
+ self.selected_option = 0
144
+ return True
145
+ return False
146
+
147
+ def prev_slide(self) -> bool:
148
+ """Move to previous slide."""
149
+ if self.current_slide > 0:
150
+ self.current_slide -= 1
151
+ self.selected_option = 0
152
+ return True
153
+ return False
154
+
155
+ def next_option(self) -> None:
156
+ """Move to next option."""
157
+ options = self.get_options_for_slide()
158
+ if options:
159
+ self.selected_option = (self.selected_option + 1) % len(options)
160
+
161
+ def prev_option(self) -> None:
162
+ """Move to previous option."""
163
+ options = self.get_options_for_slide()
164
+ if options:
165
+ self.selected_option = (self.selected_option - 1) % len(options)
166
+
167
+
168
+ # ============================================================================
169
+ # TUI Rendering
170
+ # ============================================================================
171
+
172
+
173
+ def _get_slide_panel_content(wizard: OnboardingWizard) -> ANSI:
174
+ """Generate slide content for display."""
175
+ buffer = io.StringIO()
176
+ console = Console(
177
+ file=buffer,
178
+ force_terminal=True,
179
+ width=80,
180
+ legacy_windows=False,
181
+ color_system="truecolor",
182
+ no_color=False,
183
+ force_interactive=True,
184
+ )
185
+
186
+ # Progress indicator
187
+ progress = wizard.get_progress_indicator()
188
+ console.print(f"[dim]{progress}[/dim]")
189
+ console.print(
190
+ f"[dim]Slide {wizard.current_slide + 1} of {wizard.TOTAL_SLIDES}[/dim]\n"
191
+ )
192
+
193
+ # Slide content (includes nav footer)
194
+ console.print(wizard.get_slide_content())
195
+
196
+ return ANSI(buffer.getvalue())
197
+
198
+
199
+ # ============================================================================
200
+ # Main Entry Point
201
+ # ============================================================================
202
+
203
+
204
+ async def run_onboarding_wizard() -> str | None:
205
+ """Run the interactive tutorial.
206
+
207
+ Returns:
208
+ - "chatgpt" if user wants ChatGPT OAuth
209
+ - "claude" if user wants Claude OAuth
210
+ - "completed" if finished normally
211
+ - "skipped" if user pressed ESC
212
+ - None on error
213
+ """
214
+ from code_muse.tools.command_runner import set_awaiting_user_input
215
+
216
+ wizard = OnboardingWizard()
217
+ set_awaiting_user_input(True)
218
+
219
+ # Enter alternate screen buffer
220
+ sys.stdout.write("\033[?1049h") # Enter alternate buffer
221
+ sys.stdout.write("\033[2J\033[H") # Clear and home
222
+ sys.stdout.flush()
223
+ await asyncio.sleep(0.1)
224
+
225
+ try:
226
+ kb = KeyBindings()
227
+
228
+ @kb.add("right")
229
+ @kb.add("l")
230
+ def next_slide(event):
231
+ if wizard.current_slide == wizard.TOTAL_SLIDES - 1:
232
+ wizard.result = "completed"
233
+ wizard._should_exit = True
234
+ event.app.exit()
235
+ else:
236
+ wizard.next_slide()
237
+ event.app.invalidate()
238
+
239
+ @kb.add("left")
240
+ @kb.add("h")
241
+ def prev_slide(event):
242
+ wizard.prev_slide()
243
+ event.app.invalidate()
244
+
245
+ @kb.add("down")
246
+ @kb.add("j")
247
+ @kb.add("c-n") # Ctrl+N = next (Emacs-style)
248
+ def next_option(event):
249
+ wizard.next_option()
250
+ event.app.invalidate()
251
+
252
+ @kb.add("up")
253
+ @kb.add("k")
254
+ @kb.add("c-p") # Ctrl+P = previous (Emacs-style)
255
+ def prev_option(event):
256
+ wizard.prev_option()
257
+ event.app.invalidate()
258
+
259
+ @kb.add("enter")
260
+ def select_or_next(event):
261
+ options = wizard.get_options_for_slide()
262
+ if options:
263
+ wizard.handle_option_select()
264
+
265
+ if wizard.current_slide == wizard.TOTAL_SLIDES - 1:
266
+ wizard.result = "completed"
267
+ wizard._should_exit = True
268
+ event.app.exit()
269
+ else:
270
+ wizard.next_slide()
271
+ event.app.invalidate()
272
+
273
+ @kb.add("escape")
274
+ def skip_wizard(event):
275
+ wizard.result = "skipped"
276
+ wizard._should_exit = True
277
+ event.app.exit()
278
+
279
+ @kb.add("c-c")
280
+ def cancel_wizard(event):
281
+ wizard.result = "skipped"
282
+ wizard._should_exit = True
283
+ event.app.exit()
284
+
285
+ slide_panel = Window(
286
+ content=FormattedTextControl(lambda: _get_slide_panel_content(wizard))
287
+ )
288
+
289
+ root_container = Frame(slide_panel, title="Muse Tutorial")
290
+ layout = Layout(root_container)
291
+
292
+ app = Application(
293
+ layout=layout,
294
+ key_bindings=kb,
295
+ full_screen=False,
296
+ mouse_support=False,
297
+ color_depth="DEPTH_24_BIT",
298
+ )
299
+
300
+ sys.stdout.write("\033[2J\033[H")
301
+ sys.stdout.flush()
302
+
303
+ await app.run_async()
304
+
305
+ except KeyboardInterrupt:
306
+ wizard.result = "skipped"
307
+ except Exception:
308
+ wizard.result = None
309
+ finally:
310
+ set_awaiting_user_input(False)
311
+ sys.stdout.write("\033[?1049l")
312
+ sys.stdout.flush()
313
+
314
+ # Clear exit message
315
+ from code_muse.messaging import emit_info
316
+
317
+ if wizard.result == "skipped":
318
+ emit_info("✓ Tutorial skipped")
319
+ elif wizard.result == "completed":
320
+ emit_info("[Done] Tutorial complete. Welcome.")
321
+ else:
322
+ emit_info("✓ Exited tutorial")
323
+
324
+ if wizard.result in ("completed", "skipped"):
325
+ mark_onboarding_complete()
326
+
327
+ if wizard.trigger_oauth:
328
+ return wizard.trigger_oauth
329
+
330
+ return wizard.result
331
+
332
+
333
+ async def run_onboarding_if_needed() -> str | None:
334
+ """Run tutorial if user hasn't seen it yet."""
335
+ if should_show_onboarding():
336
+ return await run_onboarding_wizard()
337
+ return None
@@ -0,0 +1,41 @@
1
+ """Shared pagination helpers for command-line TUIs.
2
+
3
+ These helpers keep page math consistent across menus so selection and
4
+ page navigation behave the same way everywhere.
5
+ """
6
+
7
+
8
+ def get_total_pages(total_items: int, page_size: int) -> int:
9
+ """Return the total number of pages for a paginated list."""
10
+ if page_size <= 0:
11
+ raise ValueError("page_size must be greater than 0")
12
+ if total_items <= 0:
13
+ return 1
14
+ return (total_items + page_size - 1) // page_size
15
+
16
+
17
+ def get_page_bounds(page: int, total_items: int, page_size: int) -> tuple[int, int]:
18
+ """Return the inclusive start and exclusive end index for a page."""
19
+ start = max(0, page) * page_size
20
+ end = min(start + page_size, max(0, total_items))
21
+ return start, end
22
+
23
+
24
+ def get_page_for_index(index: int, page_size: int) -> int:
25
+ """Return the page containing the given absolute index."""
26
+ if page_size <= 0:
27
+ raise ValueError("page_size must be greater than 0")
28
+ return max(0, index) // page_size
29
+
30
+
31
+ def ensure_visible_page(
32
+ selected_index: int,
33
+ current_page: int,
34
+ total_items: int,
35
+ page_size: int,
36
+ ) -> int:
37
+ """Return the page that keeps the selected item visible."""
38
+ start, end = get_page_bounds(current_page, total_items, page_size)
39
+ if selected_index < start or selected_index >= end:
40
+ return get_page_for_index(selected_index, page_size)
41
+ return current_page