code-puppy-core-plugins 0.0.45__tar.gz → 0.0.47__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 (360) hide show
  1. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/PKG-INFO +2 -2
  2. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/model_provider.py +5 -0
  3. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/herdr/README.md +58 -7
  4. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/herdr/client.py +188 -9
  5. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/herdr/register_callbacks.py +12 -4
  6. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/herdr/reporter.py +129 -4
  7. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/herdr/smoke.py +68 -10
  8. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/herdr/sources.py +87 -7
  9. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/pyproject.toml +2 -2
  10. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/.gitignore +0 -0
  11. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/LICENSE +0 -0
  12. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/README.md +0 -0
  13. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/__init__.py +0 -0
  14. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/README.md +0 -0
  15. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/__init__.py +0 -0
  16. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/agent.py +0 -0
  17. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/bridge.py +0 -0
  18. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/capabilities.py +0 -0
  19. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/commands.py +0 -0
  20. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/content.py +0 -0
  21. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/io_delegation.py +0 -0
  22. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/mcp_config.py +0 -0
  23. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/permissions.py +0 -0
  24. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/persistence.py +0 -0
  25. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/register_callbacks.py +0 -0
  26. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/replay.py +0 -0
  27. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/session.py +0 -0
  28. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/session_config.py +0 -0
  29. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/acp/state.py +0 -0
  30. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_creator_skill/SKILL.md +0 -0
  31. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_creator_skill/__init__.py +0 -0
  32. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_creator_skill/register_callbacks.py +0 -0
  33. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/__init__.py +0 -0
  34. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/config.py +0 -0
  35. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/discovery.py +0 -0
  36. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/downloader.py +0 -0
  37. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/enabled_skills.py +0 -0
  38. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/installer.py +0 -0
  39. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/metadata.py +0 -0
  40. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/prompt_builder.py +0 -0
  41. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/provider.py +0 -0
  42. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/register_callbacks.py +0 -0
  43. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/remote_catalog.py +0 -0
  44. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/skill_catalog.py +0 -0
  45. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/skill_commands.py +0 -0
  46. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/skills_install_menu.py +0 -0
  47. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/agent_skills/skills_menu.py +0 -0
  48. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/auto_continue/__init__.py +0 -0
  49. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/auto_continue/classifier.py +0 -0
  50. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/auto_continue/register_callbacks.py +0 -0
  51. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/aws_bedrock/__init__.py +0 -0
  52. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/aws_bedrock/config.py +0 -0
  53. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/aws_bedrock/register_callbacks.py +0 -0
  54. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/aws_bedrock/utils.py +0 -0
  55. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/azure_foundry/README.md +0 -0
  56. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/azure_foundry/__init__.py +0 -0
  57. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/azure_foundry/config.py +0 -0
  58. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/azure_foundry/discovery.py +0 -0
  59. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/azure_foundry/register_callbacks.py +0 -0
  60. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/azure_foundry/token.py +0 -0
  61. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/azure_foundry/utils.py +0 -0
  62. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/btw/__init__.py +0 -0
  63. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/btw/inline_view.py +0 -0
  64. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/btw/register_callbacks.py +0 -0
  65. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/btw/side_query.py +0 -0
  66. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/IMAGEGEN_SKILL.md +0 -0
  67. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/__init__.py +0 -0
  68. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/config.py +0 -0
  69. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/image_generation.py +0 -0
  70. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/image_tool.py +0 -0
  71. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/model_catalog.py +0 -0
  72. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/oauth_flow.py +0 -0
  73. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/register_callbacks.py +0 -0
  74. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/test_plugin.py +0 -0
  75. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/usage.py +0 -0
  76. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/chatgpt_oauth/utils.py +0 -0
  77. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_hooks/__init__.py +0 -0
  78. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_hooks/config.py +0 -0
  79. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_hooks/register_callbacks.py +0 -0
  80. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_hooks/trust.py +0 -0
  81. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/README.md +0 -0
  82. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/SETUP.md +0 -0
  83. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/__init__.py +0 -0
  84. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/config.py +0 -0
  85. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/fast_mode.py +0 -0
  86. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/model_filter.py +0 -0
  87. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/prompt_handler.py +0 -0
  88. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/register_callbacks.py +0 -0
  89. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/runtime_credentials.py +0 -0
  90. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/test_plugin.py +0 -0
  91. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
  92. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/token_store.py +0 -0
  93. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/claude_code_oauth/utils.py +0 -0
  94. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/AGENTS_AND_TOOLS.md +0 -0
  95. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/MODELS_AND_MCP.md +0 -0
  96. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/PLUGINS_AND_CALLBACKS.md +0 -0
  97. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/SESSIONS_AND_HISTORY.md +0 -0
  98. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/SKILL.md +0 -0
  99. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/SKILLS_SYSTEM.md +0 -0
  100. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/SYSTEM_PROMPT_CONFIG_AND_I18N.md +0 -0
  101. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/__init__.py +0 -0
  102. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/code_puppy_agent/register_callbacks.py +0 -0
  103. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/completion_notification/__init__.py +0 -0
  104. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/completion_notification/config.py +0 -0
  105. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/completion_notification/locales/en-US.json +0 -0
  106. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/completion_notification/locales/es.json +0 -0
  107. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/completion_notification/locales/fr-CA.json +0 -0
  108. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/completion_notification/notifier.py +0 -0
  109. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/completion_notification/register_callbacks.py +0 -0
  110. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/NativeCapture.swift +0 -0
  111. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/README.md +0 -0
  112. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/__init__.py +0 -0
  113. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/accessibility.py +0 -0
  114. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/activation.py +0 -0
  115. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/backend.py +0 -0
  116. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/backend_types.py +0 -0
  117. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/capture.py +0 -0
  118. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/commands.py +0 -0
  119. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/geometry.py +0 -0
  120. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/inline_image.py +0 -0
  121. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/keycodes.py +0 -0
  122. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/policy.py +0 -0
  123. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/register_callbacks.py +0 -0
  124. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/safety.py +0 -0
  125. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/settle.py +0 -0
  126. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/state.py +0 -0
  127. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/computer_use/tools.py +0 -0
  128. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/context_indicator/__init__.py +0 -0
  129. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/context_indicator/register_callbacks.py +0 -0
  130. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/context_indicator/usage.py +0 -0
  131. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/copilot_auth/__init__.py +0 -0
  132. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/copilot_auth/config.py +0 -0
  133. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/copilot_auth/reasoning_client.py +0 -0
  134. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/copilot_auth/register_callbacks.py +0 -0
  135. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/copilot_auth/utils.py +0 -0
  136. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/customizable_commands/__init__.py +0 -0
  137. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/customizable_commands/register_callbacks.py +0 -0
  138. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/__init__.py +0 -0
  139. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/cancel.py +0 -0
  140. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/commands.py +0 -0
  141. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/config.py +0 -0
  142. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/lifecycle.py +0 -0
  143. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/register_callbacks.py +0 -0
  144. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/runtime.py +0 -0
  145. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/startup_lock.py +0 -0
  146. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/workflow_ids.py +0 -0
  147. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/dbos_durable_exec/wrapper.py +0 -0
  148. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/destructive_command_guard/AGENTS.md +0 -0
  149. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/destructive_command_guard/__init__.py +0 -0
  150. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/destructive_command_guard/detector.py +0 -0
  151. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/destructive_command_guard/register_callbacks.py +0 -0
  152. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/emoji_filter/__init__.py +0 -0
  153. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/emoji_filter/config.py +0 -0
  154. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/emoji_filter/register_callbacks.py +0 -0
  155. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/emoji_filter/stripper.py +0 -0
  156. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/empty_html_comment_filter/register_callbacks.py +0 -0
  157. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/example_custom_command/README.md +0 -0
  158. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/example_custom_command/register_callbacks.py +0 -0
  159. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/file_permission_handler/__init__.py +0 -0
  160. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/file_permission_handler/register_callbacks.py +0 -0
  161. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/__init__.py +0 -0
  162. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/README.md +0 -0
  163. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/cheatsheet.md +0 -0
  164. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/pipeline.md +0 -0
  165. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/synopsis.md +0 -0
  166. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/about.md +0 -0
  167. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/address-feedback.md +0 -0
  168. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/ask.md +0 -0
  169. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/aug.md +0 -0
  170. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/auto-pilot.md +0 -0
  171. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/cheatsheet.md +0 -0
  172. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/commit.md +0 -0
  173. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/config.md +0 -0
  174. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/create-pr.md +0 -0
  175. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/exec.md +0 -0
  176. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/new.md +0 -0
  177. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/qa.md +0 -0
  178. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/rebase.md +0 -0
  179. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/review.md +0 -0
  180. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/split.md +0 -0
  181. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/squash-commits.md +0 -0
  182. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/status.md +0 -0
  183. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/tests.md +0 -0
  184. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_about.py +0 -0
  185. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_cheatsheet.py +0 -0
  186. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_status.py +0 -0
  187. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/installer.py +0 -0
  188. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/flux_bootstrap/register_callbacks.py +0 -0
  189. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/force_push_guard/__init__.py +0 -0
  190. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/force_push_guard/detector.py +0 -0
  191. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/force_push_guard/register_callbacks.py +0 -0
  192. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/fork/__init__.py +0 -0
  193. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/fork/register_callbacks.py +0 -0
  194. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/frontend_emitter/__init__.py +0 -0
  195. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/frontend_emitter/emitter.py +0 -0
  196. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/frontend_emitter/register_callbacks.py +0 -0
  197. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/frontend_emitter/session_context.py +0 -0
  198. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/grok_oauth/__init__.py +0 -0
  199. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/grok_oauth/config.py +0 -0
  200. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/grok_oauth/oauth_flow.py +0 -0
  201. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/grok_oauth/register_callbacks.py +0 -0
  202. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/grok_oauth/utils.py +0 -0
  203. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/herdr/__init__.py +0 -0
  204. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/hook_creator/__init__.py +0 -0
  205. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/hook_creator/register_callbacks.py +0 -0
  206. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/hook_manager/__init__.py +0 -0
  207. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/hook_manager/config.py +0 -0
  208. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/hook_manager/hooks_menu.py +0 -0
  209. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/hook_manager/register_callbacks.py +0 -0
  210. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/hook_manager/trust_handler.py +0 -0
  211. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_oauth/__init__.py +0 -0
  212. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_oauth/oauth.py +0 -0
  213. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_oauth/query_tool.py +0 -0
  214. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_oauth/register_callbacks.py +0 -0
  215. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_sessions/__init__.py +0 -0
  216. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_sessions/mirror.py +0 -0
  217. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_sessions/query.py +0 -0
  218. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_sessions/register_callbacks.py +0 -0
  219. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/logfire_sessions/sync.py +0 -0
  220. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/meta_oauth/__init__.py +0 -0
  221. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/meta_oauth/config.py +0 -0
  222. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/meta_oauth/oauth_flow.py +0 -0
  223. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/meta_oauth/register_callbacks.py +0 -0
  224. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/meta_oauth/utils.py +0 -0
  225. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/namespace_skill_search/README.md +0 -0
  226. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/namespace_skill_search/__init__.py +0 -0
  227. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/namespace_skill_search/namespaces.py +0 -0
  228. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/namespace_skill_search/register_callbacks.py +0 -0
  229. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/namespace_skill_search/search_tool.py +0 -0
  230. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/no_tools/__init__.py +0 -0
  231. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/no_tools/register_callbacks.py +0 -0
  232. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/oauth_pasteback.py +0 -0
  233. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/oauth_puppy_html.py +0 -0
  234. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/obsidian_agent/README.md +0 -0
  235. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/obsidian_agent/__init__.py +0 -0
  236. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/obsidian_agent/agent_obsidian.py +0 -0
  237. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/obsidian_agent/register_callbacks.py +0 -0
  238. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/ollama/__init__.py +0 -0
  239. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/ollama/register_callbacks.py +0 -0
  240. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/ollama_setup/__init__.py +0 -0
  241. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/ollama_setup/completer.py +0 -0
  242. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/ollama_setup/register_callbacks.py +0 -0
  243. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/openrouter_oauth/__init__.py +0 -0
  244. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/openrouter_oauth/config.py +0 -0
  245. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/openrouter_oauth/oauth_flow.py +0 -0
  246. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/openrouter_oauth/register_callbacks.py +0 -0
  247. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/openrouter_oauth/test_plugin.py +0 -0
  248. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/plugin_list/__init__.py +0 -0
  249. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/plugin_list/plugin_contributions.py +0 -0
  250. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/plugin_list/plugin_meta.py +0 -0
  251. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/plugin_list/plugin_text_utils.py +0 -0
  252. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/plugin_list/plugins_menu.py +0 -0
  253. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/plugin_list/plugins_menu_render.py +0 -0
  254. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/plugin_list/project_trust_flow.py +0 -0
  255. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/plugin_list/register_callbacks.py +0 -0
  256. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/pop_command/__init__.py +0 -0
  257. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/pop_command/register_callbacks.py +0 -0
  258. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/profiles/README.md +0 -0
  259. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/profiles/__init__.py +0 -0
  260. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/profiles/config.py +0 -0
  261. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/profiles/locales/en-US.json +0 -0
  262. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/profiles/menu.py +0 -0
  263. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/profiles/register_callbacks.py +0 -0
  264. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/prompt_newline/__init__.py +0 -0
  265. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/prompt_newline/config.py +0 -0
  266. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/prompt_newline/register_callbacks.py +0 -0
  267. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/prune/__init__.py +0 -0
  268. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/prune/prune_menu.py +0 -0
  269. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/prune/prune_model.py +0 -0
  270. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/prune/prune_render.py +0 -0
  271. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/prune/register_callbacks.py +0 -0
  272. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/README.md +0 -0
  273. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/__init__.py +0 -0
  274. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/commands.py +0 -0
  275. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/config.py +0 -0
  276. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/kennel.py +0 -0
  277. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/packer.py +0 -0
  278. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/recorder.py +0 -0
  279. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/register_callbacks.py +0 -0
  280. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/retriever.py +0 -0
  281. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/schema.py +0 -0
  282. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/state.py +0 -0
  283. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/tools.py +0 -0
  284. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_kennel/wings.py +0 -0
  285. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_spinner/README.md +0 -0
  286. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_spinner/__init__.py +0 -0
  287. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_spinner/builtin_frames.py +0 -0
  288. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_spinner/commands.py +0 -0
  289. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_spinner/picker.py +0 -0
  290. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_spinner/register_callbacks.py +0 -0
  291. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/puppy_spinner/spinners.py +0 -0
  292. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/qa_kitten_skill/SKILL.md +0 -0
  293. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/qa_kitten_skill/__init__.py +0 -0
  294. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/qa_kitten_skill/register_callbacks.py +0 -0
  295. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/quick_resume/__init__.py +0 -0
  296. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/quick_resume/register_callbacks.py +0 -0
  297. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/review_pr/__init__.py +0 -0
  298. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/review_pr/register_callbacks.py +0 -0
  299. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/session_namer/__init__.py +0 -0
  300. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/session_namer/namer.py +0 -0
  301. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/session_namer/register_callbacks.py +0 -0
  302. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/spill/LICENSE.deepseek +0 -0
  303. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/spill/__init__.py +0 -0
  304. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/spill/register_callbacks.py +0 -0
  305. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/spill/store.py +0 -0
  306. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/stack_dump/__init__.py +0 -0
  307. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/stack_dump/register_callbacks.py +0 -0
  308. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/statusline/__init__.py +0 -0
  309. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/statusline/config.py +0 -0
  310. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/statusline/payload.py +0 -0
  311. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/statusline/prompt_patch.py +0 -0
  312. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/statusline/register_callbacks.py +0 -0
  313. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/statusline/runner.py +0 -0
  314. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/statusline/statusline_command.py +0 -0
  315. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/steer_queue/__init__.py +0 -0
  316. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/steer_queue/queue_menu.py +0 -0
  317. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/steer_queue/register_callbacks.py +0 -0
  318. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/subagent_panel/README.md +0 -0
  319. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/subagent_panel/__init__.py +0 -0
  320. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/subagent_panel/coalesce_patch.py +0 -0
  321. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/subagent_panel/panel_render.py +0 -0
  322. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/subagent_panel/register_callbacks.py +0 -0
  323. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/subagent_panel/resume_repaint.py +0 -0
  324. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/subagent_panel/state.py +0 -0
  325. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/switch_agent_resume/__init__.py +0 -0
  326. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/switch_agent_resume/register_callbacks.py +0 -0
  327. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/termflow_tui.py +0 -0
  328. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/README.md +0 -0
  329. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/__init__.py +0 -0
  330. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/bundled_palettes.py +0 -0
  331. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/content_styles.py +0 -0
  332. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/osc_palette.py +0 -0
  333. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/picker.py +0 -0
  334. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/prompt_toolkit_theme.py +0 -0
  335. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/register_callbacks.py +0 -0
  336. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/rich_themes.py +0 -0
  337. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/theme/themes.py +0 -0
  338. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/timestamp_heartbeat/__init__.py +0 -0
  339. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/timestamp_heartbeat/register_callbacks.py +0 -0
  340. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/token_ratio_learner/__init__.py +0 -0
  341. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/token_ratio_learner/ratios.py +0 -0
  342. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/token_ratio_learner/register_callbacks.py +0 -0
  343. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/universal_constructor/__init__.py +0 -0
  344. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/universal_constructor/models.py +0 -0
  345. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/universal_constructor/provider.py +0 -0
  346. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/universal_constructor/register_callbacks.py +0 -0
  347. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/universal_constructor/registry.py +0 -0
  348. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/universal_constructor/sandbox.py +0 -0
  349. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/web_retriever_skill/SKILL.md +0 -0
  350. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/web_retriever_skill/__init__.py +0 -0
  351. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/web_retriever_skill/register_callbacks.py +0 -0
  352. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/wiggum/__init__.py +0 -0
  353. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/wiggum/goal_runs.py +0 -0
  354. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/wiggum/judge.py +0 -0
  355. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/wiggum/judge_config.py +0 -0
  356. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/wiggum/judges_menu.py +0 -0
  357. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/wiggum/register_callbacks.py +0 -0
  358. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/wiggum/state.py +0 -0
  359. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/code_puppy_core_plugins/yolo_cli/__init__.py +0 -0
  360. {code_puppy_core_plugins-0.0.45 → code_puppy_core_plugins-0.0.47}/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.45
