code-puppy-core-plugins 0.0.40__tar.gz → 0.0.41__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 (350) hide show
  1. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/PKG-INFO +29 -1
  2. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/README.md +28 -0
  3. code_puppy_core_plugins-0.0.41/code_puppy_core_plugins/completion_notification/__init__.py +1 -0
  4. code_puppy_core_plugins-0.0.41/code_puppy_core_plugins/completion_notification/config.py +19 -0
  5. code_puppy_core_plugins-0.0.41/code_puppy_core_plugins/completion_notification/locales/en-US.json +7 -0
  6. code_puppy_core_plugins-0.0.41/code_puppy_core_plugins/completion_notification/locales/es.json +7 -0
  7. code_puppy_core_plugins-0.0.41/code_puppy_core_plugins/completion_notification/locales/fr-CA.json +7 -0
  8. code_puppy_core_plugins-0.0.41/code_puppy_core_plugins/completion_notification/notifier.py +231 -0
  9. code_puppy_core_plugins-0.0.41/code_puppy_core_plugins/completion_notification/register_callbacks.py +135 -0
  10. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/pyproject.toml +2 -1
  11. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/.gitignore +0 -0
  12. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/LICENSE +0 -0
  13. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/__init__.py +0 -0
  14. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/README.md +0 -0
  15. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/__init__.py +0 -0
  16. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/agent.py +0 -0
  17. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/bridge.py +0 -0
  18. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/capabilities.py +0 -0
  19. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/commands.py +0 -0
  20. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/content.py +0 -0
  21. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/io_delegation.py +0 -0
  22. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/mcp_config.py +0 -0
  23. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/permissions.py +0 -0
  24. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/persistence.py +0 -0
  25. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/register_callbacks.py +0 -0
  26. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/replay.py +0 -0
  27. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/session.py +0 -0
  28. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/session_config.py +0 -0
  29. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/acp/state.py +0 -0
  30. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_creator_skill/SKILL.md +0 -0
  31. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_creator_skill/__init__.py +0 -0
  32. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_creator_skill/register_callbacks.py +0 -0
  33. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/__init__.py +0 -0
  34. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/config.py +0 -0
  35. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/discovery.py +0 -0
  36. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/downloader.py +0 -0
  37. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/enabled_skills.py +0 -0
  38. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/installer.py +0 -0
  39. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/metadata.py +0 -0
  40. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/prompt_builder.py +0 -0
  41. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/provider.py +0 -0
  42. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/register_callbacks.py +0 -0
  43. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/remote_catalog.py +0 -0
  44. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/skill_catalog.py +0 -0
  45. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/skill_commands.py +0 -0
  46. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/skills_install_menu.py +0 -0
  47. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/agent_skills/skills_menu.py +0 -0
  48. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/auto_continue/__init__.py +0 -0
  49. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/auto_continue/classifier.py +0 -0
  50. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/auto_continue/register_callbacks.py +0 -0
  51. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/aws_bedrock/__init__.py +0 -0
  52. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/aws_bedrock/config.py +0 -0
  53. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/aws_bedrock/register_callbacks.py +0 -0
  54. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/aws_bedrock/utils.py +0 -0
  55. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/azure_foundry/README.md +0 -0
  56. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/azure_foundry/__init__.py +0 -0
  57. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/azure_foundry/config.py +0 -0
  58. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/azure_foundry/discovery.py +0 -0
  59. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/azure_foundry/register_callbacks.py +0 -0
  60. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/azure_foundry/token.py +0 -0
  61. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/azure_foundry/utils.py +0 -0
  62. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/btw/__init__.py +0 -0
  63. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/btw/inline_view.py +0 -0
  64. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/btw/register_callbacks.py +0 -0
  65. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/btw/side_query.py +0 -0
  66. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/IMAGEGEN_SKILL.md +0 -0
  67. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/__init__.py +0 -0
  68. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/config.py +0 -0
  69. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/image_generation.py +0 -0
  70. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/image_tool.py +0 -0
  71. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/model_catalog.py +0 -0
  72. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/oauth_flow.py +0 -0
  73. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/register_callbacks.py +0 -0
  74. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/test_plugin.py +0 -0
  75. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/usage.py +0 -0
  76. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/chatgpt_oauth/utils.py +0 -0
  77. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_hooks/__init__.py +0 -0
  78. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_hooks/config.py +0 -0
  79. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_hooks/register_callbacks.py +0 -0
  80. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_hooks/trust.py +0 -0
  81. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/README.md +0 -0
  82. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/SETUP.md +0 -0
  83. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/__init__.py +0 -0
  84. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/config.py +0 -0
  85. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/fast_mode.py +0 -0
  86. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/prompt_handler.py +0 -0
  87. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/register_callbacks.py +0 -0
  88. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/test_plugin.py +0 -0
  89. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
  90. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/claude_code_oauth/utils.py +0 -0
  91. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/AGENTS_AND_TOOLS.md +0 -0
  92. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/MODELS_AND_MCP.md +0 -0
  93. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/PLUGINS_AND_CALLBACKS.md +0 -0
  94. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/SESSIONS_AND_HISTORY.md +0 -0
  95. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/SKILL.md +0 -0
  96. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/SKILLS_SYSTEM.md +0 -0
  97. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/SYSTEM_PROMPT_CONFIG_AND_I18N.md +0 -0
  98. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/__init__.py +0 -0
  99. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/code_puppy_agent/register_callbacks.py +0 -0
  100. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/NativeCapture.swift +0 -0
  101. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/README.md +0 -0
  102. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/__init__.py +0 -0
  103. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/accessibility.py +0 -0
  104. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/activation.py +0 -0
  105. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/backend.py +0 -0
  106. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/backend_types.py +0 -0
  107. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/capture.py +0 -0
  108. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/commands.py +0 -0
  109. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/geometry.py +0 -0
  110. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/inline_image.py +0 -0
  111. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/keycodes.py +0 -0
  112. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/policy.py +0 -0
  113. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/register_callbacks.py +0 -0
  114. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/safety.py +0 -0
  115. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/settle.py +0 -0
  116. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/state.py +0 -0
  117. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/computer_use/tools.py +0 -0
  118. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/context_indicator/__init__.py +0 -0
  119. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/context_indicator/register_callbacks.py +0 -0
  120. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/context_indicator/usage.py +0 -0
  121. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/copilot_auth/__init__.py +0 -0
  122. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/copilot_auth/config.py +0 -0
  123. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/copilot_auth/reasoning_client.py +0 -0
  124. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/copilot_auth/register_callbacks.py +0 -0
  125. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/copilot_auth/utils.py +0 -0
  126. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/customizable_commands/__init__.py +0 -0
  127. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/customizable_commands/register_callbacks.py +0 -0
  128. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/__init__.py +0 -0
  129. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/cancel.py +0 -0
  130. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/commands.py +0 -0
  131. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/config.py +0 -0
  132. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/lifecycle.py +0 -0
  133. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/register_callbacks.py +0 -0
  134. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/runtime.py +0 -0
  135. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/startup_lock.py +0 -0
  136. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/workflow_ids.py +0 -0
  137. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/dbos_durable_exec/wrapper.py +0 -0
  138. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/destructive_command_guard/AGENTS.md +0 -0
  139. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/destructive_command_guard/__init__.py +0 -0
  140. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/destructive_command_guard/detector.py +0 -0
  141. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/destructive_command_guard/register_callbacks.py +0 -0
  142. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/emoji_filter/__init__.py +0 -0
  143. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/emoji_filter/config.py +0 -0
  144. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/emoji_filter/register_callbacks.py +0 -0
  145. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/emoji_filter/stripper.py +0 -0
  146. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/empty_html_comment_filter/register_callbacks.py +0 -0
  147. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/example_custom_command/README.md +0 -0
  148. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/example_custom_command/register_callbacks.py +0 -0
  149. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/file_permission_handler/__init__.py +0 -0
  150. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/file_permission_handler/register_callbacks.py +0 -0
  151. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/__init__.py +0 -0
  152. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/README.md +0 -0
  153. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/cheatsheet.md +0 -0
  154. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/pipeline.md +0 -0
  155. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/synopsis.md +0 -0
  156. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/about.md +0 -0
  157. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/address-feedback.md +0 -0
  158. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/ask.md +0 -0
  159. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/aug.md +0 -0
  160. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/auto-pilot.md +0 -0
  161. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/cheatsheet.md +0 -0
  162. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/commit.md +0 -0
  163. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/config.md +0 -0
  164. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/create-pr.md +0 -0
  165. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/exec.md +0 -0
  166. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/new.md +0 -0
  167. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/qa.md +0 -0
  168. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/rebase.md +0 -0
  169. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/review.md +0 -0
  170. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/split.md +0 -0
  171. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/squash-commits.md +0 -0
  172. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/status.md +0 -0
  173. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/tests.md +0 -0
  174. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_about.py +0 -0
  175. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_cheatsheet.py +0 -0
  176. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_status.py +0 -0
  177. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/installer.py +0 -0
  178. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/flux_bootstrap/register_callbacks.py +0 -0
  179. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/force_push_guard/__init__.py +0 -0
  180. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/force_push_guard/detector.py +0 -0
  181. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/force_push_guard/register_callbacks.py +0 -0
  182. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/fork/__init__.py +0 -0
  183. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/fork/register_callbacks.py +0 -0
  184. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/frontend_emitter/__init__.py +0 -0
  185. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/frontend_emitter/emitter.py +0 -0
  186. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/frontend_emitter/register_callbacks.py +0 -0
  187. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/frontend_emitter/session_context.py +0 -0
  188. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/grok_oauth/__init__.py +0 -0
  189. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/grok_oauth/config.py +0 -0
  190. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/grok_oauth/oauth_flow.py +0 -0
  191. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/grok_oauth/register_callbacks.py +0 -0
  192. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/grok_oauth/utils.py +0 -0
  193. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/herdr/README.md +0 -0
  194. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/herdr/__init__.py +0 -0
  195. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/herdr/client.py +0 -0
  196. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/herdr/register_callbacks.py +0 -0
  197. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/herdr/reporter.py +0 -0
  198. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/herdr/smoke.py +0 -0
  199. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/herdr/sources.py +0 -0
  200. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/hook_creator/__init__.py +0 -0
  201. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/hook_creator/register_callbacks.py +0 -0
  202. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/hook_manager/__init__.py +0 -0
  203. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/hook_manager/config.py +0 -0
  204. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/hook_manager/hooks_menu.py +0 -0
  205. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/hook_manager/register_callbacks.py +0 -0
  206. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/hook_manager/trust_handler.py +0 -0
  207. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_oauth/__init__.py +0 -0
  208. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_oauth/oauth.py +0 -0
  209. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_oauth/query_tool.py +0 -0
  210. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_oauth/register_callbacks.py +0 -0
  211. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_sessions/__init__.py +0 -0
  212. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_sessions/mirror.py +0 -0
  213. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_sessions/query.py +0 -0
  214. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_sessions/register_callbacks.py +0 -0
  215. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/logfire_sessions/sync.py +0 -0
  216. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/meta_oauth/__init__.py +0 -0
  217. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/meta_oauth/config.py +0 -0
  218. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/meta_oauth/oauth_flow.py +0 -0
  219. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/meta_oauth/register_callbacks.py +0 -0
  220. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/meta_oauth/utils.py +0 -0
  221. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/namespace_skill_search/README.md +0 -0
  222. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/namespace_skill_search/__init__.py +0 -0
  223. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/namespace_skill_search/namespaces.py +0 -0
  224. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/namespace_skill_search/register_callbacks.py +0 -0
  225. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/namespace_skill_search/search_tool.py +0 -0
  226. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/no_tools/__init__.py +0 -0
  227. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/no_tools/register_callbacks.py +0 -0
  228. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/oauth_pasteback.py +0 -0
  229. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/oauth_puppy_html.py +0 -0
  230. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/obsidian_agent/README.md +0 -0
  231. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/obsidian_agent/__init__.py +0 -0
  232. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/obsidian_agent/agent_obsidian.py +0 -0
  233. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/obsidian_agent/register_callbacks.py +0 -0
  234. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/ollama/__init__.py +0 -0
  235. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/ollama/register_callbacks.py +0 -0
  236. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/ollama_setup/__init__.py +0 -0
  237. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/ollama_setup/completer.py +0 -0
  238. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/ollama_setup/register_callbacks.py +0 -0
  239. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/openrouter_oauth/__init__.py +0 -0
  240. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/openrouter_oauth/config.py +0 -0
  241. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/openrouter_oauth/oauth_flow.py +0 -0
  242. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/openrouter_oauth/register_callbacks.py +0 -0
  243. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/openrouter_oauth/test_plugin.py +0 -0
  244. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/plugin_list/__init__.py +0 -0
  245. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/plugin_list/plugin_contributions.py +0 -0
  246. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/plugin_list/plugin_meta.py +0 -0
  247. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/plugin_list/plugin_text_utils.py +0 -0
  248. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/plugin_list/plugins_menu.py +0 -0
  249. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/plugin_list/plugins_menu_render.py +0 -0
  250. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/plugin_list/project_trust_flow.py +0 -0
  251. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/plugin_list/register_callbacks.py +0 -0
  252. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/pop_command/__init__.py +0 -0
  253. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/pop_command/register_callbacks.py +0 -0
  254. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/prompt_newline/__init__.py +0 -0
  255. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/prompt_newline/config.py +0 -0
  256. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/prompt_newline/register_callbacks.py +0 -0
  257. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/prune/__init__.py +0 -0
  258. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/prune/prune_menu.py +0 -0
  259. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/prune/prune_model.py +0 -0
  260. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/prune/prune_render.py +0 -0
  261. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/prune/register_callbacks.py +0 -0
  262. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/README.md +0 -0
  263. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/__init__.py +0 -0
  264. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/commands.py +0 -0
  265. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/config.py +0 -0
  266. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/kennel.py +0 -0
  267. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/packer.py +0 -0
  268. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/recorder.py +0 -0
  269. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/register_callbacks.py +0 -0
  270. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/retriever.py +0 -0
  271. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/schema.py +0 -0
  272. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/state.py +0 -0
  273. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/tools.py +0 -0
  274. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_kennel/wings.py +0 -0
  275. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_spinner/README.md +0 -0
  276. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_spinner/__init__.py +0 -0
  277. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_spinner/builtin_frames.py +0 -0
  278. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_spinner/commands.py +0 -0
  279. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_spinner/picker.py +0 -0
  280. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_spinner/register_callbacks.py +0 -0
  281. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/puppy_spinner/spinners.py +0 -0
  282. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/qa_kitten_skill/SKILL.md +0 -0
  283. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/qa_kitten_skill/__init__.py +0 -0
  284. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/qa_kitten_skill/register_callbacks.py +0 -0
  285. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/quick_resume/__init__.py +0 -0
  286. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/quick_resume/register_callbacks.py +0 -0
  287. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/review_pr/__init__.py +0 -0
  288. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/review_pr/register_callbacks.py +0 -0
  289. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/session_namer/__init__.py +0 -0
  290. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/session_namer/namer.py +0 -0
  291. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/session_namer/register_callbacks.py +0 -0
  292. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/spill/LICENSE.deepseek +0 -0
  293. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/spill/__init__.py +0 -0
  294. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/spill/register_callbacks.py +0 -0
  295. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/spill/store.py +0 -0
  296. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/stack_dump/__init__.py +0 -0
  297. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/stack_dump/register_callbacks.py +0 -0
  298. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/statusline/__init__.py +0 -0
  299. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/statusline/config.py +0 -0
  300. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/statusline/payload.py +0 -0
  301. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/statusline/prompt_patch.py +0 -0
  302. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/statusline/register_callbacks.py +0 -0
  303. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/statusline/runner.py +0 -0
  304. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/statusline/statusline_command.py +0 -0
  305. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/steer_queue/__init__.py +0 -0
  306. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/steer_queue/queue_menu.py +0 -0
  307. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/steer_queue/register_callbacks.py +0 -0
  308. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/subagent_panel/README.md +0 -0
  309. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/subagent_panel/__init__.py +0 -0
  310. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/subagent_panel/coalesce_patch.py +0 -0
  311. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/subagent_panel/panel_render.py +0 -0
  312. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/subagent_panel/register_callbacks.py +0 -0
  313. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/subagent_panel/resume_repaint.py +0 -0
  314. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/subagent_panel/state.py +0 -0
  315. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/switch_agent_resume/__init__.py +0 -0
  316. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/switch_agent_resume/register_callbacks.py +0 -0
  317. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/termflow_tui.py +0 -0
  318. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/README.md +0 -0
  319. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/__init__.py +0 -0
  320. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/bundled_palettes.py +0 -0
  321. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/content_styles.py +0 -0
  322. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/osc_palette.py +0 -0
  323. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/picker.py +0 -0
  324. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/prompt_toolkit_theme.py +0 -0
  325. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/register_callbacks.py +0 -0
  326. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/rich_themes.py +0 -0
  327. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/theme/themes.py +0 -0
  328. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/timestamp_heartbeat/__init__.py +0 -0
  329. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/timestamp_heartbeat/register_callbacks.py +0 -0
  330. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/token_ratio_learner/__init__.py +0 -0
  331. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/token_ratio_learner/ratios.py +0 -0
  332. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/token_ratio_learner/register_callbacks.py +0 -0
  333. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/universal_constructor/__init__.py +0 -0
  334. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/universal_constructor/models.py +0 -0
  335. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/universal_constructor/provider.py +0 -0
  336. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/universal_constructor/register_callbacks.py +0 -0
  337. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/universal_constructor/registry.py +0 -0
  338. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/universal_constructor/sandbox.py +0 -0
  339. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/web_retriever_skill/SKILL.md +0 -0
  340. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/web_retriever_skill/__init__.py +0 -0
  341. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/web_retriever_skill/register_callbacks.py +0 -0
  342. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/wiggum/__init__.py +0 -0
  343. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/wiggum/goal_runs.py +0 -0
  344. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/wiggum/judge.py +0 -0
  345. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/wiggum/judge_config.py +0 -0
  346. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/wiggum/judges_menu.py +0 -0
  347. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/wiggum/register_callbacks.py +0 -0
  348. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/wiggum/state.py +0 -0
  349. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/code_puppy_core_plugins/yolo_cli/__init__.py +0 -0
  350. {code_puppy_core_plugins-0.0.40 → code_puppy_core_plugins-0.0.41}/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.40
