code-puppy-core-plugins 0.0.2__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 (313) hide show
  1. code_puppy_core_plugins/__init__.py +5 -0
  2. code_puppy_core_plugins/acp/README.md +266 -0
  3. code_puppy_core_plugins/acp/__init__.py +8 -0
  4. code_puppy_core_plugins/acp/agent.py +494 -0
  5. code_puppy_core_plugins/acp/bridge.py +309 -0
  6. code_puppy_core_plugins/acp/capabilities.py +73 -0
  7. code_puppy_core_plugins/acp/commands.py +116 -0
  8. code_puppy_core_plugins/acp/content.py +115 -0
  9. code_puppy_core_plugins/acp/io_delegation.py +231 -0
  10. code_puppy_core_plugins/acp/mcp_config.py +66 -0
  11. code_puppy_core_plugins/acp/permissions.py +159 -0
  12. code_puppy_core_plugins/acp/persistence.py +197 -0
  13. code_puppy_core_plugins/acp/register_callbacks.py +110 -0
  14. code_puppy_core_plugins/acp/replay.py +114 -0
  15. code_puppy_core_plugins/acp/session.py +329 -0
  16. code_puppy_core_plugins/acp/session_config.py +179 -0
  17. code_puppy_core_plugins/acp/state.py +135 -0
  18. code_puppy_core_plugins/agent_skills/__init__.py +22 -0
  19. code_puppy_core_plugins/agent_skills/config.py +208 -0
  20. code_puppy_core_plugins/agent_skills/discovery.py +337 -0
  21. code_puppy_core_plugins/agent_skills/downloader.py +392 -0
  22. code_puppy_core_plugins/agent_skills/enabled_skills.py +82 -0
  23. code_puppy_core_plugins/agent_skills/installer.py +22 -0
  24. code_puppy_core_plugins/agent_skills/metadata.py +219 -0
  25. code_puppy_core_plugins/agent_skills/prompt_builder.py +49 -0
  26. code_puppy_core_plugins/agent_skills/provider.py +52 -0
  27. code_puppy_core_plugins/agent_skills/register_callbacks.py +309 -0
  28. code_puppy_core_plugins/agent_skills/remote_catalog.py +322 -0
  29. code_puppy_core_plugins/agent_skills/skill_catalog.py +257 -0
  30. code_puppy_core_plugins/agent_skills/skill_commands.py +102 -0
  31. code_puppy_core_plugins/agent_skills/skills_install_menu.py +698 -0
  32. code_puppy_core_plugins/agent_skills/skills_menu.py +794 -0
  33. code_puppy_core_plugins/aws_bedrock/__init__.py +14 -0
  34. code_puppy_core_plugins/aws_bedrock/config.py +101 -0
  35. code_puppy_core_plugins/aws_bedrock/register_callbacks.py +243 -0
  36. code_puppy_core_plugins/aws_bedrock/utils.py +186 -0
  37. code_puppy_core_plugins/azure_foundry/README.md +238 -0
  38. code_puppy_core_plugins/azure_foundry/__init__.py +15 -0
  39. code_puppy_core_plugins/azure_foundry/config.py +126 -0
  40. code_puppy_core_plugins/azure_foundry/discovery.py +189 -0
  41. code_puppy_core_plugins/azure_foundry/register_callbacks.py +506 -0
  42. code_puppy_core_plugins/azure_foundry/token.py +182 -0
  43. code_puppy_core_plugins/azure_foundry/utils.py +375 -0
  44. code_puppy_core_plugins/btw/__init__.py +1 -0
  45. code_puppy_core_plugins/btw/inline_view.py +135 -0
  46. code_puppy_core_plugins/btw/register_callbacks.py +106 -0
  47. code_puppy_core_plugins/btw/side_query.py +91 -0
  48. code_puppy_core_plugins/chatgpt_oauth/IMAGEGEN_SKILL.md +83 -0
  49. code_puppy_core_plugins/chatgpt_oauth/__init__.py +8 -0
  50. code_puppy_core_plugins/chatgpt_oauth/config.py +52 -0
  51. code_puppy_core_plugins/chatgpt_oauth/image_generation.py +253 -0
  52. code_puppy_core_plugins/chatgpt_oauth/image_tool.py +70 -0
  53. code_puppy_core_plugins/chatgpt_oauth/oauth_flow.py +461 -0
  54. code_puppy_core_plugins/chatgpt_oauth/register_callbacks.py +288 -0
  55. code_puppy_core_plugins/chatgpt_oauth/test_plugin.py +663 -0
  56. code_puppy_core_plugins/chatgpt_oauth/usage.py +113 -0
  57. code_puppy_core_plugins/chatgpt_oauth/utils.py +534 -0
  58. code_puppy_core_plugins/claude_code_hooks/__init__.py +1 -0
  59. code_puppy_core_plugins/claude_code_hooks/config.py +137 -0
  60. code_puppy_core_plugins/claude_code_hooks/register_callbacks.py +383 -0
  61. code_puppy_core_plugins/claude_code_oauth/README.md +167 -0
  62. code_puppy_core_plugins/claude_code_oauth/SETUP.md +93 -0
  63. code_puppy_core_plugins/claude_code_oauth/__init__.py +25 -0
  64. code_puppy_core_plugins/claude_code_oauth/config.py +59 -0
  65. code_puppy_core_plugins/claude_code_oauth/fast_mode.py +122 -0
  66. code_puppy_core_plugins/claude_code_oauth/prompt_handler.py +64 -0
  67. code_puppy_core_plugins/claude_code_oauth/register_callbacks.py +719 -0
  68. code_puppy_core_plugins/claude_code_oauth/test_plugin.py +285 -0
  69. code_puppy_core_plugins/claude_code_oauth/token_refresh_heartbeat.py +240 -0
  70. code_puppy_core_plugins/claude_code_oauth/utils.py +663 -0
  71. code_puppy_core_plugins/code_puppy_agent/AGENTS_AND_TOOLS.md +155 -0
  72. code_puppy_core_plugins/code_puppy_agent/MODELS_AND_MCP.md +104 -0
  73. code_puppy_core_plugins/code_puppy_agent/PLUGINS_AND_CALLBACKS.md +147 -0
  74. code_puppy_core_plugins/code_puppy_agent/SESSIONS_AND_HISTORY.md +39 -0
  75. code_puppy_core_plugins/code_puppy_agent/SKILL.md +180 -0
  76. code_puppy_core_plugins/code_puppy_agent/SKILLS_SYSTEM.md +136 -0
  77. code_puppy_core_plugins/code_puppy_agent/SYSTEM_PROMPT_CONFIG_AND_I18N.md +160 -0
  78. code_puppy_core_plugins/code_puppy_agent/__init__.py +5 -0
  79. code_puppy_core_plugins/code_puppy_agent/register_callbacks.py +46 -0
  80. code_puppy_core_plugins/computer_use/NativeCapture.swift +123 -0
  81. code_puppy_core_plugins/computer_use/README.md +109 -0
  82. code_puppy_core_plugins/computer_use/__init__.py +1 -0
  83. code_puppy_core_plugins/computer_use/accessibility.py +163 -0
  84. code_puppy_core_plugins/computer_use/activation.py +75 -0
  85. code_puppy_core_plugins/computer_use/backend.py +584 -0
  86. code_puppy_core_plugins/computer_use/backend_types.py +5 -0
  87. code_puppy_core_plugins/computer_use/capture.py +110 -0
  88. code_puppy_core_plugins/computer_use/commands.py +62 -0
  89. code_puppy_core_plugins/computer_use/geometry.py +81 -0
  90. code_puppy_core_plugins/computer_use/inline_image.py +56 -0
  91. code_puppy_core_plugins/computer_use/keycodes.py +47 -0
  92. code_puppy_core_plugins/computer_use/policy.py +144 -0
  93. code_puppy_core_plugins/computer_use/register_callbacks.py +96 -0
  94. code_puppy_core_plugins/computer_use/safety.py +18 -0
  95. code_puppy_core_plugins/computer_use/settle.py +64 -0
  96. code_puppy_core_plugins/computer_use/state.py +86 -0
  97. code_puppy_core_plugins/computer_use/tools.py +469 -0
  98. code_puppy_core_plugins/context_indicator/__init__.py +14 -0
  99. code_puppy_core_plugins/context_indicator/register_callbacks.py +249 -0
  100. code_puppy_core_plugins/context_indicator/usage.py +40 -0
  101. code_puppy_core_plugins/copilot_auth/__init__.py +11 -0
  102. code_puppy_core_plugins/copilot_auth/config.py +93 -0
  103. code_puppy_core_plugins/copilot_auth/reasoning_client.py +409 -0
  104. code_puppy_core_plugins/copilot_auth/register_callbacks.py +460 -0
  105. code_puppy_core_plugins/copilot_auth/utils.py +587 -0
  106. code_puppy_core_plugins/customizable_commands/__init__.py +0 -0
  107. code_puppy_core_plugins/customizable_commands/register_callbacks.py +464 -0
  108. code_puppy_core_plugins/dbos_durable_exec/__init__.py +1 -0
  109. code_puppy_core_plugins/dbos_durable_exec/cancel.py +15 -0
  110. code_puppy_core_plugins/dbos_durable_exec/commands.py +31 -0
  111. code_puppy_core_plugins/dbos_durable_exec/config.py +31 -0
  112. code_puppy_core_plugins/dbos_durable_exec/lifecycle.py +83 -0
  113. code_puppy_core_plugins/dbos_durable_exec/register_callbacks.py +45 -0
  114. code_puppy_core_plugins/dbos_durable_exec/runtime.py +65 -0
  115. code_puppy_core_plugins/dbos_durable_exec/startup_lock.py +155 -0
  116. code_puppy_core_plugins/dbos_durable_exec/workflow_ids.py +16 -0
  117. code_puppy_core_plugins/dbos_durable_exec/wrapper.py +58 -0
  118. code_puppy_core_plugins/destructive_command_guard/AGENTS.md +79 -0
  119. code_puppy_core_plugins/destructive_command_guard/__init__.py +14 -0
  120. code_puppy_core_plugins/destructive_command_guard/detector.py +374 -0
  121. code_puppy_core_plugins/destructive_command_guard/register_callbacks.py +165 -0
  122. code_puppy_core_plugins/emoji_filter/__init__.py +12 -0
  123. code_puppy_core_plugins/emoji_filter/config.py +26 -0
  124. code_puppy_core_plugins/emoji_filter/register_callbacks.py +238 -0
  125. code_puppy_core_plugins/emoji_filter/stripper.py +45 -0
  126. code_puppy_core_plugins/empty_html_comment_filter/register_callbacks.py +116 -0
  127. code_puppy_core_plugins/example_custom_command/README.md +328 -0
  128. code_puppy_core_plugins/example_custom_command/register_callbacks.py +66 -0
  129. code_puppy_core_plugins/file_permission_handler/__init__.py +4 -0
  130. code_puppy_core_plugins/file_permission_handler/register_callbacks.py +575 -0
  131. code_puppy_core_plugins/flux_bootstrap/__init__.py +5 -0
  132. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/README.md +173 -0
  133. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/cheatsheet.md +86 -0
  134. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/pipeline.md +167 -0
  135. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/synopsis.md +392 -0
  136. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/about.md +51 -0
  137. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/address-feedback.md +129 -0
  138. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/ask.md +211 -0
  139. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/aug.md +181 -0
  140. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/auto-pilot.md +71 -0
  141. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/cheatsheet.md +16 -0
  142. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/commit.md +103 -0
  143. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/config.md +108 -0
  144. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/create-pr.md +195 -0
  145. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/exec.md +221 -0
  146. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/new.md +151 -0
  147. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/qa.md +208 -0
  148. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/rebase.md +180 -0
  149. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/review.md +304 -0
  150. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/split.md +120 -0
  151. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/squash-commits.md +179 -0
  152. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/status.md +46 -0
  153. code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/tests.md +155 -0
  154. code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_about.py +154 -0
  155. code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_cheatsheet.py +248 -0
  156. code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_status.py +345 -0
  157. code_puppy_core_plugins/flux_bootstrap/installer.py +256 -0
  158. code_puppy_core_plugins/flux_bootstrap/register_callbacks.py +71 -0
  159. code_puppy_core_plugins/force_push_guard/__init__.py +5 -0
  160. code_puppy_core_plugins/force_push_guard/detector.py +96 -0
  161. code_puppy_core_plugins/force_push_guard/register_callbacks.py +161 -0
  162. code_puppy_core_plugins/fork/__init__.py +7 -0
  163. code_puppy_core_plugins/fork/register_callbacks.py +445 -0
  164. code_puppy_core_plugins/frontend_emitter/__init__.py +25 -0
  165. code_puppy_core_plugins/frontend_emitter/emitter.py +249 -0
  166. code_puppy_core_plugins/frontend_emitter/register_callbacks.py +412 -0
  167. code_puppy_core_plugins/frontend_emitter/session_context.py +50 -0
  168. code_puppy_core_plugins/grok_oauth/__init__.py +6 -0
  169. code_puppy_core_plugins/grok_oauth/config.py +49 -0
  170. code_puppy_core_plugins/grok_oauth/oauth_flow.py +213 -0
  171. code_puppy_core_plugins/grok_oauth/register_callbacks.py +132 -0
  172. code_puppy_core_plugins/grok_oauth/utils.py +195 -0
  173. code_puppy_core_plugins/herdr/README.md +168 -0
  174. code_puppy_core_plugins/herdr/__init__.py +9 -0
  175. code_puppy_core_plugins/herdr/client.py +339 -0
  176. code_puppy_core_plugins/herdr/register_callbacks.py +140 -0
  177. code_puppy_core_plugins/herdr/reporter.py +212 -0
  178. code_puppy_core_plugins/herdr/smoke.py +143 -0
  179. code_puppy_core_plugins/herdr/sources.py +133 -0
  180. code_puppy_core_plugins/hook_creator/__init__.py +1 -0
  181. code_puppy_core_plugins/hook_creator/register_callbacks.py +33 -0
  182. code_puppy_core_plugins/hook_manager/__init__.py +1 -0
  183. code_puppy_core_plugins/hook_manager/config.py +290 -0
  184. code_puppy_core_plugins/hook_manager/hooks_menu.py +571 -0
  185. code_puppy_core_plugins/hook_manager/register_callbacks.py +227 -0
  186. code_puppy_core_plugins/meta_oauth/__init__.py +1 -0
  187. code_puppy_core_plugins/meta_oauth/config.py +55 -0
  188. code_puppy_core_plugins/meta_oauth/oauth_flow.py +109 -0
  189. code_puppy_core_plugins/meta_oauth/register_callbacks.py +154 -0
  190. code_puppy_core_plugins/meta_oauth/utils.py +252 -0
  191. code_puppy_core_plugins/namespace_skill_search/README.md +118 -0
  192. code_puppy_core_plugins/namespace_skill_search/__init__.py +15 -0
  193. code_puppy_core_plugins/namespace_skill_search/namespaces.py +125 -0
  194. code_puppy_core_plugins/namespace_skill_search/register_callbacks.py +99 -0
  195. code_puppy_core_plugins/namespace_skill_search/search_tool.py +158 -0
  196. code_puppy_core_plugins/no_tools/__init__.py +0 -0
  197. code_puppy_core_plugins/no_tools/register_callbacks.py +42 -0
  198. code_puppy_core_plugins/oauth_pasteback.py +110 -0
  199. code_puppy_core_plugins/oauth_puppy_html.py +194 -0
  200. code_puppy_core_plugins/obsidian_agent/README.md +52 -0
  201. code_puppy_core_plugins/obsidian_agent/__init__.py +8 -0
  202. code_puppy_core_plugins/obsidian_agent/agent_obsidian.py +147 -0
  203. code_puppy_core_plugins/obsidian_agent/register_callbacks.py +13 -0
  204. code_puppy_core_plugins/ollama/__init__.py +1 -0
  205. code_puppy_core_plugins/ollama/register_callbacks.py +127 -0
  206. code_puppy_core_plugins/ollama_setup/__init__.py +5 -0
  207. code_puppy_core_plugins/ollama_setup/completer.py +38 -0
  208. code_puppy_core_plugins/ollama_setup/register_callbacks.py +419 -0
  209. code_puppy_core_plugins/plugin_list/__init__.py +0 -0
  210. code_puppy_core_plugins/plugin_list/plugin_contributions.py +348 -0
  211. code_puppy_core_plugins/plugin_list/plugin_meta.py +67 -0
  212. code_puppy_core_plugins/plugin_list/plugin_text_utils.py +173 -0
  213. code_puppy_core_plugins/plugin_list/plugins_menu.py +455 -0
  214. code_puppy_core_plugins/plugin_list/plugins_menu_layout.py +194 -0
  215. code_puppy_core_plugins/plugin_list/plugins_menu_render.py +431 -0
  216. code_puppy_core_plugins/plugin_list/project_trust_flow.py +162 -0
  217. code_puppy_core_plugins/plugin_list/register_callbacks.py +281 -0
  218. code_puppy_core_plugins/pop_command/__init__.py +1 -0
  219. code_puppy_core_plugins/pop_command/register_callbacks.py +191 -0
  220. code_puppy_core_plugins/prompt_newline/__init__.py +13 -0
  221. code_puppy_core_plugins/prompt_newline/config.py +21 -0
  222. code_puppy_core_plugins/prompt_newline/register_callbacks.py +163 -0
  223. code_puppy_core_plugins/prune/__init__.py +1 -0
  224. code_puppy_core_plugins/prune/prune_menu.py +308 -0
  225. code_puppy_core_plugins/prune/prune_model.py +517 -0
  226. code_puppy_core_plugins/prune/prune_render.py +354 -0
  227. code_puppy_core_plugins/prune/register_callbacks.py +388 -0
  228. code_puppy_core_plugins/puppy_kennel/README.md +203 -0
  229. code_puppy_core_plugins/puppy_kennel/__init__.py +6 -0
  230. code_puppy_core_plugins/puppy_kennel/commands.py +206 -0
  231. code_puppy_core_plugins/puppy_kennel/config.py +36 -0
  232. code_puppy_core_plugins/puppy_kennel/kennel.py +368 -0
  233. code_puppy_core_plugins/puppy_kennel/packer.py +152 -0
  234. code_puppy_core_plugins/puppy_kennel/recorder.py +83 -0
  235. code_puppy_core_plugins/puppy_kennel/register_callbacks.py +109 -0
  236. code_puppy_core_plugins/puppy_kennel/retriever.py +28 -0
  237. code_puppy_core_plugins/puppy_kennel/schema.py +78 -0
  238. code_puppy_core_plugins/puppy_kennel/state.py +68 -0
  239. code_puppy_core_plugins/puppy_kennel/tools.py +449 -0
  240. code_puppy_core_plugins/puppy_kennel/wings.py +110 -0
  241. code_puppy_core_plugins/puppy_spinner/README.md +93 -0
  242. code_puppy_core_plugins/puppy_spinner/__init__.py +11 -0
  243. code_puppy_core_plugins/puppy_spinner/builtin_frames.py +172 -0
  244. code_puppy_core_plugins/puppy_spinner/commands.py +116 -0
  245. code_puppy_core_plugins/puppy_spinner/picker.py +379 -0
  246. code_puppy_core_plugins/puppy_spinner/register_callbacks.py +193 -0
  247. code_puppy_core_plugins/puppy_spinner/spinners.py +444 -0
  248. code_puppy_core_plugins/quick_resume/__init__.py +0 -0
  249. code_puppy_core_plugins/quick_resume/register_callbacks.py +77 -0
  250. code_puppy_core_plugins/review_pr/__init__.py +1 -0
  251. code_puppy_core_plugins/review_pr/register_callbacks.py +162 -0
  252. code_puppy_core_plugins/shell_safety/__init__.py +6 -0
  253. code_puppy_core_plugins/shell_safety/agent_shell_safety.py +69 -0
  254. code_puppy_core_plugins/shell_safety/command_cache.py +156 -0
  255. code_puppy_core_plugins/shell_safety/register_callbacks.py +203 -0
  256. code_puppy_core_plugins/stack_dump/__init__.py +1 -0
  257. code_puppy_core_plugins/stack_dump/register_callbacks.py +79 -0
  258. code_puppy_core_plugins/statusline/__init__.py +14 -0
  259. code_puppy_core_plugins/statusline/config.py +68 -0
  260. code_puppy_core_plugins/statusline/payload.py +138 -0
  261. code_puppy_core_plugins/statusline/prompt_patch.py +76 -0
  262. code_puppy_core_plugins/statusline/register_callbacks.py +45 -0
  263. code_puppy_core_plugins/statusline/runner.py +122 -0
  264. code_puppy_core_plugins/statusline/statusline_command.py +197 -0
  265. code_puppy_core_plugins/steer_queue/__init__.py +10 -0
  266. code_puppy_core_plugins/steer_queue/queue_menu.py +444 -0
  267. code_puppy_core_plugins/steer_queue/register_callbacks.py +138 -0
  268. code_puppy_core_plugins/subagent_panel/README.md +102 -0
  269. code_puppy_core_plugins/subagent_panel/__init__.py +24 -0
  270. code_puppy_core_plugins/subagent_panel/coalesce_patch.py +242 -0
  271. code_puppy_core_plugins/subagent_panel/panel_render.py +145 -0
  272. code_puppy_core_plugins/subagent_panel/register_callbacks.py +535 -0
  273. code_puppy_core_plugins/subagent_panel/resume_repaint.py +112 -0
  274. code_puppy_core_plugins/subagent_panel/state.py +231 -0
  275. code_puppy_core_plugins/switch_agent_resume/__init__.py +5 -0
  276. code_puppy_core_plugins/switch_agent_resume/register_callbacks.py +314 -0
  277. code_puppy_core_plugins/theme/README.md +86 -0
  278. code_puppy_core_plugins/theme/__init__.py +14 -0
  279. code_puppy_core_plugins/theme/bundled_palettes.py +346 -0
  280. code_puppy_core_plugins/theme/content_styles.py +146 -0
  281. code_puppy_core_plugins/theme/osc_palette.py +178 -0
  282. code_puppy_core_plugins/theme/picker.py +358 -0
  283. code_puppy_core_plugins/theme/prompt_toolkit_theme.py +113 -0
  284. code_puppy_core_plugins/theme/register_callbacks.py +348 -0
  285. code_puppy_core_plugins/theme/rich_themes.py +202 -0
  286. code_puppy_core_plugins/theme/themes.py +720 -0
  287. code_puppy_core_plugins/timestamp_heartbeat/__init__.py +1 -0
  288. code_puppy_core_plugins/timestamp_heartbeat/register_callbacks.py +114 -0
  289. code_puppy_core_plugins/token_ratio_learner/__init__.py +5 -0
  290. code_puppy_core_plugins/token_ratio_learner/ratios.py +208 -0
  291. code_puppy_core_plugins/token_ratio_learner/register_callbacks.py +213 -0
  292. code_puppy_core_plugins/universal_constructor/__init__.py +13 -0
  293. code_puppy_core_plugins/universal_constructor/models.py +138 -0
  294. code_puppy_core_plugins/universal_constructor/provider.py +62 -0
  295. code_puppy_core_plugins/universal_constructor/register_callbacks.py +75 -0
  296. code_puppy_core_plugins/universal_constructor/registry.py +302 -0
  297. code_puppy_core_plugins/universal_constructor/sandbox.py +584 -0
  298. code_puppy_core_plugins/wide_completion_menu/__init__.py +6 -0
  299. code_puppy_core_plugins/wide_completion_menu/register_callbacks.py +165 -0
  300. code_puppy_core_plugins/wiggum/__init__.py +1 -0
  301. code_puppy_core_plugins/wiggum/goal_runs.py +91 -0
  302. code_puppy_core_plugins/wiggum/judge.py +299 -0
  303. code_puppy_core_plugins/wiggum/judge_config.py +249 -0
  304. code_puppy_core_plugins/wiggum/judges_menu.py +814 -0
  305. code_puppy_core_plugins/wiggum/register_callbacks.py +569 -0
  306. code_puppy_core_plugins/wiggum/state.py +89 -0
  307. code_puppy_core_plugins/yolo_cli/__init__.py +1 -0
  308. code_puppy_core_plugins/yolo_cli/register_callbacks.py +41 -0
  309. code_puppy_core_plugins-0.0.2.dist-info/METADATA +64 -0
  310. code_puppy_core_plugins-0.0.2.dist-info/RECORD +313 -0
  311. code_puppy_core_plugins-0.0.2.dist-info/WHEEL +4 -0
  312. code_puppy_core_plugins-0.0.2.dist-info/entry_points.txt +55 -0
  313. code_puppy_core_plugins-0.0.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,571 @@
