code-puppy-core-plugins 0.0.26__tar.gz → 0.0.28__tar.gz

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 (344) hide show
  1. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/PKG-INFO +1 -1
  2. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/file_permission_handler/register_callbacks.py +66 -29
  3. code_puppy_core_plugins-0.0.28/code_puppy_core_plugins/openrouter_oauth/__init__.py +6 -0
  4. code_puppy_core_plugins-0.0.28/code_puppy_core_plugins/openrouter_oauth/config.py +21 -0
  5. code_puppy_core_plugins-0.0.28/code_puppy_core_plugins/openrouter_oauth/oauth_flow.py +242 -0
  6. code_puppy_core_plugins-0.0.28/code_puppy_core_plugins/openrouter_oauth/register_callbacks.py +93 -0
  7. code_puppy_core_plugins-0.0.28/code_puppy_core_plugins/openrouter_oauth/test_plugin.py +263 -0
  8. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/pyproject.toml +2 -1
  9. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/.gitignore +0 -0
  10. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/LICENSE +0 -0
  11. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/README.md +0 -0
  12. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/__init__.py +0 -0
  13. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/README.md +0 -0
  14. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/__init__.py +0 -0
  15. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/agent.py +0 -0
  16. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/bridge.py +0 -0
  17. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/capabilities.py +0 -0
  18. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/commands.py +0 -0
  19. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/content.py +0 -0
  20. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/io_delegation.py +0 -0
  21. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/mcp_config.py +0 -0
  22. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/permissions.py +0 -0
  23. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/persistence.py +0 -0
  24. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/register_callbacks.py +0 -0
  25. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/replay.py +0 -0
  26. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/session.py +0 -0
  27. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/session_config.py +0 -0
  28. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/acp/state.py +0 -0
  29. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_creator_skill/SKILL.md +0 -0
  30. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_creator_skill/__init__.py +0 -0
  31. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_creator_skill/register_callbacks.py +0 -0
  32. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/__init__.py +0 -0
  33. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/config.py +0 -0
  34. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/discovery.py +0 -0
  35. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/downloader.py +0 -0
  36. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/enabled_skills.py +0 -0
  37. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/installer.py +0 -0
  38. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/metadata.py +0 -0
  39. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/prompt_builder.py +0 -0
  40. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/provider.py +0 -0
  41. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/register_callbacks.py +0 -0
  42. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/remote_catalog.py +0 -0
  43. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/skill_catalog.py +0 -0
  44. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/skill_commands.py +0 -0
  45. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/skills_install_menu.py +0 -0
  46. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/agent_skills/skills_menu.py +0 -0
  47. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/aws_bedrock/__init__.py +0 -0
  48. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/aws_bedrock/config.py +0 -0
  49. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/aws_bedrock/register_callbacks.py +0 -0
  50. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/aws_bedrock/utils.py +0 -0
  51. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/azure_foundry/README.md +0 -0
  52. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/azure_foundry/__init__.py +0 -0
  53. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/azure_foundry/config.py +0 -0
  54. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/azure_foundry/discovery.py +0 -0
  55. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/azure_foundry/register_callbacks.py +0 -0
  56. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/azure_foundry/token.py +0 -0
  57. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/azure_foundry/utils.py +0 -0
  58. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/btw/__init__.py +0 -0
  59. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/btw/inline_view.py +0 -0
  60. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/btw/register_callbacks.py +0 -0
  61. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/btw/side_query.py +0 -0
  62. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/IMAGEGEN_SKILL.md +0 -0
  63. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/__init__.py +0 -0
  64. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/config.py +0 -0
  65. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/image_generation.py +0 -0
  66. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/image_tool.py +0 -0
  67. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/model_catalog.py +0 -0
  68. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/oauth_flow.py +0 -0
  69. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/register_callbacks.py +0 -0
  70. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/test_plugin.py +0 -0
  71. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/usage.py +0 -0
  72. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/chatgpt_oauth/utils.py +0 -0
  73. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_hooks/__init__.py +0 -0
  74. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_hooks/config.py +0 -0
  75. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_hooks/register_callbacks.py +0 -0
  76. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_hooks/trust.py +0 -0
  77. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/README.md +0 -0
  78. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/SETUP.md +0 -0
  79. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/__init__.py +0 -0
  80. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/config.py +0 -0
  81. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/fast_mode.py +0 -0
  82. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/prompt_handler.py +0 -0
  83. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/register_callbacks.py +0 -0
  84. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/test_plugin.py +0 -0
  85. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
  86. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/claude_code_oauth/utils.py +0 -0
  87. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/AGENTS_AND_TOOLS.md +0 -0
  88. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/MODELS_AND_MCP.md +0 -0
  89. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/PLUGINS_AND_CALLBACKS.md +0 -0
  90. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/SESSIONS_AND_HISTORY.md +0 -0
  91. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/SKILL.md +0 -0
  92. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/SKILLS_SYSTEM.md +0 -0
  93. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/SYSTEM_PROMPT_CONFIG_AND_I18N.md +0 -0
  94. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/__init__.py +0 -0
  95. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/code_puppy_agent/register_callbacks.py +0 -0
  96. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/NativeCapture.swift +0 -0
  97. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/README.md +0 -0
  98. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/__init__.py +0 -0
  99. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/accessibility.py +0 -0
  100. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/activation.py +0 -0
  101. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/backend.py +0 -0
  102. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/backend_types.py +0 -0
  103. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/capture.py +0 -0
  104. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/commands.py +0 -0
  105. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/geometry.py +0 -0
  106. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/inline_image.py +0 -0
  107. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/keycodes.py +0 -0
  108. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/policy.py +0 -0
  109. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/register_callbacks.py +0 -0
  110. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/safety.py +0 -0
  111. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/settle.py +0 -0
  112. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/state.py +0 -0
  113. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/computer_use/tools.py +0 -0
  114. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/context_indicator/__init__.py +0 -0
  115. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/context_indicator/register_callbacks.py +0 -0
  116. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/context_indicator/usage.py +0 -0
  117. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/copilot_auth/__init__.py +0 -0
  118. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/copilot_auth/config.py +0 -0
  119. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/copilot_auth/reasoning_client.py +0 -0
  120. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/copilot_auth/register_callbacks.py +0 -0
  121. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/copilot_auth/utils.py +0 -0
  122. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/customizable_commands/__init__.py +0 -0
  123. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/customizable_commands/register_callbacks.py +0 -0
  124. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/__init__.py +0 -0
  125. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/cancel.py +0 -0
  126. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/commands.py +0 -0
  127. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/config.py +0 -0
  128. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/lifecycle.py +0 -0
  129. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/register_callbacks.py +0 -0
  130. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/runtime.py +0 -0
  131. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/startup_lock.py +0 -0
  132. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/workflow_ids.py +0 -0
  133. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/dbos_durable_exec/wrapper.py +0 -0
  134. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/destructive_command_guard/AGENTS.md +0 -0
  135. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/destructive_command_guard/__init__.py +0 -0
  136. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/destructive_command_guard/detector.py +0 -0
  137. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/destructive_command_guard/register_callbacks.py +0 -0
  138. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/emoji_filter/__init__.py +0 -0
  139. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/emoji_filter/config.py +0 -0
  140. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/emoji_filter/register_callbacks.py +0 -0
  141. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/emoji_filter/stripper.py +0 -0
  142. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/empty_html_comment_filter/register_callbacks.py +0 -0
  143. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/example_custom_command/README.md +0 -0
  144. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/example_custom_command/register_callbacks.py +0 -0
  145. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/file_permission_handler/__init__.py +0 -0
  146. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/__init__.py +0 -0
  147. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/README.md +0 -0
  148. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/cheatsheet.md +0 -0
  149. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/pipeline.md +0 -0
  150. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/synopsis.md +0 -0
  151. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/about.md +0 -0
  152. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/address-feedback.md +0 -0
  153. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/ask.md +0 -0
  154. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/aug.md +0 -0
  155. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/auto-pilot.md +0 -0
  156. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/cheatsheet.md +0 -0
  157. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/commit.md +0 -0
  158. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/config.md +0 -0
  159. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/create-pr.md +0 -0
  160. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/exec.md +0 -0
  161. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/new.md +0 -0
  162. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/qa.md +0 -0
  163. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/rebase.md +0 -0
  164. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/review.md +0 -0
  165. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/split.md +0 -0
  166. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/squash-commits.md +0 -0
  167. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/status.md +0 -0
  168. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/tests.md +0 -0
  169. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_about.py +0 -0
  170. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_cheatsheet.py +0 -0
  171. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_status.py +0 -0
  172. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/installer.py +0 -0
  173. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/flux_bootstrap/register_callbacks.py +0 -0
  174. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/force_push_guard/__init__.py +0 -0
  175. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/force_push_guard/detector.py +0 -0
  176. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/force_push_guard/register_callbacks.py +0 -0
  177. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/fork/__init__.py +0 -0
  178. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/fork/register_callbacks.py +0 -0
  179. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/frontend_emitter/__init__.py +0 -0
  180. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/frontend_emitter/emitter.py +0 -0
  181. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/frontend_emitter/register_callbacks.py +0 -0
  182. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/frontend_emitter/session_context.py +0 -0
  183. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/grok_oauth/__init__.py +0 -0
  184. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/grok_oauth/config.py +0 -0
  185. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/grok_oauth/oauth_flow.py +0 -0
  186. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/grok_oauth/register_callbacks.py +0 -0
  187. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/grok_oauth/utils.py +0 -0
  188. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/herdr/README.md +0 -0
  189. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/herdr/__init__.py +0 -0
  190. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/herdr/client.py +0 -0
  191. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/herdr/register_callbacks.py +0 -0
  192. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/herdr/reporter.py +0 -0
  193. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/herdr/smoke.py +0 -0
  194. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/herdr/sources.py +0 -0
  195. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/hook_creator/__init__.py +0 -0
  196. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/hook_creator/register_callbacks.py +0 -0
  197. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/hook_manager/__init__.py +0 -0
  198. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/hook_manager/config.py +0 -0
  199. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/hook_manager/hooks_menu.py +0 -0
  200. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/hook_manager/register_callbacks.py +0 -0
  201. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/hook_manager/trust_handler.py +0 -0
  202. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_oauth/__init__.py +0 -0
  203. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_oauth/oauth.py +0 -0
  204. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_oauth/query_tool.py +0 -0
  205. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_oauth/register_callbacks.py +0 -0
  206. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_sessions/__init__.py +0 -0
  207. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_sessions/mirror.py +0 -0
  208. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_sessions/query.py +0 -0
  209. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_sessions/register_callbacks.py +0 -0
  210. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/logfire_sessions/sync.py +0 -0
  211. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/meta_oauth/__init__.py +0 -0
  212. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/meta_oauth/config.py +0 -0
  213. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/meta_oauth/oauth_flow.py +0 -0
  214. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/meta_oauth/register_callbacks.py +0 -0
  215. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/meta_oauth/utils.py +0 -0
  216. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/namespace_skill_search/README.md +0 -0
  217. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/namespace_skill_search/__init__.py +0 -0
  218. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/namespace_skill_search/namespaces.py +0 -0
  219. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/namespace_skill_search/register_callbacks.py +0 -0
  220. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/namespace_skill_search/search_tool.py +0 -0
  221. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/no_tools/__init__.py +0 -0
  222. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/no_tools/register_callbacks.py +0 -0
  223. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/oauth_pasteback.py +0 -0
  224. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/oauth_puppy_html.py +0 -0
  225. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/obsidian_agent/README.md +0 -0
  226. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/obsidian_agent/__init__.py +0 -0
  227. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/obsidian_agent/agent_obsidian.py +0 -0
  228. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/obsidian_agent/register_callbacks.py +0 -0
  229. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/ollama/__init__.py +0 -0
  230. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/ollama/register_callbacks.py +0 -0
  231. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/ollama_setup/__init__.py +0 -0
  232. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/ollama_setup/completer.py +0 -0
  233. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/ollama_setup/register_callbacks.py +0 -0
  234. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/plugin_list/__init__.py +0 -0
  235. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/plugin_list/plugin_contributions.py +0 -0
  236. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/plugin_list/plugin_meta.py +0 -0
  237. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/plugin_list/plugin_text_utils.py +0 -0
  238. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/plugin_list/plugins_menu.py +0 -0
  239. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/plugin_list/plugins_menu_render.py +0 -0
  240. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/plugin_list/project_trust_flow.py +0 -0
  241. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/plugin_list/register_callbacks.py +0 -0
  242. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/pop_command/__init__.py +0 -0
  243. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/pop_command/register_callbacks.py +0 -0
  244. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/prompt_newline/__init__.py +0 -0
  245. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/prompt_newline/config.py +0 -0
  246. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/prompt_newline/register_callbacks.py +0 -0
  247. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/prune/__init__.py +0 -0
  248. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/prune/prune_menu.py +0 -0
  249. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/prune/prune_model.py +0 -0
  250. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/prune/prune_render.py +0 -0
  251. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/prune/register_callbacks.py +0 -0
  252. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/README.md +0 -0
  253. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/__init__.py +0 -0
  254. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/commands.py +0 -0
  255. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/config.py +0 -0
  256. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/kennel.py +0 -0
  257. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/packer.py +0 -0
  258. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/recorder.py +0 -0
  259. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/register_callbacks.py +0 -0
  260. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/retriever.py +0 -0
  261. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/schema.py +0 -0
  262. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/state.py +0 -0
  263. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/tools.py +0 -0
  264. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_kennel/wings.py +0 -0
  265. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_spinner/README.md +0 -0
  266. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_spinner/__init__.py +0 -0
  267. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_spinner/builtin_frames.py +0 -0
  268. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_spinner/commands.py +0 -0
  269. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_spinner/picker.py +0 -0
  270. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_spinner/register_callbacks.py +0 -0
  271. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/puppy_spinner/spinners.py +0 -0
  272. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/qa_kitten_skill/SKILL.md +0 -0
  273. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/qa_kitten_skill/__init__.py +0 -0
  274. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/qa_kitten_skill/register_callbacks.py +0 -0
  275. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/quick_resume/__init__.py +0 -0
  276. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/quick_resume/register_callbacks.py +0 -0
  277. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/review_pr/__init__.py +0 -0
  278. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/review_pr/register_callbacks.py +0 -0
  279. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/session_namer/__init__.py +0 -0
  280. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/session_namer/namer.py +0 -0
  281. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/session_namer/register_callbacks.py +0 -0
  282. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/shell_safety/__init__.py +0 -0
  283. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/shell_safety/agent_shell_safety.py +0 -0
  284. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/shell_safety/command_cache.py +0 -0
  285. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/shell_safety/register_callbacks.py +0 -0
  286. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/spill/LICENSE.deepseek +0 -0
  287. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/spill/__init__.py +0 -0
  288. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/spill/register_callbacks.py +0 -0
  289. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/spill/store.py +0 -0
  290. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/stack_dump/__init__.py +0 -0
  291. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/stack_dump/register_callbacks.py +0 -0
  292. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/statusline/__init__.py +0 -0
  293. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/statusline/config.py +0 -0
  294. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/statusline/payload.py +0 -0
  295. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/statusline/prompt_patch.py +0 -0
  296. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/statusline/register_callbacks.py +0 -0
  297. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/statusline/runner.py +0 -0
  298. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/statusline/statusline_command.py +0 -0
  299. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/steer_queue/__init__.py +0 -0
  300. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/steer_queue/queue_menu.py +0 -0
  301. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/steer_queue/register_callbacks.py +0 -0
  302. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/subagent_panel/README.md +0 -0
  303. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/subagent_panel/__init__.py +0 -0
  304. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/subagent_panel/coalesce_patch.py +0 -0
  305. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/subagent_panel/panel_render.py +0 -0
  306. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/subagent_panel/register_callbacks.py +0 -0
  307. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/subagent_panel/resume_repaint.py +0 -0
  308. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/subagent_panel/state.py +0 -0
  309. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/switch_agent_resume/__init__.py +0 -0
  310. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/switch_agent_resume/register_callbacks.py +0 -0
  311. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/termflow_tui.py +0 -0
  312. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/README.md +0 -0
  313. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/__init__.py +0 -0
  314. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/bundled_palettes.py +0 -0
  315. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/content_styles.py +0 -0
  316. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/osc_palette.py +0 -0
  317. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/picker.py +0 -0
  318. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/prompt_toolkit_theme.py +0 -0
  319. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/register_callbacks.py +0 -0
  320. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/rich_themes.py +0 -0
  321. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/theme/themes.py +0 -0
  322. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/timestamp_heartbeat/__init__.py +0 -0
  323. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/timestamp_heartbeat/register_callbacks.py +0 -0
  324. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/token_ratio_learner/__init__.py +0 -0
  325. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/token_ratio_learner/ratios.py +0 -0
  326. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/token_ratio_learner/register_callbacks.py +0 -0
  327. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/universal_constructor/__init__.py +0 -0
  328. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/universal_constructor/models.py +0 -0
  329. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/universal_constructor/provider.py +0 -0
  330. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/universal_constructor/register_callbacks.py +0 -0
  331. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/universal_constructor/registry.py +0 -0
  332. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/universal_constructor/sandbox.py +0 -0
  333. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/web_retriever_skill/SKILL.md +0 -0
  334. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/web_retriever_skill/__init__.py +0 -0
  335. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/web_retriever_skill/register_callbacks.py +0 -0
  336. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/wiggum/__init__.py +0 -0
  337. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/wiggum/goal_runs.py +0 -0
  338. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/wiggum/judge.py +0 -0
  339. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/wiggum/judge_config.py +0 -0
  340. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/wiggum/judges_menu.py +0 -0
  341. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/wiggum/register_callbacks.py +0 -0
  342. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/wiggum/state.py +0 -0
  343. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/yolo_cli/__init__.py +0 -0
  344. {code_puppy_core_plugins-0.0.26 → code_puppy_core_plugins-0.0.28}/code_puppy_core_plugins/yolo_cli/register_callbacks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: code-puppy-core-plugins