3
+ Version: 0.0.41
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
@@ -55,6 +55,34 @@ The package deliberately does not depend on `code-puppy` in its own metadata.
55
55
  `code-puppy` depends on this bundle; adding the reverse edge would create a
56
56
  packaging dependency cycle. Plugin CI installs the core runtime separately.
57
57
 
58
+ ## Completion notifications
59
+
60
+ The `completion_notification` plugin is disabled by default. Enable a native,
61
+ best-effort desktop notification after a successful top-level response with:
62
+
63
+ ```text
64
+ /set completion_notifications=true
65
+ ```
66
+
67
+ Notifications use a sanitized, shortened copy of the latest user prompt as the
68
+ title and a shortened response preview as the body, with Apple Terminal, iTerm2,
69
+ or Warp labeled through `TERM_PROGRAM` when available. Unknown terminals omit
70
+ the terminal label. Sub-agent completions are intentionally silent. Desktop
71
+ notification centers may retain visible prompt and response previews.
72
+
73
+ Optional sound configuration is platform-aware:
74
+
75
+ ```text
76
+ /set completion_notification_sound=Frog
77
+ ```
78
+
79
+ On macOS, a simple name selects a system sound (`Frog`, `Glass`, `Ping`, etc.).
80
+ Preview one with `afplay /System/Library/Sounds/Frog.aiff`. On any platform, an
81
+ absolute path to a local sound file is accepted when an available platform
82
+ player can play it. Linux uses `notify-send` for desktop notifications when it
83
+ is installed; Windows uses a best-effort PowerShell toast. No external Python
84
+ dependencies are required.
85
+
58
86
  ## Releases