3
+ Version: 0.0.47
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
@@ -15,7 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
16
  Requires-Python: <3.15,>=3.11
17
17
  Requires-Dist: httpx<1,>=0.24.1
18
- Requires-Dist: pydantic-ai-slim[anthropic,mcp,openai]<3,>=2.31.0
18
+ Requires-Dist: pydantic-ai-slim[anthropic,mcp,openai]<3,>=2.35.0
19
19
  Description-Content-Type: text/markdown
20
20
 
21
21
  # Code Puppy Core Plugins
@@ -123,10 +123,15 @@ def create_claude_code_model(model_name: str, model_config: Dict, config: Dict)
123
123
  ),
124
124
  )
125
125
 
126
+ # The transport already retries 429/5xx/connection errors with backoff,
127
+ # and the agent runtime retries the turn on top of that. The SDK's own
128
+ # retries would multiply every hard failure 3x -- a 429 storm is exactly
129
+ # when hammering the endpoint makes things worse.
126
130
  anthropic_client = AsyncAnthropic(
127
131
  base_url=url,
128
132
  http_client=client,
129
133
  auth_token=api_key,
134
+ max_retries=0,
130
135
  )
131
136
 
132
137
  def _update_runtime_token(access_token: str) -> None:
@@ -11,13 +11,14 @@ This plugin teaches code-puppy to report that state authoritatively.
11
11
 
