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,165 @@
1
+ """Register callbacks for the ``wide_completion_menu`` plugin.
2
+
3
+ Hooks:
4
+
5
+ * ``startup`` — monkey-patches prompt_toolkit's completion menu width so the
6
+ scrollbar anchors to the right edge of the terminal rather than the right
7
+ edge of the menu content.
8
+ * ``custom_command`` / ``custom_command_help`` — exposes ``/widemenu`` to
9
+ toggle the effect at runtime without restarting the app.
10
+
11
+ Design notes
12
+ ------------
13
+ prompt_toolkit's :class:`CompletionsMenuControl.preferred_width` returns
14
+ ``menu_width + menu_meta_width`` based on the longest completion, so the
15
+ menu is content-sized and the scrollbar lives wherever that content ends.
16
+ We replace ``preferred_width`` with a version that returns
17
+ ``max_available_width``, causing the parent ``Window`` to stretch the menu
18
+ across the full row. Combined with the existing ``_left_justify_completion_menu``
19
+ that pins the menu's ``Float`` to column 0, the scrollbar lands flush against
20
+ the right edge of the screen.
21
+
22
+ The patch is:
23
+
24
+ * **Idempotent** — re-installing is a no-op (sentinel attribute).
25
+ * **Reversible** — original methods are stashed and restored on disable.
26
+ * **Defensive** — every patch step is wrapped in try/except so a
27
+ prompt_toolkit version bump cannot crash the prompt.
28
+ """
29
+
30
+ from __future__ import annotations
31
+
32
+ from typing import List, Tuple
33
+
34
+ from code_puppy.callbacks import register_callback
35
+
36
+ _COMMAND_NAME = "widemenu"
37
+ _PATCH_FLAG = "_wide_completion_menu_patched"
38
+ _ORIGINAL_ATTR = "_wide_completion_menu_original_preferred_width"
39
+
40
+ # Module state lets /widemenu toggle without uninstalling; disabled mode delegates
41
+ # ``preferred_width`` to upstream.
42
+ _state = {"enabled": True}
43
+
44
+
45
+ # Messaging helpers (lazy-imported to avoid boot-time cycles)
46
+ def _emit_info(message: str) -> None:
47
+ from code_puppy.messaging import emit_info
48
+
49
+ emit_info(message)
50
+
51
+
52
+ def _emit_error(message: str) -> None:
53
+ from code_puppy.messaging import emit_error
54
+
55
+ emit_error(message)
56
+
57
+
58
+ # Patching
59
+ def _patch_menu_class(cls) -> None:
60
+ """Replace ``cls.preferred_width`` with a screen-filling variant.
61
+
62
+ Stores the original method on the class under ``_ORIGINAL_ATTR`` so we
63
+ can both delegate to it (when toggled off) and restore it cleanly.
64
+ """
65
+ if getattr(cls, _PATCH_FLAG, False):
66
+ return # Already patched.
67
+
68
+ original = cls.preferred_width
69
+ setattr(cls, _ORIGINAL_ATTR, original)
70
+
71
+ def patched_preferred_width(self, max_available_width: int):
72
+ # When toggled off, behave exactly like upstream.
73
+ if not _state["enabled"]:
74
+ return original(self, max_available_width)
75
+
76
+ # Stretch only when a completion menu exists; upstream returns 0 when empty.
77
+ try:
78
+ from prompt_toolkit.application.current import get_app
79
+
80
+ complete_state = get_app().current_buffer.complete_state
81
+ except Exception:
82
+ complete_state = None
83
+
84
+ if not complete_state:
85
+ return 0
86
+ return max_available_width
87
+
88
+ cls.preferred_width = patched_preferred_width
89
+ setattr(cls, _PATCH_FLAG, True)
90
+
91
+
92
+ def _install_patch() -> None:
93
+ """Patch both single- and multi-column completion menu controls."""
94
+ from prompt_toolkit.layout.menus import (
95
+ CompletionsMenuControl,
96
+ MultiColumnCompletionMenuControl,
97
+ )
98
+
99
+ _patch_menu_class(CompletionsMenuControl)
100
+ _patch_menu_class(MultiColumnCompletionMenuControl)
101
+
102
+
103
+ def _on_startup() -> None:
104
+ try:
105
+ _install_patch()
106
+ except Exception as exc:
107
+ # Plugin rule #4: fail gracefully — never crash the app.
108
+ _emit_error(f"wide_completion_menu: failed to install patch — {exc}")
109
+
110
+
111
+ # /widemenu slash command
112
+ _USAGE = "Usage: /widemenu [on|off|toggle|status]"
113
+
114
+
115
+ def _custom_help() -> List[Tuple[str, str]]:
116
+ return [
117
+ (
118
+ _COMMAND_NAME,
119
+ "Toggle full-width completion menu (scrollbar pinned to screen edge)",
120
+ )
121
+ ]
122
+
123
+
124
+ def _handle_widemenu_command(command: str) -> bool:
125
+ # `command` is the full line, e.g. "/widemenu on". Strip the slash + name.
126
+ parts = command.strip().split()
127
+ arg = parts[1].lower() if len(parts) >= 2 else "status"
128
+
129
+ if arg in ("on", "enable", "true", "1"):
130
+ _state["enabled"] = True
131
+ _emit_info("🐶 widemenu: ON — scrollbar pinned to right edge of screen.")
132
+ elif arg in ("off", "disable", "false", "0"):
133
+ _state["enabled"] = False
134
+ _emit_info("🐶 widemenu: OFF — menu sized to content (default).")
135
+ elif arg in ("toggle", "t"):
136
+ _state["enabled"] = not _state["enabled"]
137
+ status = "ON" if _state["enabled"] else "OFF"
138
+ _emit_info(f"🐶 widemenu: {status}")
139
+ elif arg == "status":
140
+ status = "ON" if _state["enabled"] else "OFF"
141
+ _emit_info(f"🐶 widemenu is currently {status}. {_USAGE}")
142
+ else:
143
+ _emit_info(_USAGE)
144
+ return True
145
+
146
+
147
+ def _handle_custom_command(command: str, name: str):
148
+ if name != _COMMAND_NAME:
149
+ return None
150
+ return _handle_widemenu_command(command)
151
+
152
+
153
+ # Registration
154
+ register_callback("startup", _on_startup)
155
+ register_callback("custom_command", _handle_custom_command)
156
+ register_callback("custom_command_help", _custom_help)
157
+
158
+
159
+ __all__ = [
160
+ "_handle_custom_command",
161
+ "_handle_widemenu_command",
162
+ "_install_patch",
163
+ "_on_startup",
164
+ "_patch_menu_class",
165
+ ]
@@ -0,0 +1 @@
1
+ """Wiggum looping plugin."""
@@ -0,0 +1,91 @@
1
+ """Durable records for resumable ``/goal`` runs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import os
7
+ import uuid
8
+ from dataclasses import asdict, dataclass
9
+ from pathlib import Path
10
+
11
+ from code_puppy.config import STATE_DIR
12
+
13
+ _RUNS_DIR = Path(STATE_DIR) / "goal_runs"
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class GoalRun:
18
+ """The minimum state required to continue an interrupted goal."""
19
+
20
+ run_id: str
21
+ prompt: str
22
+ loop_count: int = 0
23
+ remediation_notes: str | None = None
24
+ status: str = "active"
25
+
26
+
27
+ def create(prompt: str) -> GoalRun:
28
+ """Create and persist a new goal run."""
29
+ run = GoalRun(run_id=str(uuid.uuid4()), prompt=prompt)
30
+ save(run)
31
+ return run
32
+
33
+
34
+ def save(run: GoalRun) -> None:
35
+ """Atomically persist a goal run."""
36
+ _RUNS_DIR.mkdir(parents=True, exist_ok=True)
37
+ destination = _path(run.run_id)
38
+ temporary = destination.with_suffix(f".tmp-{os.getpid()}")
39
+ temporary.write_text(json.dumps(asdict(run), indent=2), encoding="utf-8")
40
+ temporary.replace(destination)
41
+
42
+
43
+ def load(run_id: str) -> GoalRun | None:
44
+ """Load a run by UUID, returning ``None`` for invalid or missing IDs."""
45
+ normalized = _normalize_uuid(run_id)
46
+ if normalized is None:
47
+ return None
48
+ try:
49
+ payload = json.loads(_path(normalized).read_text(encoding="utf-8"))
50
+ return GoalRun(
51
+ run_id=normalized,
52
+ prompt=str(payload["prompt"]),
53
+ loop_count=max(0, int(payload.get("loop_count", 0))),
54
+ remediation_notes=payload.get("remediation_notes"),
55
+ status=str(payload.get("status", "active")),
56
+ )
57
+ except (OSError, ValueError, TypeError, KeyError, json.JSONDecodeError):
58
+ return None
59
+
60
+
61
+ def update(
62
+ run_id: str,
63
+ *,
64
+ loop_count: int,
65
+ remediation_notes: str | None,
66
+ status: str = "active",
67
+ ) -> None:
68
+ """Update mutable progress fields when the run still exists."""
69
+ run = load(run_id)
70
+ if run is None:
71
+ return
72
+ save(
73
+ GoalRun(
74
+ run_id=run.run_id,
75
+ prompt=run.prompt,
76
+ loop_count=loop_count,
77
+ remediation_notes=remediation_notes,
78
+ status=status,
79
+ )
80
+ )
81
+
82
+
83
+ def _path(run_id: str) -> Path:
84
+ return _RUNS_DIR / f"{run_id}.json"
85
+
86
+
87
+ def _normalize_uuid(value: str) -> str | None:
88
+ try:
89
+ return str(uuid.UUID(value.strip()))
90
+ except (AttributeError, ValueError):
91
+ return None
@@ -0,0 +1,299 @@
1
+ """LLM judge helpers for goal mode.
2
+
3
+ A judge is a small, read-only pydantic_ai Agent that examines the
4
+ implementor's latest response (and optionally its message history) and
5
+ returns a structured verdict: complete/not + remediation notes.
6
+
7
+ Each judge has its own model and prompt — see ``judge_config.py`` for
8
+ persistence. The /goal loop fans these out in parallel; see
9
+ ``register_callbacks._run_goal_judges``.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import asyncio
15
+ import json
16
+ from dataclasses import dataclass
17
+ from typing import Any
18
+
19
+ from pydantic import BaseModel, Field
20
+ from pydantic_ai import Agent, RunContext, ToolOutput, UsageLimits
21
+
22
+ from code_puppy.agents._history import stringify_part
23
+ from code_puppy.agents.agent_manager import load_agent
24
+ from code_puppy.model_factory import ModelFactory, make_model_settings
25
+ from code_puppy.model_utils import prepare_prompt_for_model
26
+ from code_puppy.tools.subagent_context import subagent_context
27
+
28
+ from .judge_config import DEFAULT_JUDGE_PROMPT, JudgeConfig
29
+
30
+ # Read-only judges should not need 200 requests; cap verification-heavy loops
31
+ # without letting a runaway judge consume the goal loop's budget.
32
+ GOAL_JUDGE_REQUEST_LIMIT = 200
33
+
34
+ _READ_ONLY_TOOLS = {
35
+ "list_files",
36
+ "read_file",
37
+ "grep",
38
+ "agent_run_shell_command",
39
+ "load_image_for_analysis",
40
+ "list_agents",
41
+ "invoke_agent",
42
+ }
43
+
44
+
45
+ class GoalJudgeOutput(BaseModel):
46
+ """Structured verdict from a goal judge."""
47
+
48
+ complete: bool = Field(
49
+ description="True only when the goal is verifiably complete."
50
+ )
51
+ notes: str = Field(
52
+ description="Brief rationale plus remediation notes if incomplete."
53
+ )
54
+
55
+
56
+ @dataclass(frozen=True)
57
+ class GoalJudgement:
58
+ """Final, normalized verdict surfaced to /goal callers.
59
+
60
+ ``abstained`` means the judge couldn't produce a verdict for an
61
+ infrastructure reason — model endpoint 404, auth failure, network
62
+ timeout, misconfigured model, etc. Abstaining judges are excluded
63
+ from the all-complete tally; they neither pass nor fail the goal.
64
+ """
65
+
66
+ judge_name: str
67
+ complete: bool
68
+ notes: str
69
+ raw_response: str
70
+ abstained: bool = False
71
+
72
+
73
+ def _read_only_tools_for_implementor(agent_config: Any) -> list[str]:
74
+ return [
75
+ tool for tool in agent_config.get_available_tools() if tool in _READ_ONLY_TOOLS
76
+ ]
77
+
78
+
79
+ def _format_message(message: Any, index: int) -> str:
80
+ part_lines = [stringify_part(part) for part in getattr(message, "parts", [])]
81
+ text = "\n".join(line for line in part_lines if line)
82
+ return f"[{index}] {message.__class__.__name__}:\n{text or '(empty message)'}"
83
+
84
+
85
+ def _format_history_window(
86
+ messages: list[Any],
87
+ *,
88
+ query: str | None = None,
89
+ limit: int = 20,
90
+ max_chars: int = 12000,
91
+ ) -> str:
92
+ if not messages:
93
+ return "(no implementor message history captured)"
94
+
95
+ normalized_query = (query or "").strip().lower()
96
+ indexed = list(enumerate(messages))
97
+ if normalized_query:
98
+ indexed = [
99
+ (idx, msg)
100
+ for idx, msg in indexed
101
+ if normalized_query
102
+ in "\n".join(
103
+ stringify_part(part) for part in getattr(msg, "parts", [])
104
+ ).lower()
105
+ ]
106
+
107
+ selected = indexed[-max(1, min(limit, 100)) :]
108
+ chunks: list[str] = []
109
+ total = 0
110
+ for idx, message in selected:
111
+ block = _format_message(message, idx)
112
+ if total + len(block) > max_chars:
113
+ remaining = max_chars - total
114
+ if remaining > 500:
115
+ chunks.append(block[:remaining])
116
+ break
117
+ chunks.append(block)
118
+ total += len(block)
119
+
120
+ if not chunks:
121
+ return "(no matching implementor history messages)"
122
+ return "\n\n---\n\n".join(chunks)
123
+
124
+
125
+ def _register_goal_history_tool(judge_agent: Agent, messages: list[Any]) -> None:
126
+ @judge_agent.tool
127
+ async def inspect_goal_history(
128
+ context: RunContext[None],
129
+ query: str | None = None,
130
+ limit: int = 20,
131
+ ) -> str:
132
+ """Inspect the /goal implementor's read-only message history.
133
+
134
+ Args:
135
+ query: Optional case-insensitive substring to search for in message parts.
136
+ limit: Maximum number of recent matching messages to return, capped at 100.
137
+ """
138
+ del context
139
+ return _format_history_window(messages, query=query, limit=limit)
140
+
141
+
142
+ def _strip_thinking_settings(model_settings: dict) -> None:
143
+ """Remove thinking-related settings that conflict with ToolOutput.
144
+
145
+ Anthropic models reject thinking + tool output at the same time, and other
146
+ providers don't mind missing keys. We strip:
147
+ * `anthropic_thinking` (Anthropic / Bedrock / Azure Foundry Claude / claude_code)
148
+ * `thinking` (GLM-4.7 / GLM-5 style)
149
+ * `thinking_enabled` / `thinking_level` (Gemini)
150
+ * `extra_body.output_config` (effort knob that only matters with adaptive thinking)
151
+ """
152
+ for key in ("anthropic_thinking", "thinking", "thinking_enabled", "thinking_level"):
153
+ model_settings.pop(key, None)
154
+
155
+ extra_body = model_settings.get("extra_body")
156
+ if isinstance(extra_body, dict):
157
+ extra_body.pop("output_config", None)
158
+ if not extra_body:
159
+ model_settings.pop("extra_body", None)
160
+
161
+
162
+ def _judge_user_prompt(
163
+ goal: str,
164
+ response: str | None,
165
+ error: BaseException | None,
166
+ ) -> str:
167
+ error_text = f"\nRUN ERROR:\n{error}\n" if error else ""
168
+ response_text = response or "(no response captured)"
169
+ return f"""\
170
+ Judge whether this coding goal is verifiably complete.
171
+
172
+ GOAL:
173
+ {goal}
174
+
175
+ LATEST AGENT RESPONSE:
176
+ {response_text}
177
+ {error_text}
178
+ You have a read-only `inspect_goal_history` tool for the /goal implementor's transcript.
179
+ Use it when the latest response is not enough to confidently judge completion.
180
+ """
181
+
182
+
183
+ async def judge_goal(
184
+ *,
185
+ judge_config: JudgeConfig,
186
+ implementor_agent: Any,
187
+ goal: str,
188
+ response: str | None,
189
+ error: BaseException | None,
190
+ history: list[Any] | None = None,
191
+ ) -> GoalJudgement:
192
+ """Run a single fresh, read-only judge against the implementor's latest turn.
193
+
194
+ Args:
195
+ judge_config: The judge's persisted configuration (name, model, prompt).
196
+ implementor_agent: The /goal implementor's agent — used only to discover
197
+ which read-only tools should be available to the judge.
198
+ goal: The original /goal prompt.
199
+ response: The implementor's most recent textual response (or None).
200
+ error: Any exception raised on the implementor's latest turn.
201
+ history: The implementor's message history (read-only).
202
+ """
203
+ from code_puppy import plugins
204
+
205
+ plugins.load_plugin_callbacks()
206
+
207
+ model_name = judge_config.model
208
+ models_config = ModelFactory.load_config()
209
+ if model_name not in models_config:
210
+ # Misconfigured model is an infrastructure issue, not a real
211
+ # judgement — abstain so we don't block /goal on it.
212
+ return GoalJudgement(
213
+ judge_name=judge_config.name,
214
+ complete=False,
215
+ notes=(f"model {model_name!r} not present in the model config"),
216
+ raw_response="",
217
+ abstained=True,
218
+ )
219
+
220
+ model = ModelFactory.get_model(model_name, models_config)
221
+ judge_instructions = judge_config.prompt or DEFAULT_JUDGE_PROMPT
222
+ user_prompt = _judge_user_prompt(goal, response, error)
223
+ prepared = prepare_prompt_for_model(
224
+ model_name,
225
+ judge_instructions,
226
+ user_prompt,
227
+ prepend_system_to_user=True,
228
+ )
229
+
230
+ model_settings = make_model_settings(model_name)
231
+ _strip_thinking_settings(model_settings)
232
+
233
+ judge_agent = Agent(
234
+ model=model,
235
+ instructions=prepared.instructions,
236
+ output_type=ToolOutput(
237
+ GoalJudgeOutput,
238
+ name="goal_judgement",
239
+ description="Verdict for the /goal implementor's latest iteration.",
240
+ ),
241
+ retries=3,
242
+ model_settings=model_settings,
243
+ )
244
+
245
+ # Give the judge the same read-only tools the implementor has, so it can
246
+ # poke at files/run tests/etc to verify completion.
247
+ from code_puppy.tools import register_tools_for_agent
248
+
249
+ try:
250
+ implementor_config = load_agent(implementor_agent.name)
251
+ read_only_tools = _read_only_tools_for_implementor(implementor_config)
252
+ except Exception:
253
+ read_only_tools = []
254
+
255
+ register_tools_for_agent(
256
+ judge_agent,
257
+ read_only_tools,
258
+ model_name=model_name,
259
+ )
260
+ _register_goal_history_tool(judge_agent, list(history or []))
261
+
262
+ # Run judges as sub-agents to suppress tool/reasoning chatter; rich_renderer
263
+ # and tools/display already skip those banners in sub-agent context.
264
+ try:
265
+ with subagent_context(f"judge:{judge_config.name}"):
266
+ result = await judge_agent.run(
267
+ prepared.user_prompt,
268
+ usage_limits=UsageLimits(request_limit=GOAL_JUDGE_REQUEST_LIMIT),
269
+ )
270
+ output = result.output
271
+ except (asyncio.CancelledError, KeyboardInterrupt):
272
+ # Propagate cancellation — the orchestrator handles cleanup.
273
+ raise
274
+ except Exception as exc:
275
+ # Infrastructure errors abstain rather than vote; the judge produced no
276
+ # verdict to fail the goal.
277
+ return GoalJudgement(
278
+ judge_name=judge_config.name,
279
+ complete=False,
280
+ notes=f"endpoint error ({type(exc).__name__}): {exc}",
281
+ raw_response="",
282
+ abstained=True,
283
+ )
284
+
285
+ if hasattr(output, "model_dump_json"):
286
+ raw = output.model_dump_json()
287
+ complete = output.complete
288
+ notes = output.notes
289
+ else:
290
+ raw = json.dumps(output)
291
+ complete = bool(output.get("complete"))
292
+ notes = str(output.get("notes", ""))
293
+
294
+ return GoalJudgement(
295
+ judge_name=judge_config.name,
296
+ complete=complete,
297
+ notes=notes,
298
+ raw_response=raw,
299
+ )