59
87
 
60
88
  Pushes to `main` run lint and tests, bump the patch version, build, publish to
@@ -35,6 +35,34 @@ The package deliberately does not depend on `code-puppy` in its own metadata.
35
35
  `code-puppy` depends on this bundle; adding the reverse edge would create a
36
36
  packaging dependency cycle. Plugin CI installs the core runtime separately.
37
37
 
38
+ ## Completion notifications
39
+
40
+ The `completion_notification` plugin is disabled by default. Enable a native,
41
+ best-effort desktop notification after a successful top-level response with:
42
+
43
+ ```text
44
+ /set completion_notifications=true
45
+ ```
46
+
47
+ Notifications use a sanitized, shortened copy of the latest user prompt as the
48
+ title and a shortened response preview as the body, with Apple Terminal, iTerm2,
49
+ or Warp labeled through `TERM_PROGRAM` when available. Unknown terminals omit
50
+ the terminal label. Sub-agent completions are intentionally silent. Desktop
51
+ notification centers may retain visible prompt and response previews.
52
+
53
+ Optional sound configuration is platform-aware:
54
+
55
+ ```text
56
+ /set completion_notification_sound=Frog
57
+ ```
58
+
59
+ On macOS, a simple name selects a system sound (`Frog`, `Glass`, `Ping`, etc.).
60
+ Preview one with `afplay /System/Library/Sounds/Frog.aiff`. On any platform, an
61
+ absolute path to a local sound file is accepted when an available platform
62
+ player can play it. Linux uses `notify-send` for desktop notifications when it
63
+ is installed; Windows uses a best-effort PowerShell toast. No external Python
64
+ dependencies are required.
65
+
38
66
  ## Releases