3
- Version: 0.0.26
3
+ Version: 0.0.28
4
4
  Summary: Official plugin bundle for Code Puppy
5
5
  Project-URL: Repository, https://github.com/mpfaffenberger/code_puppy_core_plugins
6
6
  Project-URL: Homepage, https://github.com/mpfaffenberger/code_puppy_core_plugins
@@ -17,11 +17,26 @@ from code_puppy.tools.file_permission_state import (
17
17
  register_file_permission_state_provider,
18
18
  )
19
19
  from code_puppy.tools.common import (
20
- _find_best_window,
21
20
  get_user_approval,
22
21
  get_user_approval_async,
23
22
  )
24
23
 
24
+ try:
25
+ # Preferred: the edit engine's own pure replacement function, so the
26
+ # permission preview shows exactly what the engine will do (including
27
+ # refusing ambiguous or unmatched edits). Available on code-puppy
28
+ # versions with Claude Code-parity edit semantics.
29
+ from code_puppy.tools.file_modifications import apply_replacements_to_content
30
+ except ImportError: # pragma: no cover - older code-puppy versions
31
+ apply_replacements_to_content = None
32
+
33
+ try:
34
+ # Legacy fuzzy matcher, only used for previews on older code-puppy
35
+ # versions whose engine still fuzzy-matches.
36
+ from code_puppy.tools.common import _find_best_window
37
+ except ImportError: # pragma: no cover - future code-puppy versions
38
+ _find_best_window = None
39
+
25
40
  # NOTE: module-level ``_FILE_CONFIRMATION_LOCK`` removed — queueing of parallel
