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,155 @@
1
+ # Agent & Tool System
2
+
3
+ > Part of the `code-puppy-agent` skill. Read this when you need to
4
+ > understand how agents are structured/discovered, or how tools get
5
+ > registered and wired to an agent. See `SKILL.md` for the overview and
6
+ > the full reference map.
7
+
8
+ ---
9
+
10
+ ## Agent System
11
+
12
+ ### BaseAgent (`agents/base_agent.py`)
13
+
14
+ All agents inherit from `BaseAgent` (ABC). Key interface:
15
+
16
+ | Member | Purpose |
17
+ |--------|---------|
18
+ | `name` (abstract property) | Stable machine identifier, e.g. `"code-puppy"` |
19
+ | `display_name` (abstract property) | Human name with emoji |
20
+ | `description` (abstract property) | One-line summary |
21
+ | `get_system_prompt()` (abstract) | The authored system prompt (identity is appended separately at runtime) |
22
+ | `get_available_tools()` (abstract) | List of tool-name strings from `TOOL_REGISTRY` |
23
+ | `get_model_name()` | Effective model: runtime override > pinned > global |
24
+ | `get_full_system_prompt()` | Authored prompt + `load_prompt` plugin fragments + identity ID |
25
+
26
+ `BaseAgent` is a **thin conductor**. Real logic lives in sibling modules:
27
+ - `_builder.py` — builds the pydantic-ai `Agent`, wires MCP toolsets
28
+ - `_runtime.py` — `run_with_mcp()` orchestration, cancellation, retries
29
+ - `_history.py` — token estimation, hashing, orphan pruning
30
+ - `_compaction.py` — summarization/truncation when context overflows
31
+
32
+ ### Agent Types
33
+
34
+ **Python agents** — classes in `agents/` discovered automatically by
35
+ `agent_manager._discover_agents()` via `pkgutil.iter_modules`. Any
36
+ `BaseAgent` subclass (excluding `JSONAgent` itself) in a non-underscore
37
+ module gets registered.
38
+
39
+ **JSON agents** — `JSONAgent` loads from `~/.code_puppy/agents/*.json`
40
+ (user) and `<CWD>/.code_puppy/agents/*.json` (project). Project overrides
41
+ user on name collision. Required fields: `name`, `description`,
42
+ `system_prompt`, `tools`. Optional: `display_name`, `user_prompt`,
43
+ `tools_config`, `model`, `mcp_servers`.
44
+
45
+ **Plugin agents** — registered via the `register_agents` callback, which
46
+ returns `[{"name": "...", "class": SomeAgentClass}]` (or
47
+ `{"name": ..., "json_path": ".../agent.json"}`).
48
+
49
+ **Discovery & precedence** — `_discover_agents()` runs three phases:
50
+
51
+ 1. Builtin Python classes (`pkgutil` scan of `agents/`).
52
+ 2. JSON agents via `discover_json_agents()`: the **user** dir is scanned
53
+ first, then the **project** dir overwrites it on collision, so **project
54
+ wins over user**. Both are skipped if a builtin Python agent already owns
55
+ the name (builtin beats JSON).
56
+ 3. Plugin-registered agents via `on_register_agents()` — these overwrite
57
+ `_AGENT_REGISTRY` **unconditionally**, so a plugin agent can shadow a
58
+ builtin. Register under a unique name.
59
+
60
+ Net precedence: **builtin Python > JSON project > JSON user**; plugin
61
+ agents are last-writer-wins (handled after the others, no collision guard).
62
+
63
+ ### Agent Manager (`agents/agent_manager.py`)
64
+
65
+ - `get_current_agent()` — returns the active `BaseAgent` instance
66
+ - `set_current_agent(name)` — switches agent, preserves history
67
+ - `get_available_agents()` — dict of `name → display_name`
68
+ - `clone_agent()` — creates a copy of the current agent
69
+
70
+ Agent selection persists per **terminal session** (keyed by PPID) in
71
+ `terminal_sessions.json` so different terminals can run different agents.
72
+
73
+ ---
74
+
75
+ ## Tool System
76
+
77
+ ### TOOL_REGISTRY (`tools/__init__.py`)
78
+
79
+ A flat dict mapping tool-name strings to registration functions:
80
+
81
+ ```python
82
+ TOOL_REGISTRY = {
83
+ "read_file": register_read_file,
84
+ "create_file": register_create_file,
85
+ "replace_in_file": register_replace_in_file,
86
+ # ... 60+ tools
87
+ }
88
+ ```
89
+
90
+ Each `register_*` function takes a pydantic-ai `agent` and calls
91
+ `@agent.tool` to wire the tool's JSON schema.
92
+
93
+ ### How tools are assigned
94
+
95
+ `register_tools_for_agent(agent, tool_names, agent_name=...)` is called
96
+ during agent build. It:
97
+
98
+ 1. Loads plugin-registered tools via `on_register_tools()` → merges into `TOOL_REGISTRY`
99
+ 2. Merges plugin-advertised tools via `on_register_agent_tools(agent_name)` → unions into the requested list
100
+ 3. Expands compound tools (e.g. `"edit_file"` → `["create_file", "replace_in_file", "delete_snippet"]`)
101
+ 4. Registers each tool by calling its `register_func(agent)`
102
+
103
+ ### Built-in tool categories
104
+
105
+ | Category | Tools |
106
+ |----------|-------|
107
+ | **File ops** | `list_files`, `read_file`, `grep` |
108
+ | **File mods** | `create_file`, `replace_in_file`, `delete_snippet`, `delete_file` |
109
+ | **Shell** | `agent_run_shell_command`, `agent_share_your_reasoning` |
110
+ | **Sub-agents** | `list_agents`, `invoke_agent`, `invoke_agent_with_model` |
111
+ | **Skills** | `activate_skill`, `list_or_search_skills` |
112
+ | **User** | `ask_user_question`, `load_image_for_analysis` |
113
+ | **Browser** | 30+ `browser_*` tools (Playwright-backed) |
114
+ | **Models** | `list_available_models` |
115
+ | **UC** | `universal_constructor` (dynamic tool factory) |
116
+
117
+ ### Plugin tools: two hooks, both required
118
+
119
+ ```python
120
+ # 1. Define the tool (adds to TOOL_REGISTRY)
121
+ def _register_tools():
122
+ return [{"name": "my_tool", "register_func": register_my_tool}]
123
+ register_callback("register_tools", _register_tools)
124
+
125
+ # 2. Advertise it to agents (adds to agent's tool list)
126
+ def _advertise(agent_name=None):
127
+ return ["my_tool"]
128
+ register_callback("register_agent_tools", _advertise)
129
+ ```
130
+
131
+ Step 1 makes the tool *exist*; step 2 makes agents *see* it. Both are
132
+ needed. `namespace_skill_search` (`code_puppy/plugins/namespace_skill_search/`)
133
+ is a small, complete example of this pattern for a single tool
134
+ (`browse_skill_namespace`) — see `SKILLS_SYSTEM.md` for what it does and
135
+ `PLUGINS_AND_CALLBACKS.md` for the callback-safety reasoning behind how
136
+ it's wired.
137
+
138
+ ### Async tool functions and blocking I/O
139
+
140
+ Tool functions taking a `RunContext` (`activate_skill`,
141
+ `list_or_search_skills`, `browse_skill_namespace`) are conventionally
142
+ `async def` in this codebase. That matters for one non-obvious reason:
143
+ pydantic-ai only auto-offloads **synchronous** tool functions to a worker
144
+ thread (via `anyio.to_thread`); an `async def` tool runs directly on the
145
+ event loop. If your async tool does blocking filesystem/network I/O
146
+ (e.g. scanning a large directory tree), wrap the blocking call
147
+ explicitly:
148
+
149
+ ```python
150
+ result = await asyncio.to_thread(blocking_function, *args)
151
+ ```
152
+
153
+ `namespace_skill_search/search_tool.py` does exactly this around its
154
+ `build_namespaces()` call — a good reference implementation if you're
155
+ writing a new async tool with real I/O in it.
@@ -0,0 +1,104 @@
1
+ # Model System & MCP Integration
2
+
3
+ > Part of the `code-puppy-agent` skill. Read this when working with model
4
+ > selection/config, or external MCP tool servers. See `SKILL.md` for the
5
+ > overview and the full reference map.
6
+
7
+ ---
8
+
9
+ ## Model System
10
+
11
+ ### ModelFactory (`model_factory.py`)
12
+
13
+ Resolves a model-name string into a pydantic-ai `Model` object.
14
+ Supports providers: OpenAI, Anthropic, Gemini, Cerebras, OpenRouter,
15
+ Azure, and custom OpenAI/Anthropic/Gemini-compatible endpoints.
16
+
17
+ ### Model configuration
18
+
19
+ Models are defined in three places (merged at runtime):
20
+
21
+ 1. **Built-in defaults** — hardcoded in the factory
22
+ 2. **`~/.code_puppy/extra_models.json`** — user-defined custom models
23
+ 3. **Plugin injection** — `load_models_config` callback returns a dict
24
+
25
+ Example `extra_models.json`:
26
+ ```json
27
+ {
28
+ "my-model": {
29
+ "type": "custom_openai",
30
+ "name": "gpt-4o",
31
+ "custom_endpoint": {
32
+ "url": "https://api.example.com/v1",
33
+ "api_key": "$MY_API_KEY"
34
+ },
35
+ "context_length": 128000
36
+ }
37
+ }
38
+ ```
39
+
40
+ ### Model types
41
+
42
+ | Type | Provider |
43
+ |------|----------|
44
+ | `openai` / `openai_responses` | OpenAI |
45
+ | `anthropic` | Anthropic (Claude) |
46
+ | `gemini` | Google Gemini |
47
+ | `cerebras` | Cerebras (via CerebrasProvider) |
48
+ | `custom_openai` | Any OpenAI-compatible endpoint |
49
+ | `custom_anthropic` | Anthropic-compatible endpoint |
50
+ | `round_robin` | Cycle through N models (rate-limit mitigation) |
51
+ | Plugin types | Registered via `register_model_type` callback |
52
+
53
+ ### Model selection precedence
54
+
55
+ For any agent: **runtime override > agent-pinned model > agent's `model`
56
+ field (JSON agents) > global model name**.
57
+
58
+ The global model is set via `/model` and stored in config.
59
+
60
+ ---
61
+
62
+ ## MCP Integration
63
+
64
+ ### MCP Manager (`mcp_/manager.py`)
65
+
66
+ Code Puppy manages external MCP (Model Context Protocol) servers that
67
+ provide additional tools to agents. Key components:
68
+
69
+ - **Registry** (`mcp_/registry.py`) — server definitions (stdio/SSE/streamable-http)
70
+ - **Manager** (`mcp_/manager.py`) — lifecycle: start, stop, health checks
71
+ - **Agent bindings** (`mcp_/agent_bindings.py`) — which agents get which servers
72
+ - **Circuit breaker** (`mcp_/circuit_breaker.py`) — auto-disables flaky servers
73
+
74
+ ### How MCP servers attach to agents
75
+
76
+ Servers can be:
77
+ 1. **Globally started** — available to all agents
78
+ 2. **Agent-bound** — declared in a JSON agent's `mcp_servers` field, or
79
+ bound via the `/mcp bind` menu
80
+ 3. **Auto-started** — bound servers with `auto_start: true` start when the
81
+ agent runs
82
+
83
+ The `pre_mcp_autostart` hook fires before auto-start, letting plugins
84
+ refresh tokens or mint credentials.
85
+
86
+ ### Managing MCP servers
87
+
88
+ Use `/mcp` in the TUI:
89
+ - `/mcp list` — show configured servers
90
+ - `/mcp start <name>` / `/mcp stop <name>`
91
+ - `/mcp status` — health dashboard
92
+ - `/mcp bind` — attach servers to agents
93
+
94
+ ### MCP servers as skill providers — a known gap, not yet implemented
95
+
96
+ Skills today are discovered only by filesystem scan (see
97
+ `SKILLS_SYSTEM.md`) or via the `register_skills` callback. There is
98
+ currently **no** mechanism for a bound MCP server to advertise skills of
99
+ its own (e.g. a hypothetical `skill_provider` capability exposing
100
+ `list_skills`/`get_skill`/`search_skills`) — skills served that way would
101
+ just look like ordinary tool results, not first-class skills appearing in
102
+ `/skills list` or `activate_skill`-able. If you're evaluating whether to
103
+ build this, that's new platform work, not something `namespace_skill_search`
104
+ or the existing skill-discovery code already covers.
@@ -0,0 +1,147 @@
1
+ # Plugin & Callback System
2
+
3
+ > Part of the `code-puppy-agent` skill. Read this before writing a new
4
+ > plugin, or when debugging why a hook isn't firing / is being
5
+ > overwritten. See `SKILL.md` for the overview and the full reference map.
6
+
7
+ ---
8
+
9
+ ## Plugin discovery (three tiers)
10
+
11
+ | Tier | Location | Load order |
12
+ |------|----------|------------|
13
+ | **Builtin** | `code_puppy/plugins/<name>/register_callbacks.py` | 1st |
14
+ | **User** | `~/.code_puppy/plugins/<name>/register_callbacks.py` | 2nd |
15
+ | **Project** | `<CWD>/.code_puppy/plugins/<name>/register_callbacks.py` | 3rd (highest precedence) |
16
+
17
+ Each plugin is a directory containing `register_callbacks.py`. The loader
18
+ auto-discovers it. Project plugins shadow user plugins on name collision.
19
+
20
+ ## The callback hook system
21
+
22
+ `register_callback(phase, func)` at module scope. The callback engine
23
+ (`callbacks.py`) stores functions per phase and fires them at the right
24
+ time. All hooks accept sync or async functions.
25
+
26
+ **Most important hooks for extending Code Puppy:**
27
+
28
+ | Hook | When | Return value |
29
+ |------|------|-------------|
30
+ | `startup` | Once, at process start | (no return value used) — do one-time setup/migrations here, NOT at module import time (see below) |
31
+ | `register_tools` | Tool registration | `list[dict]` with `name`, `register_func` |
32
+ | `register_agent_tools` | Per-agent tool advertisement | `list[str]` of tool names |
33
+ | `register_skills` | Skill catalogue | `list[dict]` with `name` + `skill_md`/`skill_md_path`/`frontmatter`+`body` |
34
+ | `register_agents` | Agent catalogue | `list[dict]` with `name`, `class` |
35
+ | `load_prompt` | System prompt assembly | `str` fragment or `None` |
36
+ | `get_model_system_prompt` | Per-model prompt patch | `dict` with `instructions`/`handled` or `None` |
37
+ | `custom_command` | Unknown `/slash` command | `True` (handled), `str` (message), or `None` (not mine) |
38
+ | `pre_tool_call` | Before tool executes | Can modify args |
39
+ | `post_tool_call` | After tool finishes | Observes result + duration |
40
+ | `run_shell_command` | Before shell exec | Return `{"blocked": True}` to block |
41
+ | `file_permission` | Before file op | `bool` — allow/deny |
42
+ | `agent_run_start` / `agent_run_end` | Agent lifecycle | Observes name, model, session |
43
+
44
+ The full list is in `callbacks.py` — `PhaseType` has ~45 phases.
45
+
46
+ ## Minimal plugin example
47
+
48
+ ```
49
+ my_plugin/
50
+ __init__.py # (can be empty)
51
+ register_callbacks.py
52
+ ```
53
+
54
+ ```python
55
+ from code_puppy.callbacks import register_callback
56
+
57
+ def _on_load_prompt():
58
+ return "\n## Project Rules\nAlways use type hints."
59
+
60
+ register_callback("load_prompt", _on_load_prompt)
61
+ ```
62
+
63
+ That's it. The loader handles discovery, import, and registration.
64
+
65
+ ---
66
+
67
+ ## Two gotchas that will bite you, both discovered building `namespace_skill_search`
68
+
69
+ `namespace_skill_search` (`code_puppy/plugins/namespace_skill_search/`)
70
+ groups skills into namespaces and replaces the flat per-skill list in the
71
+ system prompt with a compact directory + a `browse_skill_namespace` tool
72
+ (see `SKILLS_SYSTEM.md` for what it does from a user's perspective). It's
73
+ also a good reference implementation for two hook-system pitfalls that
74
+ are easy to hit and don't fail loudly when you do:
75
+
76
+ ### 1. `get_model_system_prompt` is last-write-wins, not additive
77
+
78
+ If two plugins register a `get_model_system_prompt` callback, the second
79
+ one processed can silently overwrite the first one's `instructions` —
80
+ `model_utils.prepare_prompt_for_model` threads augmenter results through
81
+ sequentially, and whichever callback runs last on a given key wins. This
82
+ is *not* a merge; the built-in `agent_skills` plugin's own contribution
83
+ (the flat skill list) can be clobbered by a badly-timed second callback
84
+ on the same phase.
85
+
86
+ **If you need to add content to the system prompt, use `load_prompt`
87
+ instead whenever possible.** `load_prompt` fragments from every plugin
88
+ are simply newline-joined by `base_agent.py::get_full_system_prompt` —
89
+ there's no merge conflict possible, by construction. This is exactly why
90
+ `namespace_skill_search` injects its namespace directory via
91
+ `load_prompt` and explicitly avoids `get_model_system_prompt`, even
92
+ though the content it's replacing (the flat skill list) is itself
93
+ injected through `get_model_system_prompt`.
94
+
95
+ ### 2. Don't mutate config (or do any other real work) at import time
96
+
97
+ A plugin's `register_callbacks.py` module body runs once, at import —
98
+ which happens during every plugin scan, including in test collection.
99
+ Anything at module scope that does real work (writes to
100
+ `~/.code_puppy/puppy.cfg`, hits the filesystem, calls out to a network)
101
+ is:
102
+
103
+ - **Hard to test** — you'd need `importlib.reload()` gymnastics to
104
+ exercise it in isolation, and reloading re-runs *every* top-level
105
+ statement in the module, not just the one you wanted to test.
106
+ - **Not observable** — it just happens silently whenever the module
107
+ happens to get imported, with no log line tied to a specific lifecycle
108
+ event.
109
+ - **A pattern already solved by the `startup` callback.** See
110
+ `code_puppy/plugins/theme/register_callbacks.py`'s
111
+ `_apply_default_theme_on_first_run`, registered via
112
+ `register_callback("startup", _apply_default_theme_on_first_run)`.
113
+
114
+ `namespace_skill_search` follows this pattern for its one piece of real
115
+ setup work (turning off the built-in flat skill list the first time it
116
+ ever runs): the config mutation lives in a plain function,
117
+ `_maybe_disable_frontmatter()`, registered on `startup` — not executed
118
+ as a bare statement in the module body. That function is directly
119
+ callable and testable with mocked config, exactly like the theme
120
+ plugin's equivalent.
121
+
122
+ If you're doing a **one-time migration** (config flip, cache rebuild,
123
+ etc.), also consider a dedicated marker config key to record "this
124
+ plugin already ran its migration," independent of whatever value the
125
+ thing you migrated currently holds — otherwise you can't distinguish
126
+ "never ran yet" from "user changed it back after we ran." See
127
+ `_MIGRATION_MARKER_KEY` in `namespace_skill_search/register_callbacks.py`
128
+ for a worked example.
129
+
130
+ ---
131
+
132
+ ## Plugin structure convention
133
+
134
+ ```
135
+ my_plugin/
136
+ ├── __init__.py # docstring (can be minimal)
137
+ ├── register_callbacks.py # entry point: register_callback() calls
138
+ ├── helpers.py # optional: logic split out
139
+ └── README.md # optional: documentation
140
+ ```
141
+
142
+ For a plugin that also ships a builtin skill via `register_skills`
143
+ (rather than, or in addition to, tools/prompt fragments), see
144
+ `code_puppy/plugins/code_puppy_agent/` (this skill's own plugin) or
145
+ `namespace_skill_search`'s README for a fuller worked example of
146
+ justifying design decisions in-repo rather than only in a PR
147
+ description.
@@ -0,0 +1,39 @@
1
+ # Session & History System
2
+
3
+ > Part of the `code-puppy-agent` skill. Read this when debugging context
4
+ > window / compaction issues, or working with session save/load. See
5
+ > `SKILL.md` for the overview and the full reference map.
6
+
7
+ ---
8
+
9
+ ## Message history
10
+
11
+ Each `BaseAgent` maintains `_message_history` — a list of pydantic-ai
12
+ `ModelMessage` objects (alternating `ModelRequest`/`ModelResponse`).
13
+ History is the conversation context sent to the LLM on each turn.
14
+
15
+ ## Context window management
16
+
17
+ When the conversation grows too large:
18
+ 1. **Token estimation** (`_history.py`) — estimates tokens per message
19
+ 2. **Compaction** (`_compaction.py`) — summarizes older messages using a
20
+ dedicated summarization agent, preserving recent messages
21
+ 3. **Protected tokens** — the most recent N tokens are never compacted
22
+ (configurable via `protected_token_count`)
23
+
24
+ ## Session persistence
25
+
26
+ Sessions are saved as pickle files in the state directory:
27
+ - `session_storage.py` handles serialization
28
+ - `/save <name>` and `/load <name>` commands
29
+ - Auto-save on exit
30
+
31
+ ## Useful history commands
32
+
33
+ | Command | Effect |
34
+ |---------|--------|
35
+ | `/save <name>` | Save current session |
36
+ | `/load <name>` | Load a saved session |
37
+ | `/pop [N]` | Remove N most recent messages |
38
+ | `/truncate <N>` | Keep only N most recent messages |
39
+ | `/prune` | Interactive context pruning UI |
@@ -0,0 +1,180 @@
1
+ ---
2
+ name: code-puppy-agent
3
+ description: How Code Puppy itself is built — its internal architecture, structure, codebase layout, and source modules. Explains agents, tools, the plugin/callback hook system, models, MCP, sessions and history/context windows, skills (including skill namespaces for large catalogs), slash commands, config, messaging/UI, system-prompt assembly, and i18n. Activate for ANY question about how Code Puppy works internally, why it behaves a certain way, where something lives in the code, how a feature is implemented, or how to navigate, debug, or extend the codebase (add a tool, agent, plugin, command, skill, model, or MCP server).
4
+ version: "2.0"
5
+ author: code-puppy
6
+ tags:
7
+ - code-puppy
8
+ - architecture
9
+ - structure
10
+ - internals
11
+ - codebase
12
+ - source
13
+ - how-it-works
14
+ - self-awareness
15
+ - agents
16
+ - tools
17
+ - plugins
18
+ - hooks
19
+ - callbacks
20
+ - models
21
+ - mcp
22
+ - sessions
23
+ - history
24
+ - skills
25
+ - namespaces
26
+ - commands
27
+ - config
28
+ - messaging
29
+ - i18n
30
+ - extend
31
+ - debug
32
+ - reference
33
+ ---
34
+
35
+ # Code Puppy — Architecture & Internals
36
+
37
+ This skill is a **self-awareness document**. When activated it teaches the
38
+ LLM how Code Puppy is structured under the hood so it can navigate the
39
+ codebase, debug issues, and extend the product without guessing.
40
+
41
+ > **Philosophy:** Code Puppy is plugin-first. Nearly all new functionality
42
+ > should be a plugin under `code_puppy/plugins/` that hooks into core via
43
+ > `code_puppy/callbacks.py`. Don't edit `code_puppy/command_line/` or core
44
+ > agent files unless a hook genuinely doesn't exist.
45
+
46
+ This skill is split across multiple files so activating it doesn't force
47
+ the full ~30KB of internals into context on every use — this SKILL.md is
48
+ the index. **Read the reference file for the topic you actually need**;
49
+ each one is self-contained and cites real file paths so you can jump
50
+ straight to source. All reference files are plain repo paths under
51
+ `code_puppy/plugins/code_puppy_agent/` — read them with `read_file`.
52
+
53
+ ---
54
+
55
+ ## Layered Architecture
56
+
57
+ ```
58
+ ┌──────────────────────────────────────────────────┐
59
+ │ TUI / CLI (command_line/, tui/) │
60
+ │ user input → slash commands → agent dispatch │
61
+ ├──────────────────────────────────────────────────┤
62
+ │ Agent Layer (agents/) │
63
+ │ BaseAgent → system prompt, tools, history │
64
+ │ _builder, _runtime, _compaction, _history │
65
+ ├──────────────────────────────────────────────────┤
66
+ │ Tool Layer (tools/) │
67
+ │ TOOL_REGISTRY → register_tools_for_agent() │
68
+ ├──────────────────────────────────────────────────┤
69
+ │ Plugin Layer (plugins/, callbacks.py) │
70
+ │ register_callback("hook", fn) at import time │
71
+ ├──────────────────────────────────────────────────┤
72
+ │ Model Layer (model_factory.py, config.py) │
73
+ │ ModelFactory → pydantic-ai Model objects │
74
+ ├──────────────────────────────────────────────────┤
75
+ │ pydantic-ai (external) │
76
+ │ Agent.run(), streaming, tool schemas │
77
+ └──────────────────────────────────────────────────┘
78
+ ```
79
+
80
+ The TUI collects user input. It delegates to the **agent manager** which
81
+ loads the current agent. The agent builds a pydantic-ai `Agent` with a
82
+ system prompt + tool set, then `run_with_mcp()` streams the LLM response.
83
+ Plugins hook into every stage via callbacks.
84
+
85
+ ---
86
+
87
+ ## Reference Map
88
+
89
+ | File | Read this for |
90
+ |------|----------------|
91
+ | `AGENTS_AND_TOOLS.md` | How agents are structured/discovered (Python, JSON, plugin agents, precedence). How tools get registered and wired to an agent. Async-tool blocking-I/O gotcha. |
92
+ | `PLUGINS_AND_CALLBACKS.md` | Plugin discovery tiers, the full callback hook table, a minimal plugin example, and **two hook-system gotchas** (`get_model_system_prompt` last-write-wins; don't do real work at import time) worth reading before writing any new plugin. |
93
+ | `MODELS_AND_MCP.md` | ModelFactory, model config precedence, model types. MCP server lifecycle, agent bindings, and a known gap (MCP servers can't yet provide skills). |
94
+ | `SESSIONS_AND_HISTORY.md` | Message history, context-window compaction, session save/load commands. |
95
+ | `SKILLS_SYSTEM.md` | Skill discovery/activation, bundled-resource-file gotcha for plugin-registered skills, and **skill namespaces** — how `namespace_skill_search` groups large skill catalogs and replaces the flat prompt list. |
96
+ | `SYSTEM_PROMPT_CONFIG_AND_I18N.md` | Exact system-prompt assembly order (which layer skills/rules/patches land in), `puppy.cfg` + key directories, the messaging bus, and an i18n quick-reference (full guide: `docs/I18N.md`). |
97
+
98
+ Don't guess which file has what you need — the table above is exhaustive
99
+ for this skill's scope. If a question doesn't map cleanly to one row, it's
100
+ probably answered by combining two (e.g. "why did my plugin's prompt
101
+ addition get silently dropped" is a `PLUGINS_AND_CALLBACKS.md` +
102
+ `SYSTEM_PROMPT_CONFIG_AND_I18N.md` question).
103
+
104
+ ---
105
+
106
+ ## Development Conventions
107
+
108
+ ### Golden rules
109
+
110
+ 1. **Plugins over core** — if a callback hook exists, use it. Don't edit
111
+ `command_line/` or core agent files.
112
+ 2. **One `register_callbacks.py` per plugin** — register at module scope.
113
+ 3. **600-line hard cap** per file — split into submodules. (This very
114
+ skill was split for exactly this reason — it was 632 lines as one file.)
115
+ 4. **Fail gracefully** — plugins must never crash the app. Wrap external
116
+ calls in try/except.
117
+ 5. **Return `None`** from hooks/commands you don't own.
118
+ 6. **Always run linters** — `ruff check --fix`, `ruff format .`
119
+ 7. **Wrap user-facing strings** in `t()`/`ngettext` (see
120
+ `SYSTEM_PROMPT_CONFIG_AND_I18N.md`) — don't hardcode English display
121
+ text. Model-facing system prompt content is explicitly exempt.
122
+ 8. **Never allow a Claude co-author commit.**
123
+
124
+ ### Plugin structure
125
+
126
+ ```
127
+ my_plugin/
128
+ ├── __init__.py # docstring (can be minimal)
129
+ ├── register_callbacks.py # entry point: register_callback() calls
130
+ ├── helpers.py # optional: logic split out
131
+ └── README.md # optional: documentation
132
+ ```
133
+
134
+ ### Zen of Code Puppy
135
+
136
+ - Simple is better than complex.
137
+ - Flat is better than nested.
138
+ - If a hook exists for it, use it.
139
+ - Files should be readable in one sitting.
140
+ - The plugin system is the API surface; the core is the engine.
141
+
142
+ ---
143
+
144
+ ## Quick Reference: Key File Map
145
+
146
+ | File | Responsibility |
147
+ |------|---------------|
148
+ | `agents/base_agent.py` | Abstract agent base — thin conductor |
149
+ | `agents/_builder.py` | Builds pydantic-ai Agent + MCP wiring |
150
+ | `agents/_runtime.py` | `run_with_mcp()` — streaming, retries, cancellation |
151
+ | `agents/_compaction.py` | Context summarization |
152
+ | `agents/agent_manager.py` | Agent registry, switching, discovery |
153
+ | `agents/json_agent.py` | JSON-config agent loader |
154
+ | `tools/__init__.py` | `TOOL_REGISTRY`, `register_tools_for_agent()` |
155
+ | `plugins/__init__.py` | Plugin loader (builtin → user → project) |
156
+ | `callbacks.py` | Hook engine — 45+ phases |
157
+ | `config.py` | Config read/write, directories, model settings |
158
+ | `model_factory.py` | Model-name → pydantic-ai Model |
159
+ | `mcp_/manager.py` | MCP server lifecycle |
160
+ | `session_storage.py` | Session pickle save/load |
161
+ | `plugins/agent_skills/` | Skills discovery, activation, UI |
162
+ | `plugins/namespace_skill_search/` | Namespace grouping + on-demand browse tool for large skill catalogs |
163
+ | `i18n/` | Internationalization: catalogs, `t()`/`ngettext`, locale detection, formatting |
164
+ | `i18n/locales/*.json` | Message catalogs (source of truth: `en-US.json`) |
165
+ | `pydantic_patches.py` | Startup monkey-patches (clipboard fix, etc.) |
166
+
167
+ ---
168
+
169
+ ## When to use this skill
170
+
171
+ Activate this skill when you need to:
172
+ - Understand **how a feature works internally** before modifying it
173
+ - **Create a new plugin** and need to know which hooks to use
174
+ - **Debug** an agent, tool, model, skill, or MCP issue
175
+ - **Navigate the codebase** and need to find the right file
176
+ - **Extend Code Puppy** with custom tools, agents, skills, or commands
177
+
178
+ Then read the specific reference file(s) from the map above — don't try
179
+ to hold all six in context at once unless the question is genuinely
180
+ that broad.