39
67
 
40
68
  Pushes to `main` run lint and tests, bump the patch version, build, publish to
@@ -0,0 +1 @@
1
+ """Opt-in desktop notifications for completed top-level agent runs."""
@@ -0,0 +1,19 @@
1
+ """Configuration accessors for the completion-notification plugin."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from code_puppy.config import get_value
6
+
7
+ KEY_ENABLED = "completion_notifications"
8
+ KEY_SOUND = "completion_notification_sound"
9
+ _TRUTHY = {"1", "true", "yes", "on"}
10
+
11
+
12
+ def is_enabled() -> bool:
13
+ """Return whether completion notifications are explicitly enabled."""
14
+ return str(get_value(KEY_ENABLED) or "").strip().lower() in _TRUTHY
15
+
16
+
17
+ def get_sound() -> str:
18
+ """Return an optional named macOS sound or absolute local sound-file path."""
19
+ return str(get_value(KEY_SOUND) or "").strip()
@@ -0,0 +1,7 @@
1
+ {
2
+ "completion_notification.title": "Code Puppy",
3
+ "completion_notification.title_with_context": "Code Puppy — {context}",
4
+ "completion_notification.response_complete": "Response complete.",
5
+ "completion_notification.response_complete_in_terminal": "Response complete in {terminal}.",
6
+ "completion_notification.response_preview_in_terminal": "{preview} · {terminal}"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "completion_notification.title": "Code Puppy",
3
+ "completion_notification.title_with_context": "Code Puppy — {context}",
4
+ "completion_notification.response_complete": "Respuesta completada.",
5
+ "completion_notification.response_complete_in_terminal": "Respuesta completada en {terminal}.",
6
+ "completion_notification.response_preview_in_terminal": "{preview} · {terminal}"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "completion_notification.title": "Code Puppy",
3
+ "completion_notification.title_with_context": "Code Puppy — {context}",
4
+ "completion_notification.response_complete": "Réponse terminée.",
5
+ "completion_notification.response_complete_in_terminal": "Réponse terminée dans {terminal}.",
6
+ "completion_notification.response_preview_in_terminal": "{preview} · {terminal}"
7
+ }
@@ -0,0 +1,231 @@
1
+ """Best-effort, dependency-free desktop completion notifications."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import ntpath
7
+ import os
8
+ import platform
9
+ import re
10
+ import shutil
11
+ import subprocess
12
+ from pathlib import Path
13
+
14
+ from code_puppy.i18n import add_catalog_dir, t
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ _TIMEOUT_SECONDS = 3
19
+ _CATALOG_DIR = Path(__file__).parent / "locales"
20
+ add_catalog_dir(str(_CATALOG_DIR))
21
+ _MACOS_SOUND_NAME = re.compile(r"^[A-Za-z0-9 _-]+$")
22
+ # Control characters cannot survive intact inside AppleScript/PowerShell/XML
23
+ # source and are never meaningful in a single-line notification, so drop them.
24
+ _CONTROL_CHARS = re.compile(r"[\x00-\x1f\x7f]")
25
+ _WHITESPACE = re.compile(r"\s+")
26
+ _TITLE_PREVIEW_CHARS = 88
27
+ _BODY_PREVIEW_CHARS = 180
28
+ _TERMINAL_NAMES = {
29
+ "apple_terminal": "Terminal",
30
+ "iterm.app": "iTerm2",
31
+ "warpterminal": "Warp",
32
+ }
33
+
34
+
35
+ def _title(prompt: str = "") -> str:
36
+ context = prompt_preview(prompt)
37
+ if context:
38
+ return t("completion_notification.title_with_context", context=context)
39
+ return t("completion_notification.title")
40
+
41
+
42
+ def notify_completion(
43
+ sound: str = "", prompt: str = "", response_text: str = ""
44
+ ) -> None:
45
+ """Show a contextual platform-native completion notification."""
46
+ try:
47
+ system = platform.system()
48
+ title = _title(prompt)
49
+ message = _completion_message(response_text)
50
+ if system == "Darwin":
51
+ _notify_macos(title, message, sound)
52
+ elif system == "Linux":
53
+ _notify_linux(title, message, sound)
54
+ elif system == "Windows":
55
+ _notify_windows(title, message, sound)
56
+ except Exception:
57
+ logger.debug("completion notification failed", exc_info=True)
58
+
59
+
60
+ def _completion_message(response_text: str = "") -> str:
61
+ terminal = _TERMINAL_NAMES.get(os.environ.get("TERM_PROGRAM", "").casefold())
62
+ preview = response_preview(response_text)
63
+ if preview:
64
+ return (
65
+ preview
66
+ if terminal is None
67
+ else t(
68
+ "completion_notification.response_preview_in_terminal",
69
+ preview=preview,
70
+ terminal=terminal,
71
+ )
72
+ )
73
+ return (
74
+ t("completion_notification.response_complete")
75
+ if terminal is None
76
+ else t(
77
+ "completion_notification.response_complete_in_terminal", terminal=terminal
78
+ )
79
+ )
80
+
81
+
82
+ def response_preview(response_text: str) -> str:
83
+ """Return a safe, bounded body preview for an agent response."""
84
+ return _preview(response_text, _BODY_PREVIEW_CHARS)
85
+
86
+
87
+ def prompt_preview(prompt: str) -> str:
88
+ """Return a safe, bounded title preview for a user prompt."""
89
+ return _preview(prompt, _TITLE_PREVIEW_CHARS)
90
+
91
+
92
+ def _preview(text: str, limit: int) -> str:
93
+ """Collapse dynamic content into a readable, bounded notification line."""
94
+ compact = _WHITESPACE.sub(" ", _CONTROL_CHARS.sub(" ", text or "")).strip()
95
+ if len(compact) <= limit:
96
+ return compact
97
+ shortened = compact[: limit - 1].rsplit(" ", 1)[0].rstrip(".,;:!?")
98
+ return f"{shortened or compact[: limit - 1]}…"
99
+
100
+
101
+ def _notify_macos(title: str, message: str, sound: str) -> None:
102
+ body = _escape_applescript(message)
103
+ title = _escape_applescript(title)
104
+ script = f'display notification "{body}" with title "{title}"'
105
+ if _is_macos_sound_name(sound):
106
+ script += f' sound name "{sound}"'
107
+ _run(["/usr/bin/osascript", "-e", script])
108
+ _play_file(sound, players=(("/usr/bin/afplay",),))
109
+
110
+
111
+ def _notify_linux(title: str, message: str, sound: str) -> None:
112
+ notify_send = shutil.which("notify-send")
113
+ if notify_send:
114
+ # "--" stops option parsing so a title/message starting with "-" is
115
+ # never misread as a flag.
116
+ _run([notify_send, "--app-name", _title(), "--", title, message])
117
+ _play_file(sound, players=(("paplay",), ("aplay",)))
118
+
119
+
120
+ def _notify_windows(title: str, message: str, sound: str) -> None:
121
+ # Windows Runtime toast APIs are available on current Windows releases. This
122
+ # remains best-effort: restricted hosts can reject the call without affecting
123
+ # the completed Code Puppy run.
124
+ toast_xml = (
125
+ '<toast><visual><binding template="ToastGeneric">'
126
+ f"<text>{_escape_xml(title)}</text><text>{_escape_xml(message)}</text>"
127
+ "</binding></visual></toast>"
128
+ )
129
+ # XML-escaping already removes single quotes, but escape the assembled
130
+ # literal defensively before it enters the single-quoted PowerShell string.
131
+ toast_literal = toast_xml.replace("'", "''")
132
+ notifier_title = _title().replace("'", "''")
133
+ script = (
134
+ "$xml = New-Object Windows.Data.Xml.Dom.XmlDocument; "
135
+ f"$xml.LoadXml('{toast_literal}'); "
136
+ "[Windows.UI.Notifications.ToastNotificationManager]::"
137
+ f"CreateToastNotifier('{notifier_title}').Show("
138
+ "[Windows.UI.Notifications.ToastNotification]::new($xml))"
139
+ )
140
+ powershell = _powershell_executable()
141
+ _run([powershell, "-NoProfile", "-NonInteractive", "-Command", script])
142
+ _play_file(
143
+ sound,
144
+ players=((powershell, "-NoProfile", "-NonInteractive", "-Command"),),
145
+ )
146
+
147
+
148
+ def _powershell_executable() -> str:
149
+ """Return Windows PowerShell by trusted absolute path, never PATH lookup."""
150
+ system_root = os.environ.get("SystemRoot", r"C:\Windows")
151
+ return ntpath.join(
152
+ system_root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"
153
+ )
154
+
155
+
156
+ def _is_macos_sound_name(sound: str) -> bool:
157
+ return bool(sound) and "/" not in sound and bool(_MACOS_SOUND_NAME.fullmatch(sound))
158
+
159
+
160
+ def _escape_applescript(text: str) -> str:
161
+ """Escape text for a double-quoted AppleScript string literal.
162
+
163
+ i18n catalogs are an untrusted plugin/community seam, so translated text is
164
+ treated as hostile input. Escaping backslash and double-quote (after dropping
165
+ control characters) prevents breaking out of the literal into ``do shell
166
+ script`` and neutralizes the injection class entirely.
167
+ """
168
+ text = _CONTROL_CHARS.sub(" ", text)
169
+ return text.replace("\\", "\\\\").replace('"', '\\"')
170
+
171
+
172
+ def _escape_xml(text: str) -> str:
173
+ """Escape text for a Windows toast XML text node (untrusted i18n input)."""
174
+ text = _CONTROL_CHARS.sub(" ", text)
175
+ return (
176
+ text.replace("&", "&amp;")
177
+ .replace("<", "&lt;")
178
+ .replace(">", "&gt;")
179
+ .replace('"', "&quot;")
180
+ .replace("'", "&apos;")
181
+ )
182
+
183
+
184
+ def _play_file(sound: str, *, players: tuple[tuple[str, ...], ...]) -> None:
185
+ path = _sound_file(sound)
186
+ if path is None:
187
+ return
188
+ for player in players:
189
+ if Path(player[0]).is_absolute() or ntpath.isabs(player[0]):
190
+ executable = player[0]
191
+ else:
192
+ executable = shutil.which(player[0]) or (
193
+ player[0] if Path(player[0]).is_file() else None
194
+ )
195
+ if executable is None:
196
+ continue
197
+ if ntpath.basename(player[0]).casefold() == "powershell.exe":
198
+ escaped_path = str(path).replace("'", "''")
199
+ _run(
200
+ [
201
+ *player,
202
+ f"(New-Object System.Media.SoundPlayer '{escaped_path}').PlaySync()",
203
+ ]
204
+ )
205
+ else:
206
+ _run([executable, *player[1:], str(path)])
207
+ return
208
+
209
+
210
+ def _sound_file(sound: str) -> Path | None:
211
+ if not sound or _is_macos_sound_name(sound):
212
+ return None
213
+ path = Path(sound).expanduser()
214
+ if not path.is_absolute() or not path.is_file():
215
+ return None
216
+ return path
217
+
218
+
219
+ def _run(command: list[str]) -> None:
220
+ try:
221
+ subprocess.run(
222
+ command,
223
+ capture_output=True,
224
+ check=False,
225
+ timeout=_TIMEOUT_SECONDS,
226
+ text=True,
227
+ )
228
+ except (OSError, subprocess.SubprocessError):
229
+ logger.debug(
230
+ "completion notification command failed: %s", command[0], exc_info=True
231
+ )
@@ -0,0 +1,135 @@
1
+ """Register opt-in desktop notifications for completed top-level agent runs."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import logging
6
+ import threading
7
+ import time
8
+
9
+ from code_puppy.callbacks import register_callback
10
+
11
+ from .config import get_sound, is_enabled
12
+ from .notifier import notify_completion, prompt_preview
13
+
14
+ logger = logging.getLogger(__name__)
15
+ _WORKER_JOIN_TIMEOUT_SECONDS = 3
16
+ _lock = threading.Lock()
17
+ _run_depth = 0
18
+ _workers: set[threading.Thread] = set()
19
+ _prompts: dict[str, str] = {}
20
+
21
+
22
+ def _on_user_prompt_submit(prompt: str, session_id: str | None = None) -> None:
23
+ """Keep an opted-in prompt only until its run finishes."""
24
+ if not session_id or not is_enabled() or _is_subagent():
25
+ return
26
+ with _lock:
27
+ _prompts[session_id] = prompt_preview(prompt)
28
+
29
+
30
+ def _is_subagent() -> bool:
31
+ try:
32
+ from code_puppy.tools.subagent_context import is_subagent
33
+
34
+ return is_subagent()
35
+ except Exception:
36
+ logger.debug(
37
+ "sub-agent status could not be determined; suppressing notification",
38
+ exc_info=True,
39
+ )
40
+ return True
41
+
42
+
43
+ def _on_agent_run_start(*_args, **_kwargs) -> None:
44
+ """Track public lifecycle depth so internal nested runs never notify."""
45
+ global _run_depth
46
+ with _lock:
47
+ _run_depth += 1
48
+
49
+
50
+ def _on_agent_run_end(
51
+ agent_name: str | None = None,
52
+ model_name: str | None = None,
53
+ session_id: str | None = None,
54
+ success: bool = True,
55
+ error: Exception | None = None,
56
+ response_text: str | None = None,
57
+ metadata: dict | None = None,
58
+ ) -> None:
59
+ """Notify only when the outermost successful textual run completes."""
60
+ del agent_name, model_name, error, metadata
61
+ global _run_depth
62
+ with _lock:
63
+ _run_depth = max(0, _run_depth - 1)
64
+ is_outermost_run = _run_depth == 0
65
+ prompt = _prompts.pop(session_id, "") if session_id else ""
66
+
67
+ if (
68
+ not is_outermost_run
69
+ or not success
70
+ or not response_text
71
+ or not is_enabled()
72
+ or _is_subagent()
73
+ ):
74
+ return
75
+
76
+ try:
77
+ _start_notification_worker(get_sound(), prompt, response_text)
78
+ except Exception:
79
+ logger.debug("completion notification worker could not start", exc_info=True)
80
+
81
+
82
+ def _start_notification_worker(
83
+ sound: str, prompt: str = "", response_text: str = ""
84
+ ) -> None:
85
+ worker: threading.Thread
86
+
87
+ def notify() -> None:
88
+ try:
89
+ notify_completion(sound, prompt, response_text)
90
+ finally:
91
+ with _lock:
92
+ _workers.discard(worker)
93
+
94
+ worker = threading.Thread(
95
+ target=notify,
96
+ daemon=True,
97
+ name="code-puppy-completion-notification",
98
+ )
99
+ with _lock:
100
+ _workers.add(worker)
101
+ worker.start()
102
+
103
+
104
+ def _drain_workers(*_args, **_kwargs) -> None:
105
+ """Give notification workers a bounded chance to finish before exit.
106
+
107
+ Joins share a single deadline so total wall time stays within the timeout
108
+ regardless of how many workers are in flight, rather than N x timeout.
109
+ """
110
+ with _lock:
111
+ workers = tuple(_workers)
112
+ _workers.clear()
113
+ deadline = time.monotonic() + _WORKER_JOIN_TIMEOUT_SECONDS
114
+ for worker in workers:
115
+ remaining = max(0.0, deadline - time.monotonic())
116
+ try:
117
+ worker.join(timeout=remaining)
118
+ except RuntimeError:
119
+ logger.debug(
120
+ "completion notification worker could not be joined", exc_info=True
121
+ )
122
+
123
+
124
+ register_callback("user_prompt_submit", _on_user_prompt_submit)
125
+ register_callback("agent_run_start", _on_agent_run_start)
126
+ register_callback("agent_run_end", _on_agent_run_end)
127
+ register_callback("session_end", _drain_workers)
128
+ register_callback("shutdown", _drain_workers)
129
+
130
+ __all__ = [
131
+ "_drain_workers",
132
+ "_on_agent_run_end",
133
+ "_on_agent_run_start",
134
+ "_on_user_prompt_submit",
135
+ ]
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-puppy-core-plugins"
7
- version = "0.0.40"
7
+ version = "0.0.41"
8
8
  description = "Official plugin bundle for Code Puppy"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11,<3.15"
@@ -40,6 +40,7 @@ claude_code_hooks = "code_puppy_core_plugins.claude_code_hooks.register_callback
40
40
  claude_code_oauth = "code_puppy_core_plugins.claude_code_oauth.register_callbacks"
41
41
  code_puppy_agent = "code_puppy_core_plugins.code_puppy_agent.register_callbacks"
42
42
  computer_use = "code_puppy_core_plugins.computer_use.register_callbacks"
43
+ completion_notification = "code_puppy_core_plugins.completion_notification.register_callbacks"
43
44
  context_indicator = "code_puppy_core_plugins.context_indicator.register_callbacks"
44
45
  copilot_auth = "code_puppy_core_plugins.copilot_auth.register_callbacks"
45
46
  customizable_commands = "code_puppy_core_plugins.customizable_commands.register_callbacks"