12
12
  ## What it does
13
13
 
14
- herdr injects three environment variables into every pane it owns:
14
+ herdr injects four environment variables into every pane it owns:
15
15
 
16
16
  | variable | meaning |
17
17
  | ------------------- | ----------------------------------------- |
18
18
  | `HERDR_ENV=1` | this shell is running inside a herdr pane |
19
19
  | `HERDR_SOCKET_PATH` | herdr's local control socket |
20
20
  | `HERDR_PANE_ID` | the pane this process owns (e.g. `w1:p1`) |
21
+ | `HERDR_TAB_ID` | the workspace tab (e.g. `w1:t1`) |
21
22
 
22
23
  On startup the plugin checks for those. If they're absent it does
23
24
  **nothing** -- zero overhead, zero output, no behaviour change, no socket,
@@ -94,6 +95,55 @@ when the reference actually changes (after `/clear`, `/session new`,
94
95
  This is a stable *reference*; automatic process restoration from it is
95
96
  **unverified** and not claimed here.
96
97
 
98
+ ## Conversation titles
99
+
100
+ The `session_namer` plugin auto-names every conversation (the titles you
101
+ see in `/resume`). This plugin propagates the current session's title to
102
+ two herdr surfaces:
103
+
104
+ * the pane's **presentation title**, which herdr renders as the pane
105
+ border label and the sidebar `pane` token, and
106
+ * the **workspace tab label** in herdr's tab bar -- but only while the
107
+ tab holds a single pane (the one running this code-puppy). The tab bar
108
+ is a user-managed surface, so a tab shared with other panes is never
109
+ touched.
110
+
111
+ Add the `pane` token to `rows_by_agent` to show the title in the sidebar
112
+ too:
113
+
114
+ ```toml
115
+ [ui.sidebar.agents.rows_by_agent]
116
+ codepuppy = [
117
+ ["state_icon", "workspace", "tab"],
118
+ ["agent", "$model", "pane"],
119
+ ["$context", "$tokens"],
120
+ ]
121
+ ```
122
+
123
+ The title is read from the session metadata sidecar that `session_namer`
124
+ maintains (the same store `/resume` reads). The pane presentation title
125
+ rides the same `pane.report_metadata` envelope as the token payload:
126
+ herdr replaces the whole per-source metadata entry on each report, so
127
+ every turn-end report re-sends the title (or a `clear_title` on a
128
+ set-to-none transition) and a title change is reported title-only the
129
+ moment it is seen. The tab label follows the same title changes via
130
+ `tab.rename`, guarded by a `tab.get` read of the tab's `pane_count`; on
131
+ a clean exit the original label is restored -- but only while the tab
132
+ still shows the label we last set, so a tab you renamed by hand is never
133
+ clobbered (a crashed exit simply leaves the last title in place, like
134
+ the stale-pane case above).
135
+
136
+ Because the namer names the session *asynchronously* after each autosave,
137
+ a bounded background wait (2s ticks, 90s ceiling -- the namer's own model
138
+ call is capped at 60s) picks the title up a few seconds after the turn
139
+ ends instead of waiting for the next turn. The wait is single-flight,
140
+ pinned to the session that triggered it, and skipped when the
141
+ `session_namer` plugin is disabled via its `session_namer` config value.
142
+ A session switch clears the previous session's title on the next prompt
143
+ (and restores the tab label). As with the token payload, the pane title
144
+ self-expires after the 24h metadata TTL, and all of this is decorative:
145
+ it never touches the authoritative state and is a no-op outside herdr.
146
+
97
147
  ## Notifications are herdr's job
98
148
 
99
149
  The plugin sends no notifications itself. herdr derives attention and
@@ -103,7 +153,8 @@ plugin's only job is to report accurate state.
103
153
 
104
154
  ## Release on exit
105
155
 
106
- On `session_end` / `shutdown` the plugin calls `pane.release_agent` once
156
+ On `session_end` / `shutdown` the plugin restores the workspace tab label
157
+ (if it relabelled one) and then calls `pane.release_agent` once
107
158
  (idempotent, bounded) so herdr knows code-puppy has let go of the pane --
108
159
  no lingering stale `working`. There is no intermediate `idle` report on
109
160
  shutdown; if herdr is unavailable the release is bounded and can never
@@ -147,9 +198,9 @@ state, metadata, and activity.
147
198
  | ----------------------- | ------------------------------------------- |
148
199
  | `client.py` | herdr socket transport (JSON, worker thread)|
149
200
  | `reporter.py` | event -> state machine (refcount + dedup) |
150
- | `sources.py` | fail-soft adapters (tokens / session / msg) |
201
+ | `sources.py` | fail-soft adapters (tokens / title / session / msg) |
151
202
  | `register_callbacks.py` | callback wiring + env activation guard |
152
- | `smoke.py` | manual live smoke test (disposable pane) |
203
+ | `smoke.py` | manual live smoke test (disposable pane + tab) |
153
204
 
154
205
  ## Live smoke test
155
206
 
@@ -163,6 +214,6 @@ python -m code_puppy_core_plugins.herdr.smoke
163
214
 
164
215
  It creates its **own** disposable pane, drives the real client through
165
216
  every protocol-16 method (state edges, session reference, metadata,
166
- release), reads each result back with `herdr pane get`, then closes the
167
- disposable pane -- your working pane is never touched. Exits non-zero if
168
- any check fails.
217
+ conversation title, release), reads each result back with
218
+ `herdr pane get`, then closes the disposable pane -- your working pane is
219
+ never touched. Exits non-zero if any check fails.
@@ -7,13 +7,16 @@ environment variables:
7
7
  * ``HERDR_ENV=1`` -- marks the pane as herdr-managed