26
41
  # approvals now lives inside ``get_user_approval`` (they line up, never auto-rejected).
27
42
 
@@ -148,35 +163,19 @@ def _preview_replace_in_file(
148
163
  except (UnicodeEncodeError, UnicodeDecodeError):
149
164
  pass
150
165
 
151
- modified = original
152
- for rep in replacements:
153
- old_snippet = rep.get("old_str", "")
154
- new_snippet = rep.get("new_str", "")
155
-
156
- if old_snippet and old_snippet in modified:
157
- modified = modified.replace(old_snippet, new_snippet)
158
- continue
159
-
160
- # Use the same logic as file_modifications for fuzzy matching
161
- orig_lines = modified.splitlines()
162
- loc, score = _find_best_window(orig_lines, old_snippet)
163
-
164
- if score < 0.95 or loc is None:
166
+ if apply_replacements_to_content is not None:
167
+ # Single source of truth: run the engine's own pure replacement
168
+ # logic. If the engine would refuse (not found / ambiguous /
169
+ # no-op), there is nothing truthful to preview.
170
+ engine_result = apply_replacements_to_content(original, replacements)
171
+ if "error" in engine_result:
165
172
  return None
166
-
167
- start, end = loc
168
- had_trailing_newline = modified.endswith("\n")
169
- prefix = "\n".join(orig_lines[:start])
170
- suffix = "\n".join(orig_lines[end:])
171
- parts = []
172
- if prefix:
173
- parts.append(prefix)
174
- parts.append(new_snippet.rstrip("\n"))
175
- if suffix:
176
- parts.append(suffix)
177
- modified = "\n".join(parts)
178
- if had_trailing_newline and not modified.endswith("\n"):
179
- modified += "\n"
173
+ modified = engine_result["content"]
174
+ else:
175
+ legacy = _legacy_fuzzy_preview(original, replacements)
176
+ if legacy is None:
177
+ return None
178
+ modified = legacy
180
179
 
181
180
  if modified == original:
182
181
  return None
@@ -195,6 +194,44 @@ def _preview_replace_in_file(
195
194
  return None
196
195
 
197
196
 
197
+ def _legacy_fuzzy_preview(
198
+ original: str, replacements: list[dict[str, str]]
199
+ ) -> str | None:
200
+ """Mirror the pre-Claude-parity engine (exact-then-fuzzy) for old cores."""
201
+ if _find_best_window is None:
202
+ return None
203
+ modified = original
204
+ for rep in replacements:
205
+ old_snippet = rep.get("old_str", "")
206
+ new_snippet = rep.get("new_str", "")
207
+
208
+ if old_snippet and old_snippet in modified:
209
+ modified = modified.replace(old_snippet, new_snippet)
210
+ continue
211
+
212
+ # Same logic as the legacy file_modifications fuzzy matcher
213
+ orig_lines = modified.splitlines()
214
+ loc, score = _find_best_window(orig_lines, old_snippet)
215
+
216
+ if score < 0.95 or loc is None:
217
+ return None
218
+
219
+ start, end = loc
220
+ had_trailing_newline = modified.endswith("\n")
221
+ prefix = "\n".join(orig_lines[:start])
222
+ suffix = "\n".join(orig_lines[end:])
223
+ parts = []
224
+ if prefix:
225
+ parts.append(prefix)
226
+ parts.append(new_snippet.rstrip("\n"))
227
+ if suffix:
228
+ parts.append(suffix)
229
+ modified = "\n".join(parts)
230
+ if had_trailing_newline and not modified.endswith("\n"):
231
+ modified += "\n"
232
+ return modified
233
+
234
+
198
235
  def _preview_delete_file(file_path: str) -> str | None:
199
236
  """Generate a preview diff for deleting a file without modifying it."""
200
237
  try:
@@ -0,0 +1,6 @@
1
+ """OpenRouter OAuth PKCE plugin.
2
+
3
+ One-click browser sign-in that exchanges an authorization code for a
4
+ user-controlled OpenRouter API key, wired into the ``/add_model`` flow via
5
+ the ``provider_credential_flow`` hook.
6
+ """
@@ -0,0 +1,21 @@
1
+ """Configuration for the OpenRouter OAuth PKCE flow.
2
+
3
+ OpenRouter's flow is deliberately simple: no client id, no scopes, no
4
+ refresh tokens. The authorization code is exchanged at ``keys_url`` for a
5
+ user-controlled API key. Localhost callbacks are supported on any port, so
6
+ we bind an ephemeral one. See https://openrouter.ai/docs/use-cases/oauth-pkce
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ OPENROUTER_OAUTH_CONFIG = {
12
+ "auth_url": "https://openrouter.ai/auth",
13
+ "keys_url": "https://openrouter.ai/api/v1/auth/keys",
14
+ "env_var": "OPENROUTER_API_KEY",
15
+ "provider_id": "openrouter",
16
+ "redirect_host": "localhost",
17
+ "redirect_path": "/callback",
18
+ # OpenRouter authorization codes are single-use and expire after 10
19
+ # minutes; give the user most of that window.
20
+ "callback_timeout": 540,
21
+ }
@@ -0,0 +1,242 @@
1
+ """OpenRouter OAuth PKCE flow.
2
+
3
+ Follows https://openrouter.ai/docs/use-cases/oauth-pkce: send the user to
4
+ ``/auth`` with an S256 code challenge, receive the authorization code on a
5
+ localhost callback (any port is allowed), then exchange code + verifier at
6
+ ``/api/v1/auth/keys`` for a user-controlled API key. There is no state
7
+ parameter in OpenRouter's flow -- PKCE is the integrity mechanism, and the
8
+ code is single-use with a 10 minute expiry.
9
+
10
+ The key is persisted via :func:`code_puppy.provider_credentials.save_credential`
11
+ so it is immediately usable by the model factory (puppy.cfg + os.environ).
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import base64
17
+ import hashlib
18
+ import secrets
19
+ import threading
20
+ import time
21
+ import urllib.parse
22
+ from http.server import BaseHTTPRequestHandler, HTTPServer
23
+ from typing import Any, Tuple
24
+
25
+ import requests
26
+
27
+ from code_puppy.messaging import emit_error, emit_info, emit_success, emit_warning
28
+ from code_puppy.provider_credentials import save_credential
29
+
30
+ from ..oauth_pasteback import parse_oauth_callback_input, read_available_stdin_line
31
+ from ..oauth_puppy_html import oauth_failure_html, oauth_success_html
32
+ from .config import OPENROUTER_OAUTH_CONFIG
33
+
34
+
35
+ def generate_pkce_pair() -> Tuple[str, str]:
36
+ """Return an S256 ``(code_verifier, code_challenge)`` pair."""
37
+ verifier = secrets.token_urlsafe(64)
38
+ digest = hashlib.sha256(verifier.encode("ascii")).digest()
39
+ challenge = base64.urlsafe_b64encode(digest).rstrip(b"=").decode("ascii")
40
+ return verifier, challenge
41
+
42
+
43
+ def exchange_code_for_key(code: str, code_verifier: str) -> str:
44
+ """Exchange an authorization code for a user-controlled API key.
45
+
46
+ Raises on HTTP errors or a malformed response so callers can surface
47
+ the failure; returns the API key on success.
48
+ """
49
+ response = requests.post(
50
+ OPENROUTER_OAUTH_CONFIG["keys_url"],
51
+ json={
52
+ "code": code,
53
+ "code_verifier": code_verifier,
54
+ "code_challenge_method": "S256",
55
+ },
56
+ timeout=30,
57
+ )
58
+ response.raise_for_status()
59
+ key = response.json().get("key")
60
+ if not key:
61
+ raise RuntimeError("OpenRouter response did not include an API key")
62
+ return key
63
+
64
+
65
+ def _save_key(key: str) -> None:
66
+ save_credential(OPENROUTER_OAUTH_CONFIG["env_var"], key)
67
+
68
+
69
+ class _OAuthServer(HTTPServer):
70
+ """Localhost callback server holding the state for one OAuth attempt."""
71
+
72
+ def __init__(self) -> None:
73
+ host = OPENROUTER_OAUTH_CONFIG["redirect_host"]
74
+ # OpenRouter explicitly supports localhost callbacks on any port.
75
+ super().__init__((host, 0), _CallbackHandler)
76
+
77
+ self.exit_code = 1
78
+ self.code_verifier, self.code_challenge = generate_pkce_pair()
79
+ port = self.server_address[1]
80
+ path = OPENROUTER_OAUTH_CONFIG["redirect_path"]
81
+ self.callback_url = f"http://{host}:{port}{path}"
82
+
83
+ def auth_url(self) -> str:
84
+ params = {
85
+ "callback_url": self.callback_url,
86
+ "code_challenge": self.code_challenge,
87
+ "code_challenge_method": "S256",
88
+ }
89
+ return f"{OPENROUTER_OAUTH_CONFIG['auth_url']}?{urllib.parse.urlencode(params)}"
90
+
91
+ def exchange_code(self, code: str) -> None:
92
+ _save_key(exchange_code_for_key(code, self.code_verifier))
93
+
94
+
95
+ class _CallbackHandler(BaseHTTPRequestHandler):
96
+ server: "_OAuthServer"
97
+
98
+ def do_GET(self) -> None: # noqa: N802
99
+ parsed = urllib.parse.urlparse(self.path)
100
+ if parsed.path != OPENROUTER_OAUTH_CONFIG["redirect_path"]:
101
+ self._send_failure(404, "Callback endpoint not found for the puppy parade.")
102
+ return
103
+
104
+ params = urllib.parse.parse_qs(parsed.query)
105
+ error = params.get("error", [None])[0]
106
+ if error:
107
+ description = params.get("error_description", [error])[0]
108
+ self._send_failure(400, f"OpenRouter authorization failed: {description}")
109
+ self._shutdown_after_delay()
110
+ return
111
+
112
+ code = params.get("code", [None])[0]
113
+ if not code:
114
+ self._send_failure(400, "Missing auth code — the token treat rolled away.")
115
+ self._shutdown_after_delay()
116
+ return
117
+
118
+ try:
119
+ self.server.exchange_code(code)
120
+ except Exception as exc: # noqa: BLE001
121
+ self._send_failure(500, f"Key exchange failed: {exc}")
122
+ self._shutdown_after_delay()
123
+ return
124
+
125
+ self.server.exit_code = 0
126
+ self._send_html(
127
+ oauth_success_html(
128
+ "OpenRouter",
129
+ "You can now close this window and return to Code Puppy.",
130
+ )
131
+ )
132
+ self._shutdown_after_delay()
133
+
134
+ def log_message(self, fmt: str, *args: Any) -> None: # noqa: A003
135
+ pass
136
+
137
+ def _send_html(self, body: str, status: int = 200) -> None:
138
+ encoded = body.encode("utf-8")
139
+ self.send_response(status)
140
+ self.send_header("Content-Type", "text/html; charset=utf-8")
141
+ self.send_header("Content-Length", str(len(encoded)))
142
+ self.end_headers()
143
+ self.wfile.write(encoded)
144
+
145
+ def _send_failure(self, status: int, reason: str) -> None:
146
+ self._send_html(oauth_failure_html("OpenRouter", reason), status)
147
+
148
+ def _shutdown_after_delay(self, seconds: float = 2.0) -> None:
149
+ def _later() -> None:
150
+ time.sleep(seconds)
151
+ self.server.shutdown()
152
+
153
+ threading.Thread(target=_later, daemon=True).start()
154
+
155
+
156
+ def _complete_pasted_input(raw_input: str, code_verifier: str) -> bool:
157
+ """Exchange a pasted callback URL / bare code for an API key."""
158
+ try:
159
+ parsed = parse_oauth_callback_input(raw_input)
160
+ except ValueError as exc:
161
+ emit_error(f"Could not parse pasted OAuth input: {exc}")
162
+ return False
163
+
164
+ if parsed.error:
165
+ emit_error(f"OpenRouter returned an error: {parsed.error_message}")
166
+ return False
167
+ if not parsed.code:
168
+ emit_error("Pasted OAuth input did not contain an authorization code.")
169
+ return False
170
+
171
+ try:
172
+ _save_key(exchange_code_for_key(parsed.code, code_verifier))
173
+ except Exception as exc: # noqa: BLE001
174
+ emit_error(f"Key exchange failed: {exc}")
175
+ return False
176
+ return True
177
+
178
+
179
+ def _wait_for_completion(server: _OAuthServer) -> bool:
180
+ """Poll for the localhost callback, accepting pasted input meanwhile."""
181
+ emit_info(
182
+ "Waiting for the OpenRouter callback. If localhost cannot be reached "
183
+ "(SSH, container), paste the full callback URL or authorization code "
184
+ "here and press Enter."
185
+ )
186
+
187
+ elapsed = 0.0
188
+ timeout = OPENROUTER_OAUTH_CONFIG["callback_timeout"]
189
+ interval = 0.25
190
+ while elapsed < timeout:
191
+ if server.exit_code == 0:
192
+ return True
193
+
194
+ pasted = read_available_stdin_line()
195
+ if pasted is not None and pasted.strip():
196
+ if _complete_pasted_input(pasted, server.code_verifier):
197
+ return True
198
+
199
+ time.sleep(interval)
200
+ elapsed += interval
201
+ return False
202
+
203
+
204
+ def run_oauth_flow() -> bool:
205
+ """Run the browser PKCE flow. Returns True when a key was saved."""
206
+ try:
207
+ server = _OAuthServer()
208
+ except Exception as exc: # noqa: BLE001
209
+ emit_error(f"Could not start OpenRouter OAuth flow: {exc}")
210
+ return False
211
+
212
+ auth_url = server.auth_url()
213
+ emit_info(f"Open this URL in your browser: {auth_url}")
214
+
215
+ server_thread = threading.Thread(target=server.serve_forever, daemon=True)
216
+ server_thread.start()
217
+
218
+ from code_puppy.tools.common import should_suppress_browser
219
+
220
+ if should_suppress_browser():
221
+ emit_info(f"[HEADLESS MODE] Would normally open: {auth_url}")
222
+ else:
223
+ try:
224
+ import webbrowser
225
+
226
+ if not webbrowser.open(auth_url):
227
+ emit_warning("Please open the URL manually — the browser stayed home.")
228
+ except Exception as exc: # noqa: BLE001
229
+ emit_warning(f"Could not open browser automatically: {exc}")
230
+
231
+ completed = _wait_for_completion(server)
232
+
233
+ server.shutdown()
234
+ server_thread.join(timeout=5)
235
+
236
+ if not completed:
237
+ emit_error("OpenRouter authentication failed or timed out.")
238
+ return False
239
+
240
+ env_var = OPENROUTER_OAUTH_CONFIG["env_var"]
241
+ emit_success(f"OpenRouter OAuth complete — API key saved as {env_var}.")
242
+ return True
@@ -0,0 +1,93 @@
1
+ """OpenRouter OAuth plugin callbacks.
2
+
3
+ Hooks into the ``/add_model`` credential step: when the user adds an
4
+ OpenRouter model and ``OPENROUTER_API_KEY`` is not set, offer the one-click
5
+ browser PKCE sign-in before falling back to manual key entry.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import logging
11
+ from typing import Optional
12
+
13
+ from code_puppy.callbacks import register_callback
14
+
15
+ from .config import OPENROUTER_OAUTH_CONFIG
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ _OAUTH = "oauth"
20
+ _MANUAL = "manual"
21
+
22
+
23
+ def _themed(builder):
24
+ """Apply the app menu theme when the host exposes it."""
25
+ try:
26
+ from code_puppy.command_line.tui_style import themed
27
+ except Exception: # noqa: BLE001 - older cores; unthemed menus still work
28
+ return builder
29
+ return themed(builder)
30
+
31
+
32
+ def build_choice_menu(**overrides):
33
+ """Menu offering browser sign-in vs manual key entry."""
34
+ from termflow.tui import MenuBuilder, MenuItem
35
+
36
+ env_var = OPENROUTER_OAUTH_CONFIG["env_var"]
37
+ builder = _themed(
38
+ MenuBuilder(f"OpenRouter needs {env_var}")
39
+ .items(
40
+ [
41
+ MenuItem(
42
+ "Sign in with OpenRouter (browser)",
43
+ value=_OAUTH,
44
+ description="OAuth PKCE — mints a key for you",
45
+ ),
46
+ MenuItem(
47
+ "Paste an API key manually",
48
+ value=_MANUAL,
49
+ description="Get one at https://openrouter.ai/keys",
50
+ ),
51
+ ]
52
+ )
53
+ .alt_screen(False)
54
+ .footer_hint("Enter select - Esc enter key manually")
55
+ )
56
+ for name, value in overrides.items():
57
+ getattr(builder, name)(value)
58
+ return builder.build()
59
+
60
+
61
+ def choose_flow(**overrides) -> str:
62
+ """Ask how to acquire the key. Esc/cancel defers to manual entry."""
63
+ result = build_choice_menu(**overrides).run()
64
+ if result.cancelled or result.item is None:
65
+ return _MANUAL
66
+ return result.item.value
67
+
68
+
69
+ def _credential_flow(*, provider_id: str, env_var: str) -> Optional[bool]:
70
+ """``provider_credential_flow`` hook: OpenRouter browser sign-in.
71
+
72
+ Returns True when a key was obtained and saved; None to defer to the
73
+ core manual-entry prompt (wrong provider, user preference, or a failed
74
+ OAuth attempt).
75
+ """
76
+ if (
77
+ provider_id != OPENROUTER_OAUTH_CONFIG["provider_id"]
78
+ or env_var != OPENROUTER_OAUTH_CONFIG["env_var"]
79
+ ):
80
+ return None
81
+ if choose_flow() != _OAUTH:
82
+ return None
83
+
84
+ from .oauth_flow import run_oauth_flow
85
+
86
+ return True if run_oauth_flow() else None
87
+
88
+
89
+ try:
90
+ register_callback("provider_credential_flow", _credential_flow)
91
+ except ValueError:
92
+ # Older core without the hook: stay quiet, /add_model still works manually.
93
+ logger.debug("Core lacks provider_credential_flow; openrouter_oauth inactive")