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,337 @@
1
+ """Skill discovery - scans directories for valid skills."""
2
+
3
+ import logging
4
+ import shutil
5
+ import threading
6
+ from dataclasses import dataclass
7
+ from pathlib import Path
8
+ from typing import Any, Iterable, List, Optional
9
+
10
+ from code_puppy.callbacks import get_callbacks, on_register_skills
11
+ from code_puppy.config import CACHE_DIR
12
+ from code_puppy_core_plugins.agent_skills.config import get_skill_directories
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ _PLUGIN_SKILLS_CACHE_DIR = Path(CACHE_DIR) / "plugin-skills"
17
+
18
+ # Serialises the wipe-and-rebuild of the shared plugin-skills cache dir: called from
19
+ # both the main loop and worker threads (anyio to_thread), so without the lock two
20
+ # threads race -- one rmtree's it while the other mkdir's/writes (macOS: OSError 22).
21
+ _PLUGIN_SKILLS_LOCK = threading.Lock()
22
+
23
+ # Memoised last successful build, keyed by a signature of the (process-deterministic)
24
+ # registrations, so the cache dir is rebuilt only when they change. Also stops a rebuild
25
+ # from tearing the dir out from under lock-free readers of returned SkillInfo.path.
26
+ _plugin_skills_cache: Optional[List["SkillInfo"]] = None
27
+ _plugin_skills_signature: Optional[tuple] = None
28
+
29
+
30
+ @dataclass
31
+ class SkillInfo:
32
+ """Basic skill information from discovery."""
33
+
34
+ name: str
35
+ path: Path
36
+ has_skill_md: bool
37
+
38
+
39
+ # Global cache for discovered skills
40
+ _skill_cache: Optional[List[SkillInfo]] = None
41
+
42
+
43
+ def get_default_skill_directories() -> List[Path]:
44
+ """Return default directories to scan for skills.
45
+
46
+ Returns:
47
+ - ~/.code_puppy/skills (user skills)
48
+ - ./.code_puppy/skills (project config skills)
49
+ - ./skills (project skills)
50
+ """
51
+ return [
52
+ Path.home() / ".code_puppy" / "skills",
53
+ Path.cwd() / ".code_puppy" / "skills",
54
+ Path.cwd() / "skills",
55
+ ]
56
+
57
+
58
+ def is_valid_skill_directory(path: Path) -> bool:
59
+ """Check if a directory contains a valid SKILL.md file."""
60
+ if not path.is_dir():
61
+ return False
62
+
63
+ skill_md_path = path / "SKILL.md"
64
+ return skill_md_path.is_file()
65
+
66
+
67
+ def _sanitize_path_part(value: str) -> str:
68
+ cleaned = (value or "").strip().replace("/", "-").replace("\\", "-")
69
+ return cleaned or "unnamed"
70
+
71
+
72
+ def _render_skill_markdown(entry: dict[str, Any]) -> str:
73
+ if "skill_md" in entry:
74
+ return str(entry["skill_md"])
75
+
76
+ if "skill_md_path" in entry:
77
+ return Path(entry["skill_md_path"]).read_text(encoding="utf-8")
78
+
79
+ if "frontmatter" in entry and "body" in entry:
80
+ frontmatter = dict(entry["frontmatter"] or {})
81
+ frontmatter.setdefault("name", entry["name"])
82
+ if entry.get("description") and "description" not in frontmatter:
83
+ frontmatter["description"] = entry["description"]
84
+ if entry.get("version") and "version" not in frontmatter:
85
+ frontmatter["version"] = entry["version"]
86
+ if entry.get("author") and "author" not in frontmatter:
87
+ frontmatter["author"] = entry["author"]
88
+ if entry.get("tags") and "tags" not in frontmatter:
89
+ frontmatter["tags"] = entry["tags"]
90
+
91
+ lines = ["---"]
92
+ for key, value in frontmatter.items():
93
+ if isinstance(value, list):
94
+ lines.append(f"{key}:")
95
+ for item in value:
96
+ lines.append(f" - {item}")
97
+ else:
98
+ lines.append(f"{key}: {value}")
99
+ lines.extend(["---", str(entry["body"])])
100
+ return "\n".join(lines).rstrip() + "\n"
101
+
102
+ raise ValueError(
103
+ "Skill entry must define either skill_md_path, skill_md, or frontmatter+body"
104
+ )
105
+
106
+
107
+ def _copy_scripts_dir(source_dir: Path, target_dir: Path) -> None:
108
+ scripts_target = target_dir / "scripts"
109
+ if scripts_target.exists() or scripts_target.is_symlink():
110
+ if scripts_target.is_dir() and not scripts_target.is_symlink():
111
+ shutil.rmtree(scripts_target)
112
+ else:
113
+ scripts_target.unlink()
114
+
115
+ try:
116
+ scripts_target.symlink_to(source_dir, target_is_directory=True)
117
+ except OSError:
118
+ shutil.copytree(source_dir, scripts_target)
119
+
120
+
121
+ def _materialize_plugin_skill(
122
+ callback_module: str, callback_name: str, entry: dict[str, Any]
123
+ ) -> SkillInfo | None:
124
+ skill_name = str(entry.get("name") or "").strip()
125
+ if not skill_name:
126
+ logger.warning(
127
+ "Plugin skill registration from %s.%s missing required 'name'",
128
+ callback_module,
129
+ callback_name,
130
+ )
131
+ return None
132
+
133
+ try:
134
+ skill_md = _render_skill_markdown(entry)
135
+ except Exception as exc:
136
+ logger.warning(
137
+ "Failed to render plugin skill %s from %s.%s: %s",
138
+ skill_name,
139
+ callback_module,
140
+ callback_name,
141
+ exc,
142
+ )
143
+ return None
144
+
145
+ owner_dir = _PLUGIN_SKILLS_CACHE_DIR / _sanitize_path_part(callback_module)
146
+ skill_dir = owner_dir / _sanitize_path_part(skill_name)
147
+ skill_dir.mkdir(parents=True, exist_ok=True)
148
+ (skill_dir / "SKILL.md").write_text(skill_md, encoding="utf-8")
149
+
150
+ scripts_dir = entry.get("scripts_dir")
151
+ if scripts_dir:
152
+ source_dir = Path(scripts_dir).expanduser().resolve()
153
+ if source_dir.is_dir():
154
+ _copy_scripts_dir(source_dir, skill_dir)
155
+ else:
156
+ logger.warning(
157
+ "Plugin skill %s from %s.%s provided invalid scripts_dir: %s",
158
+ skill_name,
159
+ callback_module,
160
+ callback_name,
161
+ source_dir,
162
+ )
163
+
164
+ return SkillInfo(name=skill_name, path=skill_dir, has_skill_md=True)
165
+
166
+
167
+ def _iter_plugin_skill_registrations() -> Iterable[tuple[str, str, dict[str, Any]]]:
168
+ callbacks = get_callbacks("register_skills")
169
+ results = on_register_skills()
170
+
171
+ for callback, result in zip(callbacks, results):
172
+ if not result:
173
+ continue
174
+ if not isinstance(result, list):
175
+ logger.warning(
176
+ "register_skills callback %s.%s must return a list, got %s",
177
+ callback.__module__,
178
+ callback.__name__,
179
+ type(result).__name__,
180
+ )
181
+ continue
182
+
183
+ for entry in result:
184
+ if not isinstance(entry, dict):
185
+ logger.warning(
186
+ "register_skills callback %s.%s returned non-dict entry: %r",
187
+ callback.__module__,
188
+ callback.__name__,
189
+ entry,
190
+ )
191
+ continue
192
+ # Provider registrations are consumed by core through the same
193
+ # hook; they are capabilities, not skills to materialize.
194
+ if "provider" in entry:
195
+ continue
196
+ yield callback.__module__, callback.__name__, entry
197
+
198
+
199
+ def _plugin_registration_signature(
200
+ registrations: List[tuple[str, str, dict[str, Any]]],
201
+ ) -> tuple:
202
+ """Deterministic signature of the plugin skill registrations.
203
+
204
+ Used to decide whether the on-disk cache still reflects the registered
205
+ skills. Sorting each entry's items by key keeps the signature stable
206
+ regardless of dict ordering.
207
+ """
208
+ return tuple(
209
+ (module, name, repr(sorted(entry.items(), key=lambda kv: kv[0])))
210
+ for module, name, entry in registrations
211
+ )
212
+
213
+
214
+ def _collect_plugin_skills() -> List[SkillInfo]:
215
+ global _plugin_skills_cache, _plugin_skills_signature
216
+
217
+ with _PLUGIN_SKILLS_LOCK:
218
+ registrations = list(_iter_plugin_skill_registrations())
219
+ signature = _plugin_registration_signature(registrations)
220
+
221
+ # Reuse the materialised cache when registrations are unchanged and files are
222
+ # still on disk. Skipping the wipe prevents a concurrent rebuild from deleting
223
+ # a SKILL.md while a lock-free reader is consuming an earlier returned path.
224
+ if (
225
+ _plugin_skills_cache is not None
226
+ and signature == _plugin_skills_signature
227
+ and _PLUGIN_SKILLS_CACHE_DIR.exists()
228
+ ):
229
+ return list(_plugin_skills_cache)
230
+
231
+ if _PLUGIN_SKILLS_CACHE_DIR.exists():
232
+ shutil.rmtree(_PLUGIN_SKILLS_CACHE_DIR, ignore_errors=True)
233
+ _PLUGIN_SKILLS_CACHE_DIR.mkdir(parents=True, exist_ok=True)
234
+
235
+ plugin_skills: List[SkillInfo] = []
236
+ seen_names: set[str] = set()
237
+
238
+ for callback_module, callback_name, entry in registrations:
239
+ skill = _materialize_plugin_skill(callback_module, callback_name, entry)
240
+ if skill is None:
241
+ continue
242
+ if skill.name in seen_names:
243
+ logger.warning(
244
+ "Skipping duplicate plugin skill registration for '%s' from %s.%s",
245
+ skill.name,
246
+ callback_module,
247
+ callback_name,
248
+ )
249
+ continue
250
+ seen_names.add(skill.name)
251
+ plugin_skills.append(skill)
252
+
253
+ _plugin_skills_cache = plugin_skills
254
+ _plugin_skills_signature = signature
255
+ return list(plugin_skills)
256
+
257
+
258
+ def discover_skills(directories: Optional[List[Path]] = None) -> List[SkillInfo]:
259
+ """Scan directories for valid skills."""
260
+ global _skill_cache
261
+
262
+ if directories is None:
263
+ configured = [Path(d) for d in get_skill_directories()]
264
+ defaults = get_default_skill_directories()
265
+ seen = {p.resolve() for p in configured}
266
+ directories = list(configured)
267
+ for d in defaults:
268
+ if d.resolve() not in seen:
269
+ directories.append(d)
270
+
271
+ discovered_skills: List[SkillInfo] = []
272
+ seen_skill_names: set[str] = set()
273
+
274
+ for directory in directories:
275
+ if not directory.exists():
276
+ logger.debug(f"Skill directory does not exist: {directory}")
277
+ continue
278
+
279
+ if not directory.is_dir():
280
+ logger.warning(f"Skill path is not a directory: {directory}")
281
+ continue
282
+
283
+ for skill_dir in directory.iterdir():
284
+ if not skill_dir.is_dir() or skill_dir.name.startswith("."):
285
+ continue
286
+
287
+ # First-discovered skill wins - skip duplicates from later directories
288
+ if skill_dir.name in seen_skill_names:
289
+ logger.debug(
290
+ "Skipping duplicate skill '%s' at %s (already discovered)",
291
+ skill_dir.name,
292
+ skill_dir,
293
+ )
294
+ continue
295
+
296
+ has_skill_md = is_valid_skill_directory(skill_dir)
297
+ skill_info = SkillInfo(
298
+ name=skill_dir.name,
299
+ path=skill_dir,
300
+ has_skill_md=has_skill_md,
301
+ )
302
+ discovered_skills.append(skill_info)
303
+ seen_skill_names.add(skill_info.name)
304
+
305
+ if has_skill_md:
306
+ logger.debug(
307
+ "Discovered valid skill: %s at %s", skill_dir.name, skill_dir
308
+ )
309
+ else:
310
+ logger.debug(
311
+ "Found skill directory without SKILL.md: %s", skill_dir.name
312
+ )
313
+
314
+ for plugin_skill in _collect_plugin_skills():
315
+ if plugin_skill.name in seen_skill_names:
316
+ logger.debug(
317
+ "Skipping plugin skill '%s' because a filesystem skill already exists",
318
+ plugin_skill.name,
319
+ )
320
+ continue
321
+ discovered_skills.append(plugin_skill)
322
+ seen_skill_names.add(plugin_skill.name)
323
+
324
+ _skill_cache = discovered_skills
325
+ logger.info(
326
+ "Discovered %s skills from %s directories",
327
+ len(discovered_skills),
328
+ len(directories),
329
+ )
330
+ return discovered_skills
331
+
332
+
333
+ def refresh_skill_cache() -> List[SkillInfo]:
334
+ """Force re-discovery of all skills."""
335
+ global _skill_cache
336
+ _skill_cache = None
337
+ return discover_skills()