8
8
  * ``HERDR_SOCKET_PATH`` -- path to herdr's local control socket
9
9
  * ``HERDR_PANE_ID`` -- the pane this process owns (e.g. ``w1:p1``)
10
+ * ``HERDR_TAB_ID`` -- the workspace tab (e.g. ``w1:t1``); optional
10
11
 
11
12
  This module speaks herdr's newline-delimited JSON socket protocol far
12
13
  enough to call ``pane.report_agent`` / ``pane.report_agent_session`` /
13
- ``pane.report_metadata`` / ``pane.release_agent``. It reads herdr's ack
14
- (and retries a few times if it doesn't come) so an authoritative state
15
- edge is never silently lost, but it never raises into the caller:
16
- reporting agent state must never be able to disturb the agent itself.
14
+ ``pane.report_metadata`` / ``pane.release_agent`` -- plus ``tab.get`` /
15
+ ``tab.rename`` for the workspace-tab label (only while the tab holds a
16
+ single pane). It reads herdr's ack (and retries a few times if it
17
+ doesn't come) so an authoritative state edge is never silently lost, but
18
+ it never raises into the caller: reporting agent state must never be
19
+ able to disturb the agent itself.
17
20
 
18
21
  Delivery runs on a single daemon worker thread fed by **coalescing
19
22
  mailbox slots** rather than an unbounded queue:
@@ -75,6 +78,8 @@ _M_STATE = "pane.report_agent"
75
78
  _M_SESSION = "pane.report_agent_session"
76
79
  _M_METADATA = "pane.report_metadata"
77
80
  _M_RELEASE = "pane.release_agent"
81
+ _M_TAB_GET = "tab.get"
82
+ _M_TAB_RENAME = "tab.rename"
78
83
 
79
84
 
80
85
  class HerdrClient:
@@ -84,9 +89,11 @@ class HerdrClient:
84
89
  self,
85
90
  socket_path: Optional[str] = None,
86
91
  pane_id: Optional[str] = None,
92
+ tab_id: Optional[str] = None,
87
93
  ) -> None:
88
94
  self._socket_path = socket_path or os.environ.get("HERDR_SOCKET_PATH")
89
95
  self._pane_id = pane_id or os.environ.get("HERDR_PANE_ID")
96
+ self._tab_id = tab_id or os.environ.get("HERDR_TAB_ID")
90
97
  self._active = bool(
91
98
  os.environ.get("HERDR_ENV") == "1"
92
99
  and self._socket_path
@@ -102,6 +109,13 @@ class HerdrClient:
102
109
  # Decorative lane (latest-wins, discarded on release).
103
110
  self._message: Optional[Dict[str, Any]] = None
104
111
  self._metadata: Optional[Dict[str, Any]] = None
112
+ # Tab-label job slot (latest-wins; survives release scheduling so
113
+ # the exit-time restore still drains before the release).
114
+ self._tab: Optional[Dict[str, Any]] = None
115
+ # Tab-label ownership state (guarded by ``self._cond``).
116
+ self._tab_original: Optional[str] = None
117
+ self._tab_renamed = False
118
+ self._tab_last_label: Optional[str] = None
105
119
  # Terminal release slot.
106
120
  self._release: Optional[Dict[str, Any]] = None
107
121
 
@@ -173,17 +187,74 @@ class HerdrClient:
173
187
  return
174
188
  self._put("_session", params)
175
189
 
176
- def report_metadata(self, tokens: Dict[str, Any]) -> None:
177
- """Report pane metadata (model / context / tokens) on the decorative lane."""
178
- if not tokens:
190
+ def report_metadata(
191
+ self,
192
+ tokens: Optional[Dict[str, Any]] = None,
193
+ *,
194
+ title: Optional[str] = None,
195
+ clear_title: bool = False,
196
+ ) -> None:
197
+ """Report pane metadata on the decorative lane (latest wins).
198
+
199
+ ``tokens`` are herdr's ``$token`` sidebar values; ``title`` sets the
200
+ pane presentation title (pane border + sidebar ``pane`` token);
201
+ ``clear_title`` drops it. No-op when nothing is set: herdr rejects
202
+ empty metadata envelopes. Note herdr replaces the whole per-source
203
+ metadata entry on each report, so a caller that sets a title must
204
+ keep re-sending it on later tokens-only reports or it is wiped.
205
+ """
206
+ if clear_title and title is not None:
207
+ # Caller bug: herdr rejects setting and clearing in one report.
208
+ # Clearing wins -- a stale title is less wrong than a rejected one.
209
+ title = None
210
+ if not clear_title and title is None and not tokens:
179
211
  return
180
212
  params: Dict[str, Any] = {
181
213
  "applies_to_source": SOURCE,
182
214
  "ttl_ms": _METADATA_TTL_MS,
183
- "tokens": dict(tokens),
184
215
  }
216
+ if clear_title:
217
+ params["clear_title"] = True
218
+ elif title is not None:
219
+ params["title"] = title
220
+ if tokens:
221
+ params["tokens"] = dict(tokens)
185
222
  self._put("_metadata", params)
186
223
 
224
+ def set_tab_label(
225
+ self, label: Optional[str], *, expected: Optional[str] = None
226
+ ) -> None:
227
+ """Set the label of the herdr workspace tab we run in, or restore it.
228
+
229
+ ``label=None`` restores the label that was in place when we first
230
+ took ownership (and only while the tab still shows ``expected`` --
231
+ a label the user changed meanwhile is left alone). The tab is only
232
+ ever relabelled when it holds a single pane: the tab bar is a
233
+ user-managed surface, and a tab shared with other panes is never
234
+ touched. Enqueued on the decorative lane; never blocks the caller,
235
+ and is a no-op when ``HERDR_TAB_ID`` is unset.
236
+ """
237
+ if not self._active or not self._tab_id:
238
+ return
239
+ with self._cond:
240
+ if label is not None:
241
+ if label == self._tab_last_label:
242
+ return
243
+ if (
244
+ self._tab is not None
245
+ and self._tab["op"] == "set"
246
+ and self._tab["label"] == label
247
+ ):
248
+ return # an identical set is already queued
249
+ elif not self._tab_renamed and self._tab is None:
250
+ return # never renamed and nothing queued: nothing to restore
251
+ self._tab = {
252
+ "op": "restore" if label is None else "set",
253
+ "label": label,
254
+ "expected": expected,
255
+ }
256
+ self._cond.notify()
257
+
187
258
  def _put(self, slot: str, params: Dict[str, Any]) -> None:
188
259
  if not self._active:
189
260
  return
@@ -249,6 +320,11 @@ class HerdrClient:
249
320
  if self._metadata is not None:
250
321
  params, self._metadata = self._metadata, None
251
322
  return _M_METADATA, params
323
+ # The tab job drains even while closing: the exit-time label
324
+ # restore is shutdown work and must land before the release.
325
+ if self._tab is not None:
326
+ job, self._tab = self._tab, None
327
+ return _M_TAB_RENAME, job
252
328
  if self._closing and self._release is not None:
253
329
  params, self._release = self._release, None
254
330
  return _M_RELEASE, params
@@ -266,7 +342,10 @@ class HerdrClient:
266
342
  self._cond.wait()
267
343
  job = self._take_next_locked()
268
344
  method, params = job
269
- self._send(method, params)
345
+ if method == _M_TAB_RENAME:
346
+ self._do_tab(params)
347
+ else:
348
+ self._send(method, params)
270
349
  if method == _M_RELEASE:
271
350
  self._released.set()
272
351
  return
@@ -286,6 +365,10 @@ class HerdrClient:
286
365
  **params,
287
366
  },
