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,461 @@
1
+ """ChatGPT OAuth flow closely matching the ChatMock implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import datetime
6
+ import threading
7
+ import time
8
+ import urllib.parse
9
+ from dataclasses import dataclass
10
+ from http.server import BaseHTTPRequestHandler, HTTPServer
11
+ from typing import Any, Optional, Tuple
12
+
13
+ import requests
14
+
15
+ from code_puppy.messaging import emit_error, emit_info, emit_success, emit_warning
16
+
17
+ from ..oauth_pasteback import parse_oauth_callback_input, read_available_stdin_line
18
+ from ..oauth_puppy_html import oauth_failure_html, oauth_success_html
19
+ from .config import CHATGPT_OAUTH_CONFIG
20
+ from .utils import (
21
+ OAuthContext,
22
+ add_models_to_extra_config,
23
+ assign_redirect_uri,
24
+ build_authorization_url,
25
+ load_stored_tokens,
26
+ parse_jwt_claims,
27
+ prepare_oauth_context,
28
+ save_tokens,
29
+ )
30
+
31
+ REQUIRED_PORT = CHATGPT_OAUTH_CONFIG["required_port"]
32
+ URL_BASE = f"http://localhost:{REQUIRED_PORT}"
33
+
34
+
35
+ @dataclass
36
+ class TokenData:
37
+ id_token: str
38
+ access_token: str
39
+ refresh_token: str
40
+ account_id: str
41
+
42
+
43
+ @dataclass
44
+ class AuthBundle:
45
+ api_key: Optional[str]
46
+ token_data: TokenData
47
+ last_refresh: str
48
+
49
+
50
+ def _exchange_code_for_auth_bundle(
51
+ *, code: str, context: OAuthContext, client_id: str
52
+ ) -> Tuple[AuthBundle, str]:
53
+ if not context.redirect_uri:
54
+ raise RuntimeError("Redirect URI missing from OAuth context")
55
+
56
+ data = {
57
+ "grant_type": "authorization_code",
58
+ "code": code,
59
+ "redirect_uri": context.redirect_uri,
60
+ "client_id": client_id,
61
+ "code_verifier": context.code_verifier,
62
+ }
63
+
64
+ response = requests.post(
65
+ CHATGPT_OAUTH_CONFIG["token_url"],
66
+ data=data,
67
+ headers={"Content-Type": "application/x-www-form-urlencoded"},
68
+ timeout=30,
69
+ )
70
+ response.raise_for_status()
71
+ payload = response.json()
72
+
73
+ id_token = payload.get("id_token", "")
74
+ access_token = payload.get("access_token", "")
75
+ refresh_token = payload.get("refresh_token", "")
76
+
77
+ id_token_claims = parse_jwt_claims(id_token) or {}
78
+ access_token_claims = parse_jwt_claims(access_token) or {}
79
+
80
+ auth_claims = id_token_claims.get("https://api.openai.com/auth") or {}
81
+ chatgpt_account_id = auth_claims.get("chatgpt_account_id", "")
82
+ organizations = auth_claims.get("organizations", [])
83
+ org_id = None
84
+ if organizations:
85
+ default_org = next(
86
+ (org for org in organizations if org.get("is_default")),
87
+ organizations[0],
88
+ )
89
+ org_id = default_org.get("id")
90
+ if not org_id:
91
+ org_id = id_token_claims.get("organization_id")
92
+
93
+ token_data = TokenData(
94
+ id_token=id_token,
95
+ access_token=access_token,
96
+ refresh_token=refresh_token,
97
+ account_id=chatgpt_account_id,
98
+ )
99
+
100
+ last_refresh = (
101
+ datetime.datetime.now(datetime.timezone.utc).isoformat().replace("+00:00", "Z")
102
+ )
103
+ bundle = AuthBundle(
104
+ api_key=token_data.access_token,
105
+ token_data=token_data,
106
+ last_refresh=last_refresh,
107
+ )
108
+
109
+ success_query = {
110
+ "id_token": token_data.id_token,
111
+ "access_token": token_data.access_token,
112
+ "refresh_token": token_data.refresh_token,
113
+ "org_id": org_id or "",
114
+ "plan_type": access_token_claims.get("chatgpt_plan_type"),
115
+ "platform_url": "https://platform.openai.com",
116
+ }
117
+ success_url = f"{URL_BASE}/success?{urllib.parse.urlencode(success_query)}"
118
+ return bundle, success_url
119
+
120
+
121
+ def _save_auth_bundle(auth_bundle: AuthBundle) -> bool:
122
+ tokens = {
123
+ "id_token": auth_bundle.token_data.id_token,
124
+ "access_token": auth_bundle.token_data.access_token,
125
+ "refresh_token": auth_bundle.token_data.refresh_token,
126
+ "account_id": auth_bundle.token_data.account_id,
127
+ "last_refresh": auth_bundle.last_refresh,
128
+ }
129
+ if auth_bundle.api_key:
130
+ tokens["api_key"] = auth_bundle.api_key
131
+ return save_tokens(tokens)
132
+
133
+
134
+ def _state_matches(context: OAuthContext, state: Optional[str]) -> bool:
135
+ return bool(state and state == context.state)
136
+
137
+
138
+ class _OAuthServer(HTTPServer):
139
+ def __init__(
140
+ self,
141
+ *,
142
+ client_id: str,
143
+ verbose: bool = False,
144
+ ) -> None:
145
+ super().__init__(
146
+ ("localhost", REQUIRED_PORT), _CallbackHandler, bind_and_activate=True
147
+ )
148
+ self.exit_code = 1
149
+ self.verbose = verbose
150
+ self.client_id = client_id
151
+ self.issuer = CHATGPT_OAUTH_CONFIG["issuer"]
152
+ self.token_endpoint = CHATGPT_OAUTH_CONFIG["token_url"]
153
+ self.error: Optional[str] = None
154
+ self.received_event = threading.Event()
155
+
156
+ # Create fresh OAuth context for this server instance
157
+ context = prepare_oauth_context()
158
+ self.redirect_uri = assign_redirect_uri(context, REQUIRED_PORT)
159
+ self.context = context
160
+
161
+ def auth_url(self) -> str:
162
+ params = {
163
+ "response_type": "code",
164
+ "client_id": self.client_id,
165
+ "redirect_uri": self.redirect_uri,
166
+ "scope": CHATGPT_OAUTH_CONFIG["scope"],
167
+ "code_challenge": self.context.code_challenge,
168
+ "code_challenge_method": "S256",
169
+ "id_token_add_organizations": "true",
170
+ "codex_cli_simplified_flow": "true",
171
+ "state": self.context.state,
172
+ }
173
+ return f"{self.issuer}/oauth/authorize?" + urllib.parse.urlencode(params)
174
+
175
+ def exchange_code(self, code: str) -> Tuple[AuthBundle, str]:
176
+ return _exchange_code_for_auth_bundle(
177
+ code=code, context=self.context, client_id=self.client_id
178
+ )
179
+
180
+
181
+ class _CallbackHandler(BaseHTTPRequestHandler):
182
+ server: "_OAuthServer"
183
+
184
+ def do_GET(self) -> None: # noqa: N802
185
+ path = urllib.parse.urlparse(self.path).path
186
+ if path == "/success":
187
+ success_html = oauth_success_html(
188
+ "ChatGPT",
189
+ "You can now close this window and return to Code Puppy.",
190
+ )
191
+ self._send_html(success_html)
192
+ self._shutdown_after_delay(2.0)
193
+ return
194
+
195
+ if path != "/auth/callback":
196
+ self._fail_callback(
197
+ 404, "Callback endpoint not found for the puppy parade."
198
+ )
199
+ self._shutdown()
200
+ return
201
+
202
+ query = urllib.parse.urlparse(self.path).query
203
+ params = urllib.parse.parse_qs(query)
204
+
205
+ code = params.get("code", [None])[0]
206
+ if not code:
207
+ self._fail_callback(400, "Missing auth code — the token treat rolled away.")
208
+ self._shutdown()
209
+ return
210
+
211
+ state = params.get("state", [None])[0]
212
+ if not _state_matches(self.server.context, state):
213
+ self._fail_callback(
214
+ 400, "State mismatch detected; aborting authentication."
215
+ )
216
+ self._shutdown()
217
+ return
218
+
219
+ try:
220
+ auth_bundle, success_url = self.server.exchange_code(code)
221
+ except Exception as exc: # noqa: BLE001
222
+ self._fail_callback(500, f"Token exchange failed: {exc}")
223
+ self._shutdown()
224
+ return
225
+
226
+ if _save_auth_bundle(auth_bundle):
227
+ self.server.exit_code = 0
228
+ self.server.received_event.set()
229
+ # Redirect to the success URL returned by exchange_code
230
+ self._send_redirect(success_url)
231
+ else:
232
+ self._fail_callback(
233
+ 500, "Unable to persist auth file — a puppy probably chewed it."
234
+ )
235
+ self._shutdown()
236
+ self._shutdown_after_delay(2.0)
237
+
238
+ def do_POST(self) -> None: # noqa: N802
239
+ self._send_failure(
240
+ 404, "POST not supported — the pups only fetch GET requests."
241
+ )
242
+ self._shutdown()
243
+
244
+ def log_message(self, fmt: str, *args: Any) -> None: # noqa: A003
245
+ if getattr(self.server, "verbose", False):
246
+ super().log_message(fmt, *args)
247
+
248
+ def _send_redirect(self, url: str) -> None:
249
+ self.send_response(302)
250
+ self.send_header("Location", url)
251
+ self.end_headers()
252
+
253
+ def _send_html(self, body: str, status: int = 200) -> None:
254
+ encoded = body.encode("utf-8")
255
+ self.send_response(status)
256
+ self.send_header("Content-Type", "text/html; charset=utf-8")
257
+ self.send_header("Content-Length", str(len(encoded)))
258
+ self.end_headers()
259
+ self.wfile.write(encoded)
260
+
261
+ def _send_failure(self, status: int, reason: str) -> None:
262
+ failure_html = oauth_failure_html("ChatGPT", reason)
263
+ self._send_html(failure_html, status)
264
+
265
+ def _fail_callback(self, status: int, reason: str) -> None:
266
+ self.server.error = reason
267
+ self.server.received_event.set()
268
+ self._send_failure(status, reason)
269
+
270
+ def _shutdown(self) -> None:
271
+ threading.Thread(target=self.server.shutdown, daemon=True).start()
272
+
273
+ def _shutdown_after_delay(self, seconds: float = 2.0) -> None:
274
+ def _later() -> None:
275
+ try:
276
+ time.sleep(seconds)
277
+ finally:
278
+ self._shutdown()
279
+
280
+ threading.Thread(target=_later, daemon=True).start()
281
+
282
+
283
+ def _prepare_manual_context() -> OAuthContext:
284
+ context = prepare_oauth_context()
285
+ assign_redirect_uri(context, REQUIRED_PORT)
286
+ return context
287
+
288
+
289
+ def _complete_pasted_input(
290
+ *, raw_input: str, context: OAuthContext, client_id: str
291
+ ) -> bool:
292
+ try:
293
+ parsed = parse_oauth_callback_input(raw_input)
294
+ except ValueError as exc:
295
+ emit_error(f"Could not parse pasted OAuth input: {exc}")
296
+ return False
297
+
298
+ if parsed.error:
299
+ emit_error(f"OAuth provider returned an error: {parsed.error_message}")
300
+ return False
301
+
302
+ if not parsed.code:
303
+ emit_error("Pasted OAuth input did not contain an authorization code.")
304
+ return False
305
+
306
+ if parsed.state:
307
+ if parsed.state != context.state:
308
+ emit_error("State mismatch detected; aborting authentication.")
309
+ return False
310
+ else:
311
+ emit_warning(
312
+ "Pasted OAuth input did not include state; continuing with this login attempt."
313
+ )
314
+
315
+ try:
316
+ auth_bundle, _ = _exchange_code_for_auth_bundle(
317
+ code=parsed.code,
318
+ context=context,
319
+ client_id=client_id,
320
+ )
321
+ except Exception as exc: # noqa: BLE001
322
+ emit_error(f"Token exchange failed: {exc}")
323
+ return False
324
+
325
+ if not _save_auth_bundle(auth_bundle):
326
+ emit_error("Unable to persist auth file.")
327
+ return False
328
+
329
+ emit_success("Authorization code accepted; tokens saved.")
330
+ return True
331
+
332
+
333
+ def _wait_for_auth_completion(
334
+ *,
335
+ server: Optional[_OAuthServer],
336
+ context: OAuthContext,
337
+ client_id: str,
338
+ ) -> bool:
339
+ emit_info(
340
+ "Waiting for authentication callback. If localhost cannot be reached, "
341
+ "paste the full callback URL or authorization code here and press Enter."
342
+ )
343
+
344
+ elapsed = 0.0
345
+ timeout = CHATGPT_OAUTH_CONFIG["callback_timeout"]
346
+ interval = 0.25
347
+ while elapsed < timeout:
348
+ if server and server.exit_code == 0:
349
+ return True
350
+ if server and server.received_event.is_set():
351
+ if server.error:
352
+ emit_error(f"OAuth callback error: {server.error}")
353
+ return server.exit_code == 0
354
+
355
+ pasted = read_available_stdin_line()
356
+ if pasted is not None and pasted.strip():
357
+ if _complete_pasted_input(
358
+ raw_input=pasted,
359
+ context=context,
360
+ client_id=client_id,
361
+ ):
362
+ return True
363
+
364
+ time.sleep(interval)
365
+ elapsed += interval
366
+
367
+ return False
368
+
369
+
370
+ def run_oauth_flow() -> None:
371
+ existing_tokens = load_stored_tokens()
372
+ if existing_tokens and existing_tokens.get("access_token"):
373
+ emit_warning("Existing ChatGPT tokens will be overwritten.")
374
+
375
+ server: Optional[_OAuthServer] = None
376
+ server_thread: Optional[threading.Thread] = None
377
+ client_id = CHATGPT_OAUTH_CONFIG["client_id"]
378
+ try:
379
+ server = _OAuthServer(client_id=client_id)
380
+ context = server.context
381
+ auth_url = server.auth_url()
382
+ except OSError as exc:
383
+ emit_warning(
384
+ f"Could not start OAuth server on port {REQUIRED_PORT}: {exc}. "
385
+ "Continuing in paste-back mode."
386
+ )
387
+ emit_info(
388
+ f"Free port {REQUIRED_PORT} to restore automatic localhost callbacks."
389
+ )
390
+ context = _prepare_manual_context()
391
+ auth_url = build_authorization_url(context)
392
+
393
+ emit_info(f"Open this URL in your browser: {auth_url}")
394
+
395
+ if server:
396
+ server_thread = threading.Thread(target=server.serve_forever, daemon=True)
397
+ server_thread.start()
398
+
399
+ webbrowser_opened = False
400
+ suppress_browser = False
401
+ try:
402
+ import webbrowser
403
+
404
+ from code_puppy.tools.common import should_suppress_browser
405
+
406
+ suppress_browser = should_suppress_browser()
407
+ if suppress_browser:
408
+ emit_info(f"[HEADLESS MODE] Would normally open: {auth_url}")
409
+ else:
410
+ webbrowser_opened = webbrowser.open(auth_url)
411
+ except Exception as exc: # noqa: BLE001
412
+ emit_warning(f"Could not open browser automatically: {exc}")
413
+
414
+ if not webbrowser_opened and not suppress_browser:
415
+ emit_warning("Please open the URL manually if the browser did not open.")
416
+
417
+ completed = _wait_for_auth_completion(
418
+ server=server,
419
+ context=context,
420
+ client_id=client_id,
421
+ )
422
+
423
+ if server:
424
+ server.shutdown()
425
+ if server_thread:
426
+ server_thread.join(timeout=5)
427
+
428
+ if not completed:
429
+ if server and server.error:
430
+ emit_error("Authentication failed.")
431
+ else:
432
+ emit_error("Authentication failed or timed out.")
433
+ return
434
+
435
+ tokens = load_stored_tokens()
436
+ if not tokens:
437
+ emit_error("Tokens saved during OAuth flow could not be loaded.")
438
+ return
439
+
440
+ api_key = tokens.get("api_key")
441
+ if api_key:
442
+ emit_success("Successfully obtained OAuth access token for API access.")
443
+ emit_info(
444
+ f"Access token saved and available via {CHATGPT_OAUTH_CONFIG['api_key_env_var']}"
445
+ )
446
+ else:
447
+ emit_warning(
448
+ "No API key obtained. You may need to configure projects at platform.openai.com."
449
+ )
450
+
451
+ if api_key:
452
+ emit_info("Registering ChatGPT Codex models…")
453
+ from .utils import fetch_chatgpt_models
454
+
455
+ account_id = tokens.get("account_id", "")
456
+ models = fetch_chatgpt_models(api_key, account_id)
457
+ if models:
458
+ if add_models_to_extra_config(models):
459
+ emit_success(
460
+ "Codex models registered. Use the `codex-` prefix in /model."
461
+ )