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,219 @@
1
+ """Skill metadata parsing - extracts info from SKILL.md frontmatter."""
2
+
3
+ import logging
4
+ import re
5
+ from dataclasses import dataclass, field
6
+ from pathlib import Path
7
+ from typing import List, Optional
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ # Regex pattern to match YAML frontmatter between --- delimiters
12
+ FRONTMATTER_PATTERN = re.compile(r"^---\s*\n(.*?)\n---\s*\n", re.DOTALL)
13
+
14
+ # Regex patterns for parsing simple key-value pairs from YAML-like frontmatter
15
+ KEY_VALUE_PATTERN = re.compile(r"^([a-zA-Z_][a-zA-Z0-9_]*):\s*(.*)$", re.MULTILINE)
16
+ LIST_PATTERN = re.compile(r"^\s+-\s+(.+)$", re.MULTILINE)
17
+
18
+
19
+ @dataclass
20
+ class SkillMetadata:
21
+ """Parsed skill metadata from SKILL.md frontmatter."""
22
+
23
+ name: str
24
+ description: str
25
+ path: Path
26
+ version: Optional[str] = None
27
+ author: Optional[str] = None
28
+ tags: List[str] = field(default_factory=list)
29
+
30
+
31
+ def _unquote(value: str) -> str:
32
+ """Remove quotes from a YAML string value if present."""
33
+ value = value.strip()
34
+ if (value.startswith('"') and value.endswith('"')) or (
35
+ value.startswith("'") and value.endswith("'")
36
+ ):
37
+ return value[1:-1]
38
+ return value
39
+
40
+
41
+ def parse_yaml_frontmatter(content: str) -> dict:
42
+ """Extract YAML frontmatter from SKILL.md content.
43
+
44
+ Frontmatter is between --- delimiters at the start of file.
45
+ Uses simple regex parsing to avoid heavy yaml dependency.
46
+
47
+ Args:
48
+ content: The full content of the SKILL.md file.
49
+
50
+ Returns:
51
+ Dictionary containing parsed frontmatter key-value pairs.
52
+ Returns empty dict if no frontmatter found or parsing fails.
53
+ """
54
+ match = FRONTMATTER_PATTERN.match(content)
55
+ if not match:
56
+ logger.debug("No frontmatter found in content")
57
+ return {}
58
+
59
+ frontmatter = match.group(1)
60
+ result: dict = {}
61
+ current_key: Optional[str] = None
62
+ current_list: List[str] = []
63
+
64
+ for line in frontmatter.split("\n"):
65
+ stripped = line.strip()
66
+
67
+ # Skip empty lines and comments
68
+ if not stripped or stripped.startswith("#"):
69
+ continue
70
+
71
+ # Check if this is a list item
72
+ list_match = LIST_PATTERN.match(line)
73
+ if list_match and current_key:
74
+ current_list.append(_unquote(list_match.group(1)))
75
+ continue
76
+
77
+ # Check if this is a key-value pair
78
+ kv_match = KEY_VALUE_PATTERN.match(line)
79
+ if kv_match:
80
+ # Save any accumulated list items from previous key
81
+ if current_key and current_list:
82
+ result[current_key] = current_list
83
+ current_list = []
84
+
85
+ key, value = kv_match.groups()
86
+ key = key.strip()
87
+ value = value.strip()
88
+
89
+ # If value is empty, this might be a list start
90
+ if not value:
91
+ current_key = key
92
+ result[key] = [] # Initialize as empty list
93
+ else:
94
+ result[key] = _unquote(value)
95
+ current_key = None
96
+
97
+ # Handle case where list items were at the end
98
+ if current_key and current_list:
99
+ result[current_key] = current_list
100
+
101
+ return result
102
+
103
+
104
+ def parse_skill_metadata(skill_path: Path) -> Optional[SkillMetadata]:
105
+ """Parse metadata from a skill's SKILL.md file.
106
+
107
+ Args:
108
+ skill_path: Path to the skill directory (not the SKILL.md file)
109
+
110
+ Returns:
111
+ SkillMetadata if successful, None if parsing fails.
112
+ """
113
+ if not skill_path.exists():
114
+ logger.debug(f"Skill path does not exist: {skill_path}")
115
+ return None
116
+
117
+ skill_md_path = skill_path / "SKILL.md"
118
+ if not skill_md_path.exists():
119
+ logger.debug(f"SKILL.md not found in skill directory: {skill_path}")
120
+ return None
121
+
122
+ try:
123
+ content = skill_md_path.read_text(encoding="utf-8")
124
+ except Exception as e:
125
+ logger.error(f"Failed to read SKILL.md at {skill_md_path}: {e}")
126
+ return None
127
+
128
+ frontmatter = parse_yaml_frontmatter(content)
129
+ if not frontmatter:
130
+ logger.debug(f"No valid frontmatter found in {skill_md_path}")
131
+ return None
132
+
133
+ # Required fields
134
+ name = frontmatter.get("name")
135
+ if not name:
136
+ logger.debug(
137
+ f"'name' is required in frontmatter but not found in {skill_md_path}"
138
+ )
139
+ return None
140
+
141
+ description = frontmatter.get("description")
142
+ if not description:
143
+ logger.debug(
144
+ f"'description' is required in frontmatter but not found in {skill_md_path}"
145
+ )
146
+ return None
147
+
148
+ # Handle tags - could be a list or a comma-separated string
149
+ tags: List[str] = []
150
+ raw_tags = frontmatter.get("tags", [])
151
+ if isinstance(raw_tags, list):
152
+ tags = raw_tags
153
+ elif isinstance(raw_tags, str):
154
+ tags = [tag.strip() for tag in raw_tags.split(",") if tag.strip()]
155
+
156
+ return SkillMetadata(
157
+ name=name,
158
+ description=description,
159
+ path=skill_path,
160
+ version=frontmatter.get("version"),
161
+ author=frontmatter.get("author"),
162
+ tags=tags,
163
+ )
164
+
165
+
166
+ def load_full_skill_content(skill_path: Path) -> Optional[str]:
167
+ """Load the complete SKILL.md content for activation.
168
+
169
+ Args:
170
+ skill_path: Path to the skill directory
171
+
172
+ Returns:
173
+ Full file content as string, or None if not found.
174
+ """
175
+ if not skill_path.exists():
176
+ logger.debug(f"Skill path does not exist: {skill_path}")
177
+ return None
178
+
179
+ skill_md_path = skill_path / "SKILL.md"
180
+ if not skill_md_path.exists():
181
+ logger.debug(f"SKILL.md not found in skill directory: {skill_path}")
182
+ return None
183
+
184
+ try:
185
+ return skill_md_path.read_text(encoding="utf-8")
186
+ except Exception as e:
187
+ logger.error(f"Failed to read SKILL.md at {skill_md_path}: {e}")
188
+ return None
189
+
190
+
191
+ def get_skill_resources(skill_path: Path) -> List[Path]:
192
+ """List all resource files bundled with a skill.
193
+
194
+ Returns paths to all non-SKILL.md files in the skill directory.
195
+
196
+ Args:
197
+ skill_path: Path to the skill directory
198
+
199
+ Returns:
200
+ List of paths to resource files (excluding SKILL.md).
201
+ """
202
+ if not skill_path.exists():
203
+ logger.debug(f"Skill path does not exist: {skill_path}")
204
+ return []
205
+
206
+ if not skill_path.is_dir():
207
+ logger.warning(f"Skill path is not a directory: {skill_path}")
208
+ return []
209
+
210
+ resources: List[Path] = []
211
+ try:
212
+ for item in skill_path.iterdir():
213
+ if item.is_file() and item.name != "SKILL.md":
214
+ resources.append(item)
215
+ except Exception as e:
216
+ logger.error(f"Failed to list resources in {skill_path}: {e}")
217
+ return []
218
+
219
+ return sorted(resources) # Sort for consistent ordering
@@ -0,0 +1,49 @@
1
+ """Build the `available skills` section for system-prompt injection.
2
+
3
+ Keep the verbosity floor-low. Each skill becomes a single line of the form
4
+ ``- <name>: <description>``. That is essentially the frontmatter `name` and
5
+ `description` fields, flattened. No XML, no ceremony, no escaping circus.
6
+ """
7
+
8
+ from typing import TYPE_CHECKING, List
9
+
10
+ if TYPE_CHECKING:
11
+ from .metadata import SkillMetadata
12
+
13
+
14
+ def _one_line(text: str) -> str:
15
+ """Collapse whitespace so each skill stays on a single line."""
16
+ return " ".join(text.split())
17
+
18
+
19
+ def build_available_skills_block(skills: List["SkillMetadata"]) -> str:
20
+ """Render a minimal markdown list of available skills.
21
+
22
+ Format::
23
+
24
+ ## Available Skills
25
+ - skill-one: short description
26
+ - skill-two: short description
27
+
28
+ Returns an empty string when there are no skills — callers can simply
29
+ concatenate without worrying about stray headings.
30
+ """
31
+ if not skills:
32
+ return ""
33
+
34
+ lines = ["## Available Skills"]
35
+ for skill in skills:
36
+ desc = _one_line(skill.description) if skill.description else ""
37
+ lines.append(f"- {skill.name}: {desc}" if desc else f"- {skill.name}")
38
+ return "\n".join(lines)
39
+
40
+
41
+ def build_skills_guidance() -> str:
42
+ """Tell the model when and how to use a skill."""
43
+ return (
44
+ "When the user's question or task relates to a skill listed above, "
45
+ "activate it with `activate_skill(name)` **before** answering so its "
46
+ "full instructions are loaded into context. Use "
47
+ "`list_or_search_skills(query)` to discover skills by keyword — it "
48
+ "matches any individual word in the query."
49
+ )
@@ -0,0 +1,52 @@
1
+ """Core-facing provider backed by the agent_skills plugin's existing helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import Any, List, Optional, Set
7
+
8
+ from .config import get_disabled_skills, get_skills_enabled
9
+ from .enabled_skills import iter_enabled_skills, list_enabled_skill_metadata
10
+ from .metadata import get_skill_resources, load_full_skill_content
11
+ from .skill_catalog import catalog
12
+
13
+
14
+ class AgentSkillsProvider:
15
+ """Adapt agent_skills internals to the neutral core provider contract."""
16
+
17
+ def is_enabled(self) -> bool:
18
+ return get_skills_enabled()
19
+
20
+ def get_disabled_skill_names(self) -> Set[str]:
21
+ return get_disabled_skills()
22
+
23
+ def list_enabled_skills(self) -> List[dict[str, Any]]:
24
+ return [
25
+ {
26
+ "name": metadata.name,
27
+ "description": metadata.description,
28
+ "path": str(metadata.path),
29
+ "tags": metadata.tags,
30
+ "version": metadata.version,
31
+ "author": metadata.author,
32
+ }
33
+ for metadata in list_enabled_skill_metadata()
34
+ ]
35
+
36
+ def find_enabled_skill_path(self, skill_name: str) -> Optional[Path]:
37
+ return next(
38
+ (info.path for info in iter_enabled_skills() if info.name == skill_name),
39
+ None,
40
+ )
41
+
42
+ def load_skill_content(self, skill_path: Path) -> Optional[str]:
43
+ return load_full_skill_content(skill_path)
44
+
45
+ def get_skill_resources(self, skill_path: Path) -> List[Path]:
46
+ return get_skill_resources(skill_path)
47
+
48
+ def get_catalog_skill_ids(self) -> List[str]:
49
+ return [entry.id for entry in catalog.get_all()]
50
+
51
+
52
+ skill_provider = AgentSkillsProvider()
@@ -0,0 +1,309 @@
1
+ """Agent Skills plugin - registers callbacks for skill integration.
2
+
3
+ This plugin:
4
+ 1. Injects available skills into system prompts
5
+ 2. Registers skill-related tools
6
+ 3. Exposes a skills provider via the ``register_skills`` hook
7
+ 4. Provides /skills slash command (and alias /skill)
8
+ """
9
+
10
+ import logging
11
+ from typing import Any, Dict, List, Optional, Tuple
12
+
13
+ from code_puppy.callbacks import register_callback
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ def _get_skills_prompt_section() -> Optional[str]:
19
+ """Build the skills section to inject into system prompts.
20
+
21
+ Returns None if skills are disabled or no enabled skills exist.
22
+ Disabled skills never have their frontmatter loaded — see
23
+ :mod:`code_puppy_core_plugins.agent_skills.enabled_skills`.
24
+
25
+ When ``frontmatter_in_system_prompt`` is ``False``, the per-skill list is
26
+ omitted but the short guidance line is still emitted so the model knows
27
+ the ``activate_skill`` / ``list_or_search_skills`` mechanism exists.
28
+ """
29
+ from .config import get_frontmatter_in_system_prompt
30
+ from .enabled_skills import list_enabled_skill_metadata
31
+ from .prompt_builder import build_available_skills_block, build_skills_guidance
32
+
33
+ skills_metadata = list_enabled_skill_metadata()
34
+ if not skills_metadata:
35
+ logger.debug("No enabled skills with metadata found, skipping prompt injection")
36
+ return None
37
+
38
+ guidance = build_skills_guidance()
39
+
40
+ if not get_frontmatter_in_system_prompt():
41
+ logger.debug(
42
+ "Frontmatter injection disabled; emitting guidance line only "
43
+ f"({len(skills_metadata)} skills hidden from system prompt)"
44
+ )
45
+ return guidance
46
+
47
+ skills_block = build_available_skills_block(skills_metadata)
48
+ logger.debug(f"Injecting skills section with {len(skills_metadata)} skills")
49
+ return f"{skills_block}\n\n{guidance}"
50
+
51
+
52
+ def _inject_skills_into_prompt(
53
+ model_name: str, default_system_prompt: str, user_prompt: str
54
+ ) -> Optional[Dict[str, Any]]:
55
+ """Callback to inject skills into system prompt.
56
+
57
+ This is registered with the 'get_model_system_prompt' callback phase.
58
+ """
59
+ skills_section = _get_skills_prompt_section()
60
+
61
+ if not skills_section:
62
+ return None # No skills, don't modify prompt
63
+
64
+ # Append skills section to system prompt
65
+ enhanced_prompt = f"{default_system_prompt}\n\n{skills_section}"
66
+
67
+ return {
68
+ "instructions": enhanced_prompt,
69
+ "user_prompt": user_prompt,
70
+ "handled": False, # Let other handlers also process
71
+ }
72
+
73
+
74
+ def _register_skills_tools() -> List[Dict[str, Any]]:
75
+ """Callback to register skills tools.
76
+
77
+ This is registered with the 'register_tools' callback phase.
78
+ Returns tool definitions for the tool registry.
79
+ """
80
+ from code_puppy.tools.skills_tools import (
81
+ register_activate_skill,
82
+ register_list_or_search_skills,
83
+ )
84
+
85
+ return [
86
+ {"name": "activate_skill", "register_func": register_activate_skill},
87
+ {
88
+ "name": "list_or_search_skills",
89
+ "register_func": register_list_or_search_skills,
90
+ },
91
+ ]
92
+
93
+
94
+ def _register_skills() -> List[Dict[str, Any]]:
95
+ """Expose the plugin through the neutral ``register_skills`` provider seam."""
96
+ from .provider import skill_provider
97
+
98
+ return [{"provider": skill_provider}]
99
+
100
+
101
+ # ---------------------------------------------------------------------------
102
+ # Slash command: /skills (and alias /skill)
103
+ # ---------------------------------------------------------------------------
104
+
105
+ _COMMAND_NAME = "skills"
106
+ _ALIASES = ("skill",)
107
+
108
+
109
+ def _skills_command_help() -> List[Tuple[str, str]]:
110
+ """Advertise /skills (+ every individual skill) in the /help menu."""
111
+ from .skill_commands import skill_command_help
112
+
113
+ entries: List[Tuple[str, str]] = [
114
+ ("skills", "Manage agent skills – browse, enable, disable, install"),
115
+ ("skill", "Alias for /skills"),
116
+ ]
117
+ # Append per-skill commands so they show up in /help & tab-completion.
118
+ entries.extend(skill_command_help())
119
+ return entries
120
+
121
+
122
+ def _handle_skills_command(command: str, name: str) -> Optional[Any]:
123
+ """Handle /skills and /skill slash commands.
124
+
125
+ Sub-commands:
126
+ /skills – Launch interactive TUI menu
127
+ /skills list – Quick text list of all skills
128
+ /skills install – Browse & install from remote catalog
129
+ /skills enable – Enable skills integration globally
130
+ /skills disable – Disable skills integration globally
131
+ /skills toggle – Toggle skills integration globally
132
+ /skills refresh – Force skill re-discovery and refresh local cache
133
+ /skills help – Show skills command help
134
+ """
135
+ if name not in (_COMMAND_NAME, *_ALIASES):
136
+ # Not the /skills meta-command — maybe it's an individual skill?
137
+ from .skill_commands import handle_skill_command
138
+
139
+ return handle_skill_command(command, name)
140
+
141
+ from code_puppy.messaging import emit_error, emit_info, emit_success, emit_warning
142
+ from code_puppy_core_plugins.agent_skills.config import (
143
+ get_disabled_skills,
144
+ get_frontmatter_in_system_prompt,
145
+ get_skills_enabled,
146
+ set_frontmatter_in_system_prompt,
147
+ set_skills_enabled,
148
+ )
149
+ from code_puppy_core_plugins.agent_skills.discovery import (
150
+ discover_skills,
151
+ refresh_skill_cache,
152
+ )
153
+ from code_puppy_core_plugins.agent_skills.metadata import parse_skill_metadata
154
+ from code_puppy_core_plugins.agent_skills.skills_menu import show_skills_menu
155
+
156
+ tokens = command.split()
157
+
158
+ if len(tokens) > 1:
159
+ subcommand = tokens[1].lower()
160
+
161
+ if subcommand == "list":
162
+ disabled_skills = get_disabled_skills()
163
+ skills = discover_skills()
164
+ enabled = get_skills_enabled()
165
+
166
+ if not skills:
167
+ emit_info("No skills found.")
168
+ emit_info("Create skills in:")
169
+ emit_info(" - ~/.code_puppy/skills/")
170
+ emit_info(" - ./skills/")
171
+ return True
172
+
173
+ emit_info(
174
+ f"\U0001f6e0\ufe0f Skills (integration: {'enabled' if enabled else 'disabled'})"
175
+ )
176
+ emit_info(f"Found {len(skills)} skill(s):\n")
177
+
178
+ for skill in skills:
179
+ metadata = parse_skill_metadata(skill.path)
180
+ if metadata:
181
+ status = (
182
+ "\U0001f534 disabled"
183
+ if metadata.name in disabled_skills
184
+ else "\U0001f7e2 enabled"
185
+ )
186
+ version_str = f" v{metadata.version}" if metadata.version else ""
187
+ author_str = f" by {metadata.author}" if metadata.author else ""
188
+ emit_info(f" {status} {metadata.name}{version_str}{author_str}")
189
+ emit_info(f" {metadata.description}")
190
+ if metadata.tags:
191
+ emit_info(f" tags: {', '.join(metadata.tags)}")
192
+ else:
193
+ status = (
194
+ "\U0001f534 disabled"
195
+ if skill.name in disabled_skills
196
+ else "\U0001f7e2 enabled"
197
+ )
198
+ emit_info(f" {status} {skill.name}")
199
+ emit_info(" (no SKILL.md metadata found)")
200
+ emit_info("")
201
+ return True
202
+
203
+ elif subcommand == "install":
204
+ from code_puppy_core_plugins.agent_skills.skills_install_menu import (
205
+ run_skills_install_menu,
206
+ )
207
+
208
+ run_skills_install_menu()
209
+ return True
210
+
211
+ elif subcommand == "enable":
212
+ set_skills_enabled(True)
213
+ emit_success("\u2705 Skills integration enabled globally")
214
+ return True
215
+
216
+ elif subcommand == "disable":
217
+ set_skills_enabled(False)
218
+ emit_warning("\U0001f534 Skills integration disabled globally")
219
+ return True
220
+
221
+ elif subcommand == "toggle":
222
+ new_state = not get_skills_enabled()
223
+ set_skills_enabled(new_state)
224
+ if new_state:
225
+ emit_success("✅ Skills integration enabled globally")
226
+ else:
227
+ emit_warning("🔴 Skills integration disabled globally")
228
+ return True
229
+
230
+ elif subcommand == "frontmatter":
231
+ # /skills frontmatter [on|off|toggle] (no arg = show state)
232
+ arg = tokens[2].lower() if len(tokens) > 2 else None
233
+ current = get_frontmatter_in_system_prompt()
234
+
235
+ if arg in ("on", "enable", "true"):
236
+ new_state = True
237
+ elif arg in ("off", "disable", "false"):
238
+ new_state = False
239
+ elif arg == "toggle":
240
+ new_state = not current
241
+ elif arg is None:
242
+ emit_info(
243
+ f"Skill frontmatter in system prompt: "
244
+ f"{'🟢 on' if current else '🔴 off'}"
245
+ )
246
+ emit_info("Usage: /skills frontmatter [on|off|toggle]")
247
+ return True
248
+ else:
249
+ emit_error(f"Unknown frontmatter arg: {arg}")
250
+ emit_info("Usage: /skills frontmatter [on|off|toggle]")
251
+ return True
252
+
253
+ set_frontmatter_in_system_prompt(new_state)
254
+ if new_state:
255
+ emit_success(
256
+ "✅ Skill frontmatter will be injected into system prompts"
257
+ )
258
+ else:
259
+ emit_warning(
260
+ "🔴 Skill frontmatter hidden from system prompts "
261
+ "(model can still call activate_skill / list_or_search_skills)"
262
+ )
263
+ return True
264
+
265
+ elif subcommand == "refresh":
266
+ refreshed = refresh_skill_cache()
267
+ valid_skills = [skill for skill in refreshed if skill.has_skill_md]
268
+ emit_success(
269
+ f"🔄 Refreshed skills cache: {len(refreshed)} discovered "
270
+ f"({len(valid_skills)} with SKILL.md)"
271
+ )
272
+ return True
273
+
274
+ elif subcommand == "help":
275
+ emit_info("Available /skills subcommands:")
276
+ emit_info(" /skills list - List all installed skills")
277
+ emit_info(" /skills install - Browse & install from catalog")
278
+ emit_info(" /skills enable - Enable skills integration globally")
279
+ emit_info(" /skills disable - Disable skills integration globally")
280
+ emit_info(" /skills toggle - Toggle skills integration globally")
281
+ emit_info(
282
+ " /skills frontmatter [on|off|toggle] - Toggle skill list injection into system prompt"
283
+ )
284
+ emit_info(" /skills refresh - Refresh skill cache")
285
+ emit_info(" /skills - Open interactive skills menu")
286
+ return True
287
+
288
+ else:
289
+ emit_error(f"Unknown subcommand: {subcommand}")
290
+ emit_info(
291
+ "Usage: /skills [list|install|enable|disable|toggle|frontmatter|refresh|help]"
292
+ )
293
+ return True
294
+
295
+ # No subcommand – launch TUI menu
296
+ show_skills_menu()
297
+ return True
298
+
299
+
300
+ # ---------------------------------------------------------------------------
301
+ # Register all callbacks
302
+ # ---------------------------------------------------------------------------
303
+ register_callback("get_model_system_prompt", _inject_skills_into_prompt)
304
+ register_callback("register_tools", _register_skills_tools)
305
+ register_callback("register_skills", _register_skills)
306
+ register_callback("custom_command_help", _skills_command_help)
307
+ register_callback("custom_command", _handle_skills_command)
308
+
309
+ logger.info("Agent Skills plugin loaded")