288
367
  }
368
+ self._transmit(method, envelope)
369
+
370
+ def _transmit(self, method: str, envelope: Dict[str, Any]) -> None:
371
+ """Fire-and-forget send with retry-until-acked. Never raises."""
289
372
  payload = (json.dumps(envelope) + "\n").encode("utf-8")
290
373
  last_exc: Optional[Exception] = None
291
374
  for attempt in range(_SEND_ATTEMPTS):
@@ -335,5 +418,101 @@ class HerdrClient:
335
418
  pipe.write(payload)
336
419
  return bool(pipe.readline(_ACK_BYTES))
337
420
 
421
+ # -- tab label -----------------------------------------------------
422
+
423
+ def _do_tab(self, job: Dict[str, Any]) -> None:
424
+ """Apply a tab-label set or restore, with the ownership gate.
425
+
426
+ Runs on the worker. The tab is only ever relabelled by us while it
427
+ holds exactly one pane: herdr's tab bar is a user-managed surface,
428
+ and a tab shared with other panes is never touched. The original
429
+ label is captured on first takeover and restored on a clean exit
430
+ -- but only while the tab still shows the label we last set, so a
431
+ manual rename by the user is never clobbered.
432
+ """
433
+ info = self._request(_M_TAB_GET, {"tab_id": self._tab_id}) or {}
434
+ result = info.get("result") if isinstance(info.get("result"), dict) else {}
435
+ tab = result.get("tab") if isinstance(result.get("tab"), dict) else {}
436
+ if tab.get("pane_count") != 1:
437
+ return # shared or vanished tab: leave its label alone
438
+ current = tab.get("label")
439
+ label = job.get("label")
440
+ with self._cond:
441
+ if label is None: # restore
442
+ if not (self._tab_renamed and self._tab_original):
443
+ return
444
+ expected = job.get("expected")
445
+ if expected is not None and current != expected:
446
+ return # the user changed it meanwhile; leave it
447
+ target = self._tab_original
448
+ else:
449
+ if not self._tab_renamed:
450
+ self._tab_original = current
451
+ self._tab_renamed = True
452
+ self._tab_last_label = label
453
+ target = label
454
+ if current != target:
455
+ seq = self._next_seq()
456
+ self._transmit(
457
+ _M_TAB_RENAME,
458
+ {
459
+ "id": f"{SOURCE}:{seq}",
460
+ "method": _M_TAB_RENAME,
461
+ "params": {"tab_id": self._tab_id, "label": target},
462
+ },
463
+ )
464
+ if label is None:
465
+ with self._cond:
466
+ self._tab_renamed = False
467
+ self._tab_original = None
468
+ self._tab_last_label = None
469
+
470
+ def _request(self, method: str, params: Dict[str, Any]) -> Optional[Dict[str, Any]]:
471
+ """One request/response round-trip on a fresh connection.
472
+
473
+ Used only for the tab-info read (``tab.get``). Unlike fire-and-forget
474
+ reports, the response carries data we need; any failure degrades to
475
+ ``None`` and the caller simply skips the operation.
476
+ """
477
+ seq = self._next_seq()
478
+ envelope = {"id": f"{SOURCE}:{seq}", "method": method, "params": params}
479
+ payload = (json.dumps(envelope) + "\n").encode("utf-8")
480
+ try:
481
+ raw = (
482
+ self._request_pipe(payload)
483
+ if os.name == "nt"
484
+ else self._request_unix(payload)
485
+ )
486
+ except (OSError, ValueError):
487
+ logger.debug("herdr %s failed", method, exc_info=True)
488
+ return None
489
+ if not raw:
490
+ return None
491
+ try:
492
+ reply = json.loads(raw.decode("utf-8", "replace"))
493
+ except ValueError:
494
+ return None
495
+ return reply if isinstance(reply, dict) else None
496
+
497
+ def _request_unix(self, payload: bytes) -> bytes:
498
+ with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
499
+ sock.settimeout(_CONNECT_TIMEOUT_S)
500
+ sock.connect(self._socket_path) # type: ignore[arg-type]
501
+ sock.sendall(payload)
502
+ line = b""
503
+ while not line.endswith(b"\n") and len(line) < 65536:
504
+ chunk = sock.recv(_ACK_BYTES)
505
+ if not chunk:
506
+ break
507
+ line += chunk
508
+ return line
509
+
510
+ def _request_pipe(self, payload: bytes) -> bytes:
511
+ # Same named-pipe mapping as ``_deliver_pipe`` (see there).
512
+ pipe_name = "\\\\.\\pipe\\" + str(self._socket_path)
513
+ with open(pipe_name, "r+b", buffering=0) as pipe:
514
+ pipe.write(payload)
515
+ return pipe.readline(65536)
516
+
338
517
 