1
+ """
2
+ Interactive TUI for managing Claude Code hooks.
3
+
4
+ Launch with /hooks to browse, enable/disable, inspect, and delete hooks
5
+ from both global (~/.code_puppy/hooks.json) and project (.claude/settings.json) sources.
6
+
7
+ Built with prompt_toolkit to match the existing skills_menu aesthetic exactly
8
+ (VSplit, FormattedTextControl, Frame).
9
+ """
10
+
11
+ import sys
12
+ import time
13
+ from typing import List, Optional
14
+
15
+ from prompt_toolkit.application import Application
16
+ from prompt_toolkit.key_binding import KeyBindings
17
+ from prompt_toolkit.layout import Dimension, Layout, VSplit, Window
18
+ from prompt_toolkit.layout.controls import FormattedTextControl
19
+ from prompt_toolkit.widgets import Frame
20
+
21
+ from code_puppy.messaging import emit_error
22
+
23
+ from .config import (
24
+ HookEntry,
25
+ _load_global_hooks_config,
26
+ _load_project_hooks_config,
27
+ delete_hook,
28
+ flatten_all_hooks,
29
+ save_global_hooks_config,
30
+ save_hooks_config,
31
+ toggle_hook_enabled,
32
+ )
33
+ from code_puppy.callbacks import on_prompt_toolkit_style
34
+
35
+ PAGE_SIZE = 12
36
+
37
+
38
+ class HooksMenu:
39
+ """Interactive TUI for managing hooks from both global and project sources."""
40
+
41
+ def __init__(self) -> None:
42
+ self.entries: List[HookEntry] = []
43
+ self.selected_idx: int = 0
44
+ self.current_page: int = 0
45
+ self.result: Optional[str] = None
46
+ self.status_message: str = ""
47
+
48
+ # prompt_toolkit controls (set during run())
49
+ self.list_control: Optional[FormattedTextControl] = None
50
+ self.detail_control: Optional[FormattedTextControl] = None
51
+
52
+ self._refresh_data()
53
+
54
+ # ------------------------------------------------------------------
55
+ # Data helpers
56
+ # ------------------------------------------------------------------
57
+
58
+ def _refresh_data(self) -> None:
59
+ """Reload hooks from both global and project sources."""
60
+ try:
61
+ self.entries = flatten_all_hooks()
62
+ # Clamp selection
63
+ if self.entries:
64
+ self.selected_idx = min(self.selected_idx, len(self.entries) - 1)
65
+ else:
66
+ self.selected_idx = 0
67
+ except Exception as exc:
68
+ emit_error(f"Failed to refresh hooks data: {exc}")
69
+ self.entries = []
70
+
71
+ def _current_entry(self) -> Optional[HookEntry]:
72
+ if 0 <= self.selected_idx < len(self.entries):
73
+ return self.entries[self.selected_idx]
74
+ return None
75
+
76
+ def _save_current_entry(
77
+ self, entry: HookEntry, new_enabled: Optional[bool] = None
78
+ ) -> None:
79
+ """Persist changes to the current entry's source file."""
80
+ if entry.source == "global":
81
+ global_config = _load_global_hooks_config()
82
+ if new_enabled is not None:
83
+ global_config = toggle_hook_enabled(
84
+ global_config,
85
+ entry.event_type,
86
+ entry._group_index,
87
+ entry._hook_index,
88
+ new_enabled,
89
+ )
90
+ save_global_hooks_config(global_config)
91
+ else: # project
92
+ project_config = _load_project_hooks_config()
93
+ if new_enabled is not None:
94
+ project_config = toggle_hook_enabled(
95
+ project_config,
96
+ entry.event_type,
97
+ entry._group_index,
98
+ entry._hook_index,
99
+ new_enabled,
100
+ )
101
+ save_hooks_config(project_config)
102
+
103
+ # ------------------------------------------------------------------
104
+ # Actions triggered by key bindings
105
+ # ------------------------------------------------------------------
106
+
107
+ def _toggle_current(self) -> None:
108
+ """Toggle enabled/disabled on the selected hook."""
109
+ entry = self._current_entry()
110
+ if entry is None:
111
+ return
112
+ new_enabled = not entry.enabled
113
+ self._save_current_entry(entry, new_enabled)
114
+ self._refresh_data()
115
+ self.status_message = (
116
+ f"Hook {'enabled' if new_enabled else 'disabled'}: {entry.display_command}"
117
+ )
118
+ self.update_display()
119
+
120
+ def _delete_current(self) -> None:
121
+ """Delete the selected hook (with guard against empty config)."""
122
+ entry = self._current_entry()
123
+ if entry is None:
124
+ return
125
+
126
+ if entry.source == "global":
127
+ global_config = _load_global_hooks_config()
128
+ global_config = delete_hook(
129
+ global_config,
130
+ entry.event_type,
131
+ entry._group_index,
132
+ entry._hook_index,
133
+ )
134
+ save_global_hooks_config(global_config)
135
+ else: # project
136
+ project_config = _load_project_hooks_config()
137
+ project_config = delete_hook(
138
+ project_config,
139
+ entry.event_type,
140
+ entry._group_index,
141
+ entry._hook_index,
142
+ )
143
+ save_hooks_config(project_config)
144
+
145
+ self._refresh_data()
146
+ self.status_message = f"Deleted hook: {entry.display_command}"
147
+ self.update_display()
148
+
149
+ def _enable_all(self) -> None:
150
+ """Enable every hook in both project and global configs."""
151
+ import copy
152
+
153
+ # Enable all project hooks
154
+ project_config = _load_project_hooks_config()
155
+ project_cfg = copy.deepcopy(project_config)
156
+ for groups in project_cfg.values():
157
+ if not isinstance(groups, list):
158
+ continue
159
+ for group in groups:
160
+ for hook in group.get("hooks", []):
161
+ hook["enabled"] = True
162
+ save_hooks_config(project_cfg)
163
+
164
+ # Enable all global hooks
165
+ global_config = _load_global_hooks_config()
166
+ global_cfg = copy.deepcopy(global_config)
167
+ for groups in global_cfg.values():
168
+ if not isinstance(groups, list):
169
+ continue
170
+ for group in groups:
171
+ for hook in group.get("hooks", []):
172
+ hook["enabled"] = True
173
+ save_global_hooks_config(global_cfg)
174
+
175
+ self._refresh_data()
176
+ self.status_message = "All hooks enabled."
177
+ self.update_display()
178
+
179
+ def _disable_all(self) -> None:
180
+ """Disable every hook in both project and global configs."""
181
+ import copy
182
+
183
+ # Disable all project hooks
184
+ project_config = _load_project_hooks_config()
185
+ project_cfg = copy.deepcopy(project_config)
186
+ for groups in project_cfg.values():
187
+ if not isinstance(groups, list):
188
+ continue
189
+ for group in groups:
190
+ for hook in group.get("hooks", []):
191
+ hook["enabled"] = False
192
+ save_hooks_config(project_cfg)
193
+
194
+ # Disable all global hooks
195
+ global_config = _load_global_hooks_config()
196
+ global_cfg = copy.deepcopy(global_config)
197
+ for groups in global_cfg.values():
198
+ if not isinstance(groups, list):
199
+ continue
200
+ for group in groups:
201
+ for hook in group.get("hooks", []):
202
+ hook["enabled"] = False
203
+ save_global_hooks_config(global_cfg)
204
+
205
+ self._refresh_data()
206
+ self.status_message = "All hooks disabled."
207
+ self.update_display()
208
+
209
+ # ------------------------------------------------------------------
210
+ # Rendering helpers
211
+ # ------------------------------------------------------------------
212
+
213
+ def _render_list(self) -> List:
214
+ """Render the left-hand hooks list panel."""
215
+ lines: List = []
216
+
217
+ total = len(self.entries)
218
+ enabled_count = sum(1 for e in self.entries if e.enabled)
219
+ project_count = sum(1 for e in self.entries if e.source == "project")
220
+ global_count = sum(1 for e in self.entries if e.source == "global")
221
+
222
+ header_color = "class:tui.success" if enabled_count > 0 else "class:tui.error"
223
+ lines.append((header_color, f" Hooks: {enabled_count}/{total} enabled"))
224
+ lines.append(("", f" ({project_count} project, {global_count} global)\n\n"))
225
+
226
+ if not self.entries:
227
+ lines.append(("class:tui.warning", " No hooks configured."))
228
+ lines.append(("", "\n"))
229
+ lines.append(
230
+ ("class:tui.muted", " Add hooks to .claude/settings.json (project)")
231
+ )
232
+ lines.append(("", "\n"))
233
+ lines.append(("class:tui.muted", " or ~/.code_puppy/hooks.json (global)"))
234
+ lines.append(("", "\n\n"))
235
+ self._render_nav_hints(lines)
236
+ return lines
237
+
238
+ total_pages = max(1, (total + PAGE_SIZE - 1) // PAGE_SIZE)
239
+ start = self.current_page * PAGE_SIZE
240
+ end = min(start + PAGE_SIZE, total)
241
+ for i in range(start, end):
242
+ entry = self.entries[i]
243
+ is_selected = i == self.selected_idx
244
+ status_icon = "✓" if entry.enabled else "✗"
245
+ status_style = "class:tui.success" if entry.enabled else "class:tui.error"
246
+ source_indicator = "🌍" if entry.source == "global" else "📁"
247
+ prefix = " > " if is_selected else " "
248
+
249
+ if is_selected:
250
+ lines.append(("class:tui.selected", prefix))
251
+ lines.append((status_style + " bold", status_icon))
252
+ lines.append(
253
+ ("class:tui.selected", f" {source_indicator} [{entry.event_type}]")
254
+ )
255
+ lines.append(("class:tui.selected", f" {entry.display_matcher}"))
256
+ else:
257
+ lines.append(("", prefix))
258
+ lines.append((status_style, status_icon))
259
+ source_color = (
260
+ "class:tui.header"
261
+ if entry.source == "global"
262
+ else "class:tui.success"
263
+ )
264
+ lines.append((source_color, f" {source_indicator}"))
265
+ lines.append(("class:tui.muted", f" [{entry.event_type}]"))
266
+ lines.append(("", f" {entry.display_matcher}"))
267
+ lines.append(("", "\n"))
268
+
269
+ lines.append(("", "\n"))
270
+ lines.append(
271
+ ("class:tui.muted", f" Page {self.current_page + 1}/{total_pages}")
272
+ )
273
+ lines.append(("", "\n"))
274
+
275
+ # Status message (shows result of last action)
276
+ if self.status_message:
277
+ lines.append(("", "\n"))
278
+ lines.append(("class:tui.header", f" {self.status_message}"))
279
+ lines.append(("", "\n"))
280
+
281
+ self._render_nav_hints(lines)
282
+ return lines
283
+
284
+ def _render_nav_hints(self, lines: List) -> None:
285
+ """Append keyboard shortcut hints to lines."""
286
+ lines.append(("", "\n"))
287
+ lines.append(("class:tui.help-key", " ↑/↓ j/k "))
288
+ lines.append(("", "Navigate\n"))
289
+ lines.append(("class:tui.help-key", " Enter "))
290
+ lines.append(("", "Toggle enable/disable\n"))
291
+ lines.append(("class:tui.help-key", " d "))
292
+ lines.append(("", "Delete hook\n"))
293
+ lines.append(("class:tui.help-key", " A "))
294
+ lines.append(("", "Enable all\n"))
295
+ lines.append(("class:tui.help-key", " D "))
296
+ lines.append(("", "Disable all\n"))
297
+ lines.append(("class:tui.help-key", " r "))
298
+ lines.append(("", "Refresh\n"))
299
+ lines.append(("class:tui.help-key", " q/Esc "))
300
+ lines.append(("", "Exit"))
301
+
302
+ def _render_detail(self) -> List:
303
+ """Render the right-hand hook detail panel."""
304
+ lines: List = []
305
+ lines.append(("class:tui.title dim", " HOOK DETAILS"))
306
+ lines.append(("", "\n\n"))
307
+
308
+ entry = self._current_entry()
309
+ if entry is None:
310
+ lines.append(("class:tui.warning", " No hook selected."))
311
+ lines.append(("", "\n\n"))
312
+ lines.append(("class:tui.muted", " Select a hook from the list"))
313
+ lines.append(("", "\n"))
314
+ lines.append(("class:tui.muted", " to view its details."))
315
+ return lines
316
+
317
+ # Status badge
318
+ status_text = "Enabled" if entry.enabled else "Disabled"
319
+ status_style = (
320
+ "class:tui.success" + " bold"
321
+ if entry.enabled
322
+ else "class:tui.error" + " bold"
323
+ )
324
+ lines.append(("bold", " Status: "))
325
+ lines.append((status_style, status_text))
326
+ lines.append(("", "\n\n"))
327
+
328
+ # Source indicator
329
+ source_label = (
330
+ "Global (~/.code_puppy/hooks.json)"
331
+ if entry.source == "global"
332
+ else "Project (.claude/settings.json)"
333
+ )
334
+ source_color = (
335
+ "class:tui.header" if entry.source == "global" else "class:tui.success"
336
+ )
337
+ lines.append(("bold", " Source: "))
338
+ lines.append((source_color, source_label))
339
+ lines.append(("", "\n\n"))
340
+
341
+ # Event type
342
+ lines.append(("bold", " Event: "))
343
+ lines.append(("class:tui.header", entry.event_type))
344
+ lines.append(("", "\n\n"))
345
+
346
+ # Matcher
347
+ lines.append(("bold", " Matcher: "))
348
+ lines.append(("", "\n"))
349
+ for chunk in _wrap(entry.matcher, 50):
350
+ lines.append(("class:tui.warning", f" {chunk}"))
351
+ lines.append(("", "\n"))
352
+ lines.append(("", "\n"))
353
+
354
+ # Type
355
+ lines.append(("bold", " Type: "))
356
+ lines.append(("class:tui.muted", entry.hook_type))
357
+ lines.append(("", "\n\n"))
358
+
359
+ # Command / prompt
360
+ label = "Command:" if entry.hook_type == "command" else "Prompt: "
361
+ lines.append(("bold", f" {label}"))
362
+ lines.append(("", "\n"))
363
+ for chunk in _wrap(entry.command, 50):
364
+ lines.append(("class:tui.muted", f" {chunk}"))
365
+ lines.append(("", "\n"))
366
+ lines.append(("", "\n"))
367
+
368
+ # Timeout
369
+ lines.append(("bold", " Timeout: "))
370
+ lines.append(("class:tui.muted", f"{entry.timeout} ms"))
371
+ lines.append(("", "\n\n"))
372
+
373
+ # Hook ID
374
+ if entry.hook_id:
375
+ lines.append(("bold", " ID: "))
376
+ lines.append(("class:tui.muted", entry.hook_id))
377
+ lines.append(("", "\n\n"))
378
+
379
+ # Config location hint
380
+ lines.append(("class:tui.muted", f" Stored in {source_label}"))
381
+ lines.append(("", "\n"))
382
+ lines.append(
383
+ (
384
+ "class:tui.muted",
385
+ f" group #{entry._group_index} hook #{entry._hook_index}",
386
+ )
387
+ )
388
+ lines.append(("", "\n"))
389
+
390
+ return lines
391
+
392
+ def update_display(self) -> None:
393
+ """Push freshly rendered text into the prompt_toolkit controls."""
394
+ if self.list_control:
395
+ self.list_control.text = self._render_list()
396
+ if self.detail_control:
397
+ self.detail_control.text = self._render_detail()
398
+
399
+ # ------------------------------------------------------------------
400
+ # Main entry point
401
+ # ------------------------------------------------------------------
402
+
403
+ def run(self) -> Optional[str]:
404
+ """Launch the interactive TUI. Returns the exit reason string."""
405
+ self.result = None
406
+
407
+ self.list_control = FormattedTextControl(text="")
408
+ self.detail_control = FormattedTextControl(text="")
409
+
410
+ list_window = Window(
411
+ content=self.list_control, wrap_lines=True, width=Dimension(weight=40)
412
+ )
413
+ detail_window = Window(
414
+ content=self.detail_control, wrap_lines=True, width=Dimension(weight=60)
415
+ )
416
+
417
+ list_frame = Frame(list_window, width=Dimension(weight=40), title="Hooks")
418
+ detail_frame = Frame(detail_window, width=Dimension(weight=60), title="Details")
419
+
420
+ root_container = VSplit([list_frame, detail_frame])
421
+ kb = KeyBindings()
422
+
423
+ # --- Navigation ---
424
+ @kb.add("up")
425
+ @kb.add("c-p")
426
+ @kb.add("k")
427
+ def _move_up(event):
428
+ if self.selected_idx > 0:
429
+ self.selected_idx -= 1
430
+ self.current_page = self.selected_idx // PAGE_SIZE
431
+ self.update_display()
432
+
433
+ @kb.add("down")
434
+ @kb.add("c-n")
435
+ @kb.add("j")
436
+ def _move_down(event):
437
+ if self.selected_idx < len(self.entries) - 1:
438
+ self.selected_idx += 1
439
+ self.current_page = self.selected_idx // PAGE_SIZE
440
+ self.update_display()
441
+
442
+ @kb.add("left")
443
+ def _prev_page(event):
444
+ if self.current_page > 0:
445
+ self.current_page -= 1
446
+ self.selected_idx = self.current_page * PAGE_SIZE
447
+ self.update_display()
448
+
449
+ @kb.add("right")
450
+ def _next_page(event):
451
+ total_pages = max(1, (len(self.entries) + PAGE_SIZE - 1) // PAGE_SIZE)
452
+ if self.current_page < total_pages - 1:
453
+ self.current_page += 1
454
+ self.selected_idx = self.current_page * PAGE_SIZE
455
+ self.update_display()
456
+
457
+ # --- Actions ---
458
+ @kb.add("enter")
459
+ def _toggle(event):
460
+ self._toggle_current()
461
+ self.result = "changed"
462
+
463
+ @kb.add("d")
464
+ def _delete(event):
465
+ self._delete_current()
466
+ self.result = "changed"
467
+
468
+ @kb.add("A") # capital A = enable ALL
469
+ def _enable_all(event):
470
+ self._enable_all()
471
+ self.result = "changed"
472
+
473
+ @kb.add("D") # capital D = disable ALL
474
+ def _disable_all(event):
475
+ self._disable_all()
476
+ self.result = "changed"
477
+
478
+ @kb.add("r")
479
+ def _refresh(event):
480
+ self._refresh_data()
481
+ self.status_message = "Refreshed."
482
+ self.update_display()
483
+
484
+ # --- Exit ---
485
+ @kb.add("q")
486
+ @kb.add("escape")
487
+ def _quit(event):
488
+ self.result = "quit"
489
+ event.app.exit()
490
+
491
+ @kb.add("c-c")
492
+ def _quit_ctrl_c(event):
493
+ self.result = "quit"
494
+ event.app.exit()
495
+
496
+ layout = Layout(root_container)
497
+ app = Application(
498
+ layout=layout,
499
+ key_bindings=kb,
500
+ full_screen=False,
501
+ mouse_support=False,
502
+ style=on_prompt_toolkit_style(),
503
+ )
504
+
505
+ try:
506
+ from code_puppy.tools.command_runner import set_awaiting_user_input
507
+
508
+ set_awaiting_user_input(True)
509
+ except Exception:
510
+ pass
511
+
512
+ # Enter alternate screen buffer
513
+ sys.stdout.write("\033[?1049h")
514
+ sys.stdout.write("\033[2J\033[H")
515
+ sys.stdout.flush()
516
+ time.sleep(0.05)
517
+
518
+ try:
519
+ self.update_display()
520
+ sys.stdout.write("\033[2J\033[H")
521
+ sys.stdout.flush()
522
+ app.run(in_thread=True)
523
+ finally:
524
+ sys.stdout.write("\033[?1049l")
525
+ sys.stdout.flush()
526
+ try:
527
+ import termios
528
+
529
+ termios.tcflush(sys.stdin.fileno(), termios.TCIFLUSH)
530
+ except Exception:
531
+ pass # ImportError on Windows, termios.error, or not a tty
532
+ time.sleep(0.1)
533
+ try:
534
+ from code_puppy.tools.command_runner import set_awaiting_user_input
535
+
536
+ set_awaiting_user_input(False)
537
+ except Exception:
538
+ pass
539
+
540
+ return self.result
541
+
542
+
543
+ # ---------------------------------------------------------------------------
544
+ # Helpers
545
+ # ---------------------------------------------------------------------------
546
+
547
+
548
+ def _wrap(text: str, width: int) -> List[str]:
549
+ """Wrap text to *width* characters, splitting on whitespace."""
550
+ words = text.split()
551
+ lines: List[str] = []
552
+ current: List[str] = []
553
+ length = 0
554
+ for word in words:
555
+ if length + len(word) + (1 if current else 0) <= width:
556
+ current.append(word)
557
+ length += len(word) + (1 if len(current) > 1 else 0)
558
+ else:
559
+ if current:
560
+ lines.append(" ".join(current))
561
+ current = [word]
562
+ length = len(word)
563
+ if current:
564
+ lines.append(" ".join(current))
565
+ return lines or [""]
566
+
567
+
568
+ def show_hooks_menu() -> None:
569
+ """Public entry point called from register_callbacks.py."""
570
+ menu = HooksMenu()
571
+ menu.run()