339
518
  __all__ = ["HerdrClient", "SOURCE", "AGENT"]
@@ -31,13 +31,15 @@ Callback -> effect:
31
31
  * ``agent_run_cancel`` / ``interactive_turn_end`` .... reset -> idle
32
32
  * ``interactive_turn_cancel`` ........................ reset -> idle
33
33
  * ``awaiting_user_input`` ............................ blocked <-> not
34
+ * ``post_autosave`` .................................. title refresh / wait
34
35
 
35
36
  Session identity is the durable autosave (name, path) resolved by
36
37
  ``sources.current_session_ref`` -- NOT the per-run ``group_id`` UUID, which
37
- changes every turn. Pane metadata (model / context / tokens) and the
38
- best-effort activity ``message`` are decorative: they never perturb the
39
- authoritative state and never delay a state edge, session reference, or the
40
- final ``pane.release_agent`` on exit.
38
+ changes every turn. Pane metadata (model / context / tokens), the
39
+ session namer's conversation title, and the best-effort activity
40
+ ``message`` are decorative: they never perturb the authoritative state and
41
+ never delay a state edge, session reference, or the final
42
+ ``pane.release_agent`` on exit.
41
43
 
42
44
  Handlers are plain sync functions that swallow every argument: the callback
43
45
  dispatcher passes hook args positionally and runs sync callbacks happily
@@ -90,6 +92,11 @@ def _on_turn_end(*_args, **_kw) -> None:
90
92
  _reporter.on_turn_end()
91
93
 
92
94
 
95
+ def _on_post_autosave(*_args, **_kw) -> None:
96
+ # (SessionMetadata,) -- the reporter reads the sidecar itself.
97
+ _reporter.on_post_autosave()
98
+
99
+
93
100
  def _on_tool_start(*args, **kwargs):
94
101
  # (tool_name, tool_args, context=None). Decorative only -> return None so
95
102
  # the tool is never blocked or transformed.
@@ -127,6 +134,7 @@ if _reporter.active:
127
134
  register_callback("agent_run_cancel", _on_run_cancel)
128
135
  register_callback("interactive_turn_end", _on_turn_end)
129
136
  register_callback("interactive_turn_cancel", _on_turn_end)
137
+ register_callback("post_autosave", _on_post_autosave)
130
138
  register_callback("pre_tool_call", _on_tool_start)
131
139
  register_callback("post_tool_call", _on_tool_complete)
132
140
  register_callback("awaiting_user_input", _on_awaiting_user_input)
@@ -26,12 +26,19 @@ Effective state::
26
26
  Sub-agents fire the same ``agent_run_start`` / ``agent_run_end`` hooks as the
27
27
  root agent, so we refcount active runs (the same pattern the puppy_spinner
28
28
  plugin uses) rather than flipping idle when a sub-agent finishes.
29
+
30
+ Beyond state, the reporter propagates the session namer's auto-generated
31
+ conversation title to the pane (presentation title: herdr's pane border and
32
+ the sidebar ``pane`` token). The namer names the session asynchronously
33
+ after each autosave, so a bounded background wait re-reads the sidecar and
34
+ reports the title the moment it lands, without waiting for the next turn.
29
35
  """
30
36
 
31
37
  from __future__ import annotations
32
38
 
33
39
  import logging
34
40
  import threading
41
+ import time
35
42
  from typing import Optional, Tuple
36
43
 
37
44
  from .client import HerdrClient
@@ -48,6 +55,11 @@ IDLE = "idle"
48
55
  THINKING = "thinking"
49
56
  AWAITING = "awaiting input"
50
57
 
58
+ # The namer's model call has its own 60s timeout; the wait for a fresh
59
+ # title must cover that plus queueing slack, then give up.
60
+ _TITLE_WAIT_INTERVAL_S = 2.0
61
+ _TITLE_WAIT_TIMEOUT_S = 90.0
62
+
51
63
 
52
64
  class HerdrReporter:
53
65
  """Thread-safe, dedup-ing bridge from callbacks to :class:`HerdrClient`."""
@@ -66,6 +78,13 @@ class HerdrReporter:
66
78
  # Durable session reference (name, pickle_path) — NOT the per-run group_id UUID,
67
79
  # which changes every turn and can't identify a resumable session.
68
80
  self._session_ref: Optional[Tuple[str, str]] = None
81
+ # The title we believe herdr currently shows for our source (herdr
82
+ # replaces the whole per-source metadata entry per report, so this
83
+ # must always match the last envelope we sent).
84
+ self._reported_title: Optional[str] = None
85
+ # Single-flight background wait for the namer's async title write.
86
+ self._title_wait: Optional[threading.Thread] = None
87
+ self._title_wait_session: Optional[str] = None
69
88
 
70
89
  @property
71
90
  def active(self) -> bool:
@@ -139,6 +158,26 @@ class HerdrReporter:
139
158
  def on_user_prompt(self, *_ignored) -> None:
140
159
  # Ignore the callback's per-run group_id; resolve the durable session.
141
160
  self._refresh_session()
161
+ # The title belongs to the session: a resumed or fresh session shows
162
+ # its own title (or none) without waiting for the next turn.
163
+ self._refresh_title()
164
+
165
+ def on_post_autosave(self, *_ignored) -> None:
166
+ """A session was just saved: report a fresh title, or wait for one.
167
+
168
+ The namer names the conversation asynchronously after this event, so
169
+ a title typically lands seconds later. When the session is still
170
+ unnamed and the namer is enabled, a bounded background wait reports
171
+ the title as soon as it appears. No-op outside herdr.
172
+ """
173
+ if not self._client.active:
174
+ return
175
+ if sources.current_session_title() is not None:
176
+ self._refresh_title()
177
+ return
178
+ if not sources.naming_enabled():
179
+ return
180
+ self._start_title_wait()
142
181
 
143
182
  def on_run_start(self, *_ignored) -> None:
144
183
  with self._lock:
@@ -190,10 +229,88 @@ class HerdrReporter:
190
229
  self._emit_metadata()
191
230
 
192
231
  def _emit_metadata(self) -> None:
193
- """Compute and enqueue pane metadata. Never holds the reporter lock."""
194
- payload = sources.current_tokens_payload()
195
- if payload:
196
- self._client.report_metadata(payload)
232
+ """Compute and enqueue pane metadata. Never holds the reporter lock.
233
+
234
+ The tokens payload and the session title ride one envelope: herdr
235
+ replaces the whole per-source metadata entry on each report, so a
236
+ tokens report that omits the title would silently wipe it.
237
+ """
238
+ tokens = sources.current_tokens_payload()
239
+ title = sources.current_session_title()
240
+ changed, previous = self._claim_title(title)
241
+ if tokens is None and not changed:
242
+ return
243
+ # Clear only on a set->None transition; when a tokens report is
244
+ # present, its entry replacement clears any stale title for us.
245
+ self._client.report_metadata(
246
+ tokens, title=title, clear_title=changed and title is None
247
+ )
248
+ if changed:
249
+ self._client.set_tab_label(title, expected=previous)
250
+
251
+ # -- session title propagation --------------------------------------
252
+
253
+ def _claim_title(self, title: Optional[str]) -> Tuple[bool, Optional[str]]:
254
+ """Record ``title`` as the herdr-side value.
255
+
256
+ Returns ``(changed, previous)`` -- ``previous`` is the value herdr
257
+ showed before this claim, so a clear can tell the tab-label restore
258
+ what label it should find there. Both title paths (turn-end
259
+ metadata and title-only refresh) go through here, so
260
+ ``_reported_title`` is the single source of truth for what herdr
261
+ currently shows for our source.
262
+ """
263
+ with self._lock:
264
+ previous = self._reported_title
265
+ if title == previous:
266
+ return False, previous
267
+ self._reported_title = title
268
+ return True, previous
269
+
270
+ def _refresh_title(self) -> bool:
271
+ """Report the current session's title (or its absence). Title-only.
272
+
273
+ Returns True when a report was enqueued. Safe to call whenever:
274
+ deduped by :meth:`_claim_title`.
275
+ """
276
+ title = sources.current_session_title()
277
+ changed, previous = self._claim_title(title)
278
+ if not changed:
279
+ return False
280
+ self._client.report_metadata(None, title=title, clear_title=(title is None))
281
+ self._client.set_tab_label(title, expected=previous)
282
+ return True
283
+
284
+ def _start_title_wait(self) -> None:
285
+ """Arm a bounded, session-pinned background wait for a fresh title.
286
+
287
+ Single-flight: at most one wait at a time. The wait stops on title
288
+ arrival, session change, shutdown (daemon thread), or timeout.
289
+ """
290
+ session = sources.current_session_name()
291
+ with self._lock:
292
+ wait = self._title_wait
293
+ if wait is not None and wait.is_alive():
294
+ return
295
+ wait = threading.Thread(
296
+ target=self._title_wait_loop, name="herdr-title-wait", daemon=True
297
+ )
298
+ self._title_wait = wait
299
+ self._title_wait_session = session
300
+ wait.start()
301
+
302
+ def _title_wait_loop(self) -> None:
303
+ """Re-check the sidecar until the title lands, the session changes,
304
+ or the timeout elapses. Runs on its own daemon thread; every step
305
+ is fail-soft."""
306
+ deadline = time.monotonic() + _TITLE_WAIT_TIMEOUT_S
307
+ pinned = self._title_wait_session
308
+ while time.monotonic() < deadline:
309
+ time.sleep(_TITLE_WAIT_INTERVAL_S)
310
+ if sources.current_session_name() != pinned:
311
+ return # the new prompt's refresh owns the new session's title
312
+ if self._refresh_title():
313
+ return # title landed (or its absence was reported)
197
314
 
198
315
  def on_awaiting_user_input(self, awaiting: bool, *, notify: bool = True) -> None:
199
316
  """Track an interactive wait, notifying only when requested."""
@@ -203,6 +320,14 @@ class HerdrReporter:
203
320
  self._sync()
204
321
 
205
322
  def on_shutdown(self) -> None:
323
+ # If we relabelled the workspace tab, restore its original label
324
+ # first: the client drains the tab job ahead of the release on its
325
+ # worker. A title currently displayed means the tab may be ours;
326
+ # no title ever shown means no tab job is needed at all.
327
+ with self._lock:
328
+ expected = self._reported_title
329
+ if expected is not None:
330
+ self._client.set_tab_label(None, expected=expected)
206
331
  # Release pane authority directly (no intermediate idle report).
207
332
  # release_and_close() is idempotent and bounded, so calling it from both
208
333
  # session_end and shutdown can never delay process exit.