code-puppy-core-plugins 0.0.4__tar.gz → 0.0.6__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 (317) hide show
  1. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/PKG-INFO +1 -1
  2. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/PLUGINS_AND_CALLBACKS.md +15 -1
  3. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/SKILL.md +2 -2
  4. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/SYSTEM_PROMPT_CONFIG_AND_I18N.md +17 -0
  5. code_puppy_core_plugins-0.0.6/code_puppy_core_plugins/spill/LICENSE.deepseek +28 -0
  6. code_puppy_core_plugins-0.0.6/code_puppy_core_plugins/spill/__init__.py +1 -0
  7. code_puppy_core_plugins-0.0.6/code_puppy_core_plugins/spill/register_callbacks.py +256 -0
  8. code_puppy_core_plugins-0.0.6/code_puppy_core_plugins/spill/store.py +173 -0
  9. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/pyproject.toml +2 -1
  10. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/.gitignore +0 -0
  11. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/LICENSE +0 -0
  12. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/README.md +0 -0
  13. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/__init__.py +0 -0
  14. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/README.md +0 -0
  15. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/__init__.py +0 -0
  16. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/agent.py +0 -0
  17. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/bridge.py +0 -0
  18. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/capabilities.py +0 -0
  19. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/commands.py +0 -0
  20. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/content.py +0 -0
  21. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/io_delegation.py +0 -0
  22. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/mcp_config.py +0 -0
  23. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/permissions.py +0 -0
  24. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/persistence.py +0 -0
  25. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/register_callbacks.py +0 -0
  26. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/replay.py +0 -0
  27. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/session.py +0 -0
  28. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/session_config.py +0 -0
  29. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/acp/state.py +0 -0
  30. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/__init__.py +0 -0
  31. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/config.py +0 -0
  32. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/discovery.py +0 -0
  33. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/downloader.py +0 -0
  34. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/enabled_skills.py +0 -0
  35. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/installer.py +0 -0
  36. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/metadata.py +0 -0
  37. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/prompt_builder.py +0 -0
  38. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/provider.py +0 -0
  39. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/register_callbacks.py +0 -0
  40. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/remote_catalog.py +0 -0
  41. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/skill_catalog.py +0 -0
  42. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/skill_commands.py +0 -0
  43. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/skills_install_menu.py +0 -0
  44. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/agent_skills/skills_menu.py +0 -0
  45. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/aws_bedrock/__init__.py +0 -0
  46. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/aws_bedrock/config.py +0 -0
  47. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/aws_bedrock/register_callbacks.py +0 -0
  48. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/aws_bedrock/utils.py +0 -0
  49. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/azure_foundry/README.md +0 -0
  50. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/azure_foundry/__init__.py +0 -0
  51. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/azure_foundry/config.py +0 -0
  52. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/azure_foundry/discovery.py +0 -0
  53. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/azure_foundry/register_callbacks.py +0 -0
  54. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/azure_foundry/token.py +0 -0
  55. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/azure_foundry/utils.py +0 -0
  56. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/btw/__init__.py +0 -0
  57. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/btw/inline_view.py +0 -0
  58. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/btw/register_callbacks.py +0 -0
  59. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/btw/side_query.py +0 -0
  60. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/IMAGEGEN_SKILL.md +0 -0
  61. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/__init__.py +0 -0
  62. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/config.py +0 -0
  63. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/image_generation.py +0 -0
  64. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/image_tool.py +0 -0
  65. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/oauth_flow.py +0 -0
  66. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/register_callbacks.py +0 -0
  67. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/test_plugin.py +0 -0
  68. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/usage.py +0 -0
  69. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/chatgpt_oauth/utils.py +0 -0
  70. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_hooks/__init__.py +0 -0
  71. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_hooks/config.py +0 -0
  72. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_hooks/register_callbacks.py +0 -0
  73. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/README.md +0 -0
  74. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/SETUP.md +0 -0
  75. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/__init__.py +0 -0
  76. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/config.py +0 -0
  77. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/fast_mode.py +0 -0
  78. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/prompt_handler.py +0 -0
  79. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/register_callbacks.py +0 -0
  80. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/test_plugin.py +0 -0
  81. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
  82. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/claude_code_oauth/utils.py +0 -0
  83. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/AGENTS_AND_TOOLS.md +0 -0
  84. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/MODELS_AND_MCP.md +0 -0
  85. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/SESSIONS_AND_HISTORY.md +0 -0
  86. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/SKILLS_SYSTEM.md +0 -0
  87. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/__init__.py +0 -0
  88. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/code_puppy_agent/register_callbacks.py +0 -0
  89. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/NativeCapture.swift +0 -0
  90. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/README.md +0 -0
  91. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/__init__.py +0 -0
  92. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/accessibility.py +0 -0
  93. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/activation.py +0 -0
  94. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/backend.py +0 -0
  95. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/backend_types.py +0 -0
  96. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/capture.py +0 -0
  97. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/commands.py +0 -0
  98. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/geometry.py +0 -0
  99. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/inline_image.py +0 -0
  100. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/keycodes.py +0 -0
  101. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/policy.py +0 -0
  102. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/register_callbacks.py +0 -0
  103. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/safety.py +0 -0
  104. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/settle.py +0 -0
  105. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/state.py +0 -0
  106. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/computer_use/tools.py +0 -0
  107. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/context_indicator/__init__.py +0 -0
  108. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/context_indicator/register_callbacks.py +0 -0
  109. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/context_indicator/usage.py +0 -0
  110. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/copilot_auth/__init__.py +0 -0
  111. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/copilot_auth/config.py +0 -0
  112. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/copilot_auth/reasoning_client.py +0 -0
  113. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/copilot_auth/register_callbacks.py +0 -0
  114. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/copilot_auth/utils.py +0 -0
  115. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/customizable_commands/__init__.py +0 -0
  116. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/customizable_commands/register_callbacks.py +0 -0
  117. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/__init__.py +0 -0
  118. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/cancel.py +0 -0
  119. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/commands.py +0 -0
  120. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/config.py +0 -0
  121. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/lifecycle.py +0 -0
  122. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/register_callbacks.py +0 -0
  123. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/runtime.py +0 -0
  124. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/startup_lock.py +0 -0
  125. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/workflow_ids.py +0 -0
  126. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/dbos_durable_exec/wrapper.py +0 -0
  127. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/destructive_command_guard/AGENTS.md +0 -0
  128. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/destructive_command_guard/__init__.py +0 -0
  129. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/destructive_command_guard/detector.py +0 -0
  130. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/destructive_command_guard/register_callbacks.py +0 -0
  131. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/emoji_filter/__init__.py +0 -0
  132. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/emoji_filter/config.py +0 -0
  133. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/emoji_filter/register_callbacks.py +0 -0
  134. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/emoji_filter/stripper.py +0 -0
  135. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/empty_html_comment_filter/register_callbacks.py +0 -0
  136. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/example_custom_command/README.md +0 -0
  137. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/example_custom_command/register_callbacks.py +0 -0
  138. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/file_permission_handler/__init__.py +0 -0
  139. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/file_permission_handler/register_callbacks.py +0 -0
  140. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/__init__.py +0 -0
  141. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/README.md +0 -0
  142. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/cheatsheet.md +0 -0
  143. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/pipeline.md +0 -0
  144. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/_docs/synopsis.md +0 -0
  145. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/about.md +0 -0
  146. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/address-feedback.md +0 -0
  147. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/ask.md +0 -0
  148. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/aug.md +0 -0
  149. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/auto-pilot.md +0 -0
  150. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/cheatsheet.md +0 -0
  151. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/commit.md +0 -0
  152. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/config.md +0 -0
  153. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/create-pr.md +0 -0
  154. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/exec.md +0 -0
  155. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/new.md +0 -0
  156. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/qa.md +0 -0
  157. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/rebase.md +0 -0
  158. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/review.md +0 -0
  159. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/split.md +0 -0
  160. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/squash-commits.md +0 -0
  161. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/status.md +0 -0
  162. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/commands/flux/tests.md +0 -0
  163. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_about.py +0 -0
  164. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_cheatsheet.py +0 -0
  165. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/bundled/scripts/flux_status.py +0 -0
  166. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/installer.py +0 -0
  167. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/flux_bootstrap/register_callbacks.py +0 -0
  168. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/force_push_guard/__init__.py +0 -0
  169. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/force_push_guard/detector.py +0 -0
  170. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/force_push_guard/register_callbacks.py +0 -0
  171. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/fork/__init__.py +0 -0
  172. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/fork/register_callbacks.py +0 -0
  173. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/frontend_emitter/__init__.py +0 -0
  174. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/frontend_emitter/emitter.py +0 -0
  175. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/frontend_emitter/register_callbacks.py +0 -0
  176. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/frontend_emitter/session_context.py +0 -0
  177. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/grok_oauth/__init__.py +0 -0
  178. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/grok_oauth/config.py +0 -0
  179. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/grok_oauth/oauth_flow.py +0 -0
  180. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/grok_oauth/register_callbacks.py +0 -0
  181. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/grok_oauth/utils.py +0 -0
  182. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/herdr/README.md +0 -0
  183. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/herdr/__init__.py +0 -0
  184. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/herdr/client.py +0 -0
  185. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/herdr/register_callbacks.py +0 -0
  186. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/herdr/reporter.py +0 -0
  187. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/herdr/smoke.py +0 -0
  188. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/herdr/sources.py +0 -0
  189. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/hook_creator/__init__.py +0 -0
  190. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/hook_creator/register_callbacks.py +0 -0
  191. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/hook_manager/__init__.py +0 -0
  192. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/hook_manager/config.py +0 -0
  193. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/hook_manager/hooks_menu.py +0 -0
  194. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/hook_manager/register_callbacks.py +0 -0
  195. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/meta_oauth/__init__.py +0 -0
  196. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/meta_oauth/config.py +0 -0
  197. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/meta_oauth/oauth_flow.py +0 -0
  198. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/meta_oauth/register_callbacks.py +0 -0
  199. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/meta_oauth/utils.py +0 -0
  200. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/namespace_skill_search/README.md +0 -0
  201. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/namespace_skill_search/__init__.py +0 -0
  202. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/namespace_skill_search/namespaces.py +0 -0
  203. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/namespace_skill_search/register_callbacks.py +0 -0
  204. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/namespace_skill_search/search_tool.py +0 -0
  205. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/no_tools/__init__.py +0 -0
  206. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/no_tools/register_callbacks.py +0 -0
  207. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/oauth_pasteback.py +0 -0
  208. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/oauth_puppy_html.py +0 -0
  209. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/obsidian_agent/README.md +0 -0
  210. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/obsidian_agent/__init__.py +0 -0
  211. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/obsidian_agent/agent_obsidian.py +0 -0
  212. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/obsidian_agent/register_callbacks.py +0 -0
  213. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/ollama/__init__.py +0 -0
  214. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/ollama/register_callbacks.py +0 -0
  215. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/ollama_setup/__init__.py +0 -0
  216. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/ollama_setup/completer.py +0 -0
  217. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/ollama_setup/register_callbacks.py +0 -0
  218. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/__init__.py +0 -0
  219. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/plugin_contributions.py +0 -0
  220. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/plugin_meta.py +0 -0
  221. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/plugin_text_utils.py +0 -0
  222. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/plugins_menu.py +0 -0
  223. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/plugins_menu_layout.py +0 -0
  224. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/plugins_menu_render.py +0 -0
  225. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/project_trust_flow.py +0 -0
  226. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/plugin_list/register_callbacks.py +0 -0
  227. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/pop_command/__init__.py +0 -0
  228. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/pop_command/register_callbacks.py +0 -0
  229. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/prompt_newline/__init__.py +0 -0
  230. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/prompt_newline/config.py +0 -0
  231. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/prompt_newline/register_callbacks.py +0 -0
  232. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/prune/__init__.py +0 -0
  233. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/prune/prune_menu.py +0 -0
  234. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/prune/prune_model.py +0 -0
  235. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/prune/prune_render.py +0 -0
  236. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/prune/register_callbacks.py +0 -0
  237. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/README.md +0 -0
  238. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/__init__.py +0 -0
  239. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/commands.py +0 -0
  240. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/config.py +0 -0
  241. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/kennel.py +0 -0
  242. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/packer.py +0 -0
  243. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/recorder.py +0 -0
  244. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/register_callbacks.py +0 -0
  245. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/retriever.py +0 -0
  246. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/schema.py +0 -0
  247. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/state.py +0 -0
  248. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/tools.py +0 -0
  249. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_kennel/wings.py +0 -0
  250. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_spinner/README.md +0 -0
  251. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_spinner/__init__.py +0 -0
  252. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_spinner/builtin_frames.py +0 -0
  253. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_spinner/commands.py +0 -0
  254. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_spinner/picker.py +0 -0
  255. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_spinner/register_callbacks.py +0 -0
  256. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/puppy_spinner/spinners.py +0 -0
  257. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/quick_resume/__init__.py +0 -0
  258. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/quick_resume/register_callbacks.py +0 -0
  259. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/review_pr/__init__.py +0 -0
  260. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/review_pr/register_callbacks.py +0 -0
  261. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/shell_safety/__init__.py +0 -0
  262. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/shell_safety/agent_shell_safety.py +0 -0
  263. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/shell_safety/command_cache.py +0 -0
  264. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/shell_safety/register_callbacks.py +0 -0
  265. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/stack_dump/__init__.py +0 -0
  266. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/stack_dump/register_callbacks.py +0 -0
  267. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/statusline/__init__.py +0 -0
  268. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/statusline/config.py +0 -0
  269. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/statusline/payload.py +0 -0
  270. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/statusline/prompt_patch.py +0 -0
  271. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/statusline/register_callbacks.py +0 -0
  272. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/statusline/runner.py +0 -0
  273. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/statusline/statusline_command.py +0 -0
  274. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/steer_queue/__init__.py +0 -0
  275. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/steer_queue/queue_menu.py +0 -0
  276. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/steer_queue/register_callbacks.py +0 -0
  277. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/subagent_panel/README.md +0 -0
  278. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/subagent_panel/__init__.py +0 -0
  279. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/subagent_panel/coalesce_patch.py +0 -0
  280. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/subagent_panel/panel_render.py +0 -0
  281. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/subagent_panel/register_callbacks.py +0 -0
  282. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/subagent_panel/resume_repaint.py +0 -0
  283. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/subagent_panel/state.py +0 -0
  284. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/switch_agent_resume/__init__.py +0 -0
  285. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/switch_agent_resume/register_callbacks.py +0 -0
  286. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/README.md +0 -0
  287. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/__init__.py +0 -0
  288. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/bundled_palettes.py +0 -0
  289. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/content_styles.py +0 -0
  290. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/osc_palette.py +0 -0
  291. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/picker.py +0 -0
  292. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/prompt_toolkit_theme.py +0 -0
  293. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/register_callbacks.py +0 -0
  294. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/rich_themes.py +0 -0
  295. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/theme/themes.py +0 -0
  296. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/timestamp_heartbeat/__init__.py +0 -0
  297. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/timestamp_heartbeat/register_callbacks.py +0 -0
  298. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/token_ratio_learner/__init__.py +0 -0
  299. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/token_ratio_learner/ratios.py +0 -0
  300. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/token_ratio_learner/register_callbacks.py +0 -0
  301. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/universal_constructor/__init__.py +0 -0
  302. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/universal_constructor/models.py +0 -0
  303. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/universal_constructor/provider.py +0 -0
  304. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/universal_constructor/register_callbacks.py +0 -0
  305. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/universal_constructor/registry.py +0 -0
  306. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/universal_constructor/sandbox.py +0 -0
  307. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wide_completion_menu/__init__.py +0 -0
  308. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wide_completion_menu/register_callbacks.py +0 -0
  309. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wiggum/__init__.py +0 -0
  310. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wiggum/goal_runs.py +0 -0
  311. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wiggum/judge.py +0 -0
  312. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wiggum/judge_config.py +0 -0
  313. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wiggum/judges_menu.py +0 -0
  314. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wiggum/register_callbacks.py +0 -0
  315. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/wiggum/state.py +0 -0
  316. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/code_puppy_core_plugins/yolo_cli/__init__.py +0 -0
  317. {code_puppy_core_plugins-0.0.4 → code_puppy_core_plugins-0.0.6}/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.4
3
+ Version: 0.0.6
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
@@ -36,13 +36,27 @@ time. All hooks accept sync or async functions.
36
36
  | `get_model_system_prompt` | Per-model prompt patch | `dict` with `instructions`/`handled` or `None` |
37
37
  | `custom_command` | Unknown `/slash` command | `True` (handled), `str` (message), or `None` (not mine) |
38
38
  | `pre_tool_call` | Before tool executes | Can modify args |
39
- | `post_tool_call` | After tool finishes | Observes result + duration |
39
+ | `post_tool_call` | After tool finishes | Observes result + duration; can mutate dict results in place |
40
40
  | `run_shell_command` | Before shell exec | Return `{"blocked": True}` to block |
41
41
  | `file_permission` | Before file op | `bool` — allow/deny |
42
42
  | `agent_run_start` / `agent_run_end` | Agent lifecycle | Observes name, model, session |
43
43
 
44
44
  The full list is in `callbacks.py` — `PhaseType` has ~45 phases.
45
45
 
46
+ ### Mutating results from `post_tool_call`
47
+
48
+ The patched tool runner evaluates the result reference before awaiting
49
+ `post_tool_call`. A callback can therefore mutate a plain dict result in
50
+ place and the model sees the change. It cannot replace a string or other
51
+ non-dict result by rebinding its local argument. Tool exceptions arrive
52
+ as error-only dicts and should remain intact.
53
+
54
+ Mutation is order-sensitive: result-bounding callbacks must run after
55
+ callbacks that append content. Sync callbacks also execute on the event
56
+ loop, so blocking work belongs in an async callback via
57
+ `asyncio.to_thread()`. The builtin `spill` plugin is the canonical
58
+ implementation.
59
+
46
60
  ## Minimal plugin example
47
61
 
48
62
  ```
@@ -89,11 +89,11 @@ Plugins hook into every stage via callbacks.
89
89
  | File | Read this for |
90
90
  |------|----------------|
91
91
  | `AGENTS_AND_TOOLS.md` | How agents are structured/discovered (Python, JSON, plugin agents, precedence). How tools get registered and wired to an agent. Async-tool blocking-I/O gotcha. |
92
- | `PLUGINS_AND_CALLBACKS.md` | Plugin discovery tiers, the full callback hook table, a minimal plugin example, and **two hook-system gotchas** (`get_model_system_prompt` last-write-wins; don't do real work at import time) worth reading before writing any new plugin. |
92
+ | `PLUGINS_AND_CALLBACKS.md` | Plugin discovery tiers, the callback hook table, in-place tool-result mutation and ordering, a minimal plugin example, and hook-system gotchas (`get_model_system_prompt` last-write-wins; don't do real work at import time). |
93
93
  | `MODELS_AND_MCP.md` | ModelFactory, model config precedence, model types. MCP server lifecycle, agent bindings, and a known gap (MCP servers can't yet provide skills). |
94
94
  | `SESSIONS_AND_HISTORY.md` | Message history, context-window compaction, session save/load commands. |
95
95
  | `SKILLS_SYSTEM.md` | Skill discovery/activation, bundled-resource-file gotcha for plugin-registered skills, and **skill namespaces** — how `namespace_skill_search` groups large skill catalogs and replaces the flat prompt list. |
96
- | `SYSTEM_PROMPT_CONFIG_AND_I18N.md` | Exact system-prompt assembly order (which layer skills/rules/patches land in), `puppy.cfg` + key directories, the messaging bus, and an i18n quick-reference (full guide: `docs/I18N.md`). |
96
+ | `SYSTEM_PROMPT_CONFIG_AND_I18N.md` | Exact system-prompt assembly order, `puppy.cfg` + key directories, spill configuration, the messaging bus, and an i18n quick-reference (full guide: `docs/I18N.md`). |
97
97
 
98
98
  Don't guess which file has what you need — the table above is exhaustive
99
99
  for this skill's scope. If a question doesn't map cleanly to one row, it's
@@ -76,6 +76,23 @@ turning off `frontmatter_in_system_prompt` on its first run) does **not**
76
76
  automatically revert. Disabling the plugin and undoing what it already
77
77
  did to your config are two separate actions.
78
78
 
79
+ ### Bounding oversized tool results with `spill`
80
+
81
+ The builtin `spill` plugin saves oversized top-level string fields to
82
+ private files and substitutes bounded head/tail previews with retrieval
83
+ guidance. It leaves error-only and non-dict results untouched and skips
84
+ `read_file` by default to avoid a read → spill → read loop.
85
+
86
+ | `puppy.cfg` key | Default | Meaning |
87
+ |-----------------|---------|---------|
88
+ | `spill_max_inline_bytes` | `32768` | Aggregate inline string-byte cap; `0` or negative disables spilling |
89
+ | `spill_preview_bytes` | `4096` | Head-plus-tail source-byte budget per spilled field |
90
+ | `spill_root` | unset | Storage root override; otherwise use a private OS temp directory |
91
+ | `spill_skip_tools` | `read_file` | Comma-separated tool names that must remain inline |
92
+
93
+ Storage is best-effort: any spill failure keeps the original successful
94
+ tool result inline.
95
+
79
96
  ---
80
97
 
81
98
  ## Messaging & UI
@@ -0,0 +1,28 @@
1
+ DeepSeek Harness spill attribution
2
+
3
+ The spill functionality in this package is based on the spill packages from
4
+ DeepSeek Harness:
5
+
6
+ https://github.com/deepseek-ai/DeepSeek-Harness
7
+
8
+ MIT License
9
+
10
+ Copyright (c) 2026 DeepSeek
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ """Keep oversized dict-shaped tool results out of model context."""
@@ -0,0 +1,256 @@
1
+ """Plugin: spill oversized dict-shaped tool results to private files.
2
+
3
+ Ported from DeepSeek Harness's MIT-licensed spill design. See
4
+ ``LICENSE.deepseek`` in this package for its copyright and license notice.
5
+
6
+ The post-tool hook receives the same dict reference that Code Puppy later
7
+ serializes for the model, so this plugin can replace top-level string fields
8
+ in place. Non-dict results (notably plain strings) cannot be replaced through
9
+ this hook and are deliberately left untouched.
10
+
11
+ When the combined UTF-8 size of top-level string values exceeds the configured
12
+ cap, fields are considered largest-first. Their full text is saved verbatim,
13
+ then replaced by a bounded byte-sliced head/tail preview and a retrieval notice.
14
+ ``read_file`` is skipped by default to avoid a read -> spill -> read loop.
15
+ Every failure is best-effort: the successful tool result stays available inline.
16
+
17
+ Config (puppy.cfg, also settable with ``/set``):
18
+ spill_max_inline_bytes = 32768 # 0 or negative disables
19
+ spill_preview_bytes = 4096 # source bytes retained per field
20
+ spill_root = # unset uses a private OS temp directory
21
+ spill_skip_tools = read_file # comma-separated tool names
22
+ """
23
+
24
+ from __future__ import annotations
25
+
26
+ import asyncio
27
+ import logging
28
+ import math
29
+ from pathlib import Path
30
+ from typing import Any
31
+
32
+ from code_puppy.callbacks import register_callback, unregister_callback
33
+
34
+ from . import store
35
+
36
+ logger = logging.getLogger(__name__)
37
+
38
+ MAX_INLINE_KEY = "spill_max_inline_bytes"
39
+ PREVIEW_KEY = "spill_preview_bytes"
40
+ ROOT_KEY = "spill_root"
41
+ SKIP_TOOLS_KEY = "spill_skip_tools"
42
+ DEFAULT_MAX_INLINE_BYTES = 32768
43
+ DEFAULT_PREVIEW_BYTES = 4096
44
+ DEFAULT_SKIP_TOOLS = frozenset({"read_file"})
45
+ OMISSION_MARKER = "\n\n[...]\n\n"
46
+
47
+
48
+ def _get_value(key: str) -> Any:
49
+ try:
50
+ from code_puppy.config import get_value
51
+
52
+ return get_value(key)
53
+ except Exception:
54
+ return None
55
+
56
+
57
+ def _get_int(key: str, default: int) -> int:
58
+ raw = _get_value(key)
59
+ if raw is None or str(raw).strip() == "":
60
+ return default
61
+ try:
62
+ return int(str(raw).strip())
63
+ except (TypeError, ValueError):
64
+ logger.warning("Invalid %s value; falling back to %d", key, default)
65
+ return default
66
+
67
+
68
+ def _get_root() -> str | None:
69
+ raw = _get_value(ROOT_KEY)
70
+ if raw is None or not str(raw).strip():
71
+ return None
72
+ return str(raw).strip()
73
+
74
+
75
+ def _get_skip_tools() -> frozenset[str]:
76
+ raw = _get_value(SKIP_TOOLS_KEY)
77
+ if raw is None or not str(raw).strip():
78
+ return DEFAULT_SKIP_TOOLS
79
+ return frozenset(name.strip() for name in str(raw).split(",") if name.strip())
80
+
81
+
82
+ def _byte_size(text: str) -> int:
83
+ return len(text.encode("utf-8"))
84
+
85
+
86
+ def _preview(text: str, budget: int) -> tuple[str, int]:
87
+ """Return a byte-sliced preview and the count of omitted source bytes."""
88
+ encoded = text.encode("utf-8")
89
+ kept_bytes = min(max(0, budget), len(encoded))
90
+ if kept_bytes == 0:
91
+ return "", len(encoded)
92
+ head_bytes = math.ceil(kept_bytes / 2)
93
+ tail_bytes = math.floor(kept_bytes / 2)
94
+ head = encoded[:head_bytes].decode("utf-8", errors="replace")
95
+ tail = encoded[-tail_bytes:].decode("utf-8", errors="replace") if tail_bytes else ""
96
+ return f"{head}{OMISSION_MARKER}{tail}", len(encoded) - kept_bytes
97
+
98
+
99
+ def _notice(omitted: int, path: Path) -> str:
100
+ return (
101
+ f"(~{omitted} bytes omitted. Full output stored at: {path}. "
102
+ "Retrieve it with read_file using start_line/num_lines, or grep this path.)"
103
+ )
104
+
105
+
106
+ def _build_replacement(
107
+ text: str,
108
+ path: Path,
109
+ preview_bytes: int,
110
+ max_bytes: int | None,
111
+ ) -> str | None:
112
+ """Build a strictly smaller replacement, optionally fitting ``max_bytes``."""
113
+ original_bytes = _byte_size(text)
114
+ budget = min(max(0, preview_bytes), original_bytes)
115
+ limit = original_bytes - 1
116
+ if max_bytes is not None:
117
+ limit = min(limit, max_bytes)
118
+ if limit < 0:
119
+ return None
120
+
121
+ while True:
122
+ preview, omitted = _preview(text, budget)
123
+ notice = _notice(omitted, path)
124
+ replacement = f"{preview}\n\n{notice}" if preview else notice
125
+ replacement_bytes = _byte_size(replacement)
126
+ if replacement_bytes <= limit:
127
+ return replacement
128
+ if budget == 0:
129
+ return None
130
+ budget = max(0, budget - max(1, replacement_bytes - limit))
131
+
132
+
133
+ def _spill_result(
134
+ tool_name: str, result: dict[Any, Any], session_id: str | None = None
135
+ ) -> None:
136
+ cap = _get_int(MAX_INLINE_KEY, DEFAULT_MAX_INLINE_BYTES)
137
+ if cap <= 0 or tool_name in _get_skip_tools():
138
+ return
139
+ preview_bytes = _get_int(PREVIEW_KEY, DEFAULT_PREVIEW_BYTES)
140
+ if preview_bytes < 0:
141
+ logger.warning(
142
+ "Invalid %s value; falling back to %d",
143
+ PREVIEW_KEY,
144
+ DEFAULT_PREVIEW_BYTES,
145
+ )
146
+ preview_bytes = DEFAULT_PREVIEW_BYTES
147
+
148
+ fields = [
149
+ (key, value, _byte_size(value))
150
+ for key, value in result.items()
151
+ if isinstance(value, str)
152
+ ]
153
+ total = sum(size for _, _, size in fields)
154
+ if total <= cap:
155
+ return
156
+
157
+ replacements: dict[Any, str] = {}
158
+ for key, original, original_bytes in sorted(
159
+ fields, key=lambda item: item[2], reverse=True
160
+ ):
161
+ if total <= cap:
162
+ break
163
+ try:
164
+ path = store.save_text(
165
+ original, tool_name, _get_root(), session_id=session_id
166
+ )
167
+ except Exception:
168
+ logger.warning(
169
+ "Failed to spill %s result field %r; keeping it inline",
170
+ tool_name,
171
+ key,
172
+ exc_info=True,
173
+ )
174
+ continue
175
+
176
+ other_bytes = total - original_bytes
177
+ field_limit = cap - other_bytes if other_bytes < cap else None
178
+ replacement = _build_replacement(
179
+ original,
180
+ path,
181
+ preview_bytes,
182
+ field_limit,
183
+ )
184
+ if replacement is None:
185
+ logger.warning(
186
+ "Spill notice for %s result field %r cannot fit; keeping it inline",
187
+ tool_name,
188
+ key,
189
+ )
190
+ continue
191
+ replacements[key] = replacement
192
+ total = other_bytes + _byte_size(replacement)
193
+
194
+ # Commit atomically. A partial preview set that still exceeds the cap is
195
+ # neither bounded nor graceful; keep every original inline in that case.
196
+ if total <= cap:
197
+ result.update(replacements)
198
+
199
+
200
+ async def _on_post_tool_call(
201
+ tool_name: str,
202
+ tool_args: dict,
203
+ result: Any,
204
+ duration_ms: float,
205
+ context: Any = None,
206
+ ) -> None:
207
+ """Spill oversized string fields off the event loop without breaking calls."""
208
+ _ = tool_args, duration_ms, context
209
+ try:
210
+ if not isinstance(result, dict) or set(result) == {"error"}:
211
+ return
212
+ # Capture session attribution before entering the worker. The result
213
+ # reference remains valid and the callback dispatcher awaits us before
214
+ # the model serializes it.
215
+ session_id = store.current_session_id()
216
+ await asyncio.to_thread(_spill_result, tool_name, result, session_id)
217
+ except Exception:
218
+ logger.debug(
219
+ "spill plugin failed; keeping the tool result inline", exc_info=True
220
+ )
221
+
222
+
223
+ def _on_startup() -> None:
224
+ """Move spill behind result-mutating plugins so the final result is capped."""
225
+ if unregister_callback("post_tool_call", _on_post_tool_call):
226
+ # unregister_callback intentionally preserves callback ownership, so
227
+ # disabled-plugin filtering still recognizes this as the spill hook.
228
+ register_callback("post_tool_call", _on_post_tool_call)
229
+
230
+
231
+ register_callback("startup", _on_startup)
232
+
233
+
234
+ def _reset_state() -> None:
235
+ """Reset lazy process storage state for tests and defensive re-init."""
236
+ store._reset_state()
237
+
238
+
239
+ register_callback("post_tool_call", _on_post_tool_call)
240
+
241
+
242
+ __all__ = [
243
+ "DEFAULT_MAX_INLINE_BYTES",
244
+ "DEFAULT_PREVIEW_BYTES",
245
+ "DEFAULT_SKIP_TOOLS",
246
+ "MAX_INLINE_KEY",
247
+ "PREVIEW_KEY",
248
+ "ROOT_KEY",
249
+ "SKIP_TOOLS_KEY",
250
+ "_build_replacement",
251
+ "_get_int",
252
+ "_on_post_tool_call",
253
+ "_on_startup",
254
+ "_reset_state",
255
+ "_spill_result",
256
+ ]
@@ -0,0 +1,173 @@
1
+ """Private local storage for spilled tool-result text."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import os
7
+ import re
8
+ import secrets
9
+ import stat
10
+ import tempfile
11
+ import threading
12
+ import uuid
13
+ from pathlib import Path
14
+
15
+ _default_root: Path | None = None
16
+ _process_session_id: str | None = None
17
+ _state_lock = threading.Lock()
18
+ _UNSAFE_NAME = re.compile(r"[^A-Za-z0-9._-]+")
19
+
20
+
21
+ def private_root(configured_root: str | None = None) -> Path:
22
+ """Return the configured root or a lazy private per-process temp root."""
23
+ global _default_root
24
+ if configured_root:
25
+ root = Path(configured_root).expanduser().resolve()
26
+ root.mkdir(mode=0o700, parents=True, exist_ok=True)
27
+ return root
28
+ with _state_lock:
29
+ if _default_root is None:
30
+ _default_root = Path(tempfile.mkdtemp(prefix="code-puppy-spill-"))
31
+ return _default_root
32
+
33
+
34
+ def _process_fallback_session_id() -> str:
35
+ global _process_session_id
36
+ with _state_lock:
37
+ if _process_session_id is None:
38
+ _process_session_id = uuid.uuid4().hex
39
+ return _process_session_id
40
+
41
+
42
+ def current_session_id() -> str:
43
+ """Return an async-safe session scope, with a stable process fallback."""
44
+ try:
45
+ from code_puppy.tools.subagent_context import get_conversation_root_id
46
+
47
+ conversation_id = get_conversation_root_id()
48
+ if conversation_id:
49
+ return str(conversation_id)
50
+ except Exception:
51
+ pass
52
+
53
+ # MessageBus session state is process-global and can be overwritten by any
54
+ # concurrent agent task. If no async-safe conversation root is available,
55
+ # prefer the honest process fallback over confidently misattributing a spill.
56
+ return _process_fallback_session_id()
57
+
58
+
59
+ def _session_name(session_id: str) -> str:
60
+ digest = hashlib.sha256(session_id.encode("utf-8")).hexdigest()[:12]
61
+ return f"session-{digest}"
62
+
63
+
64
+ def session_dir(root: Path, session_id: str) -> Path:
65
+ """Create a private real directory under ``root``, rejecting symlinks."""
66
+ directory = root / _session_name(session_id)
67
+ directory.mkdir(mode=0o700, parents=True, exist_ok=True)
68
+ metadata = directory.lstat()
69
+ if stat.S_ISLNK(metadata.st_mode) or not stat.S_ISDIR(metadata.st_mode):
70
+ raise OSError(f"Unsafe spill session directory: {directory}")
71
+ if os.chmod in os.supports_follow_symlinks:
72
+ os.chmod(directory, 0o700, follow_symlinks=False)
73
+ else:
74
+ # Platforms without no-follow chmod also lack the directory-fd path
75
+ # below. Re-check immediately before the best available fallback.
76
+ if directory.is_symlink():
77
+ raise OSError(f"Unsafe spill session directory: {directory}")
78
+ os.chmod(directory, 0o700)
79
+ return directory
80
+
81
+
82
+ def _open_session_dir(root: Path, session_id: str) -> tuple[Path, int | None]:
83
+ """Open a session directory without following a pre-planted symlink."""
84
+ supports_safe_open = (
85
+ os.open in os.supports_dir_fd
86
+ and os.mkdir in os.supports_dir_fd
87
+ and hasattr(os, "O_DIRECTORY")
88
+ and hasattr(os, "O_NOFOLLOW")
89
+ and hasattr(os, "fchmod")
90
+ )
91
+ if not supports_safe_open:
92
+ return session_dir(root, session_id), None
93
+
94
+ name = _session_name(session_id)
95
+ root_flags = os.O_RDONLY | os.O_DIRECTORY
96
+ root_fd = os.open(root, root_flags)
97
+ try:
98
+ try:
99
+ os.mkdir(name, 0o700, dir_fd=root_fd)
100
+ except FileExistsError:
101
+ pass
102
+ flags = os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW
103
+ directory_fd = os.open(name, flags, dir_fd=root_fd)
104
+ finally:
105
+ os.close(root_fd)
106
+
107
+ try:
108
+ os.fchmod(directory_fd, 0o700)
109
+ except Exception:
110
+ os.close(directory_fd)
111
+ raise
112
+ return root / name, directory_fd
113
+
114
+
115
+ def safe_filename(tool_name: str) -> str:
116
+ """Convert an untrusted tool name into one harmless filename segment."""
117
+ raw = f"{tool_name}.txt".replace("\x00", "_")
118
+ safe = _UNSAFE_NAME.sub("_", raw.replace("/", "_").replace("\\", "_"))
119
+ while ".." in safe:
120
+ safe = safe.replace("..", "_")
121
+ safe = safe.strip(".")
122
+ return safe or "tool.txt"
123
+
124
+
125
+ def save_text(
126
+ content: str,
127
+ tool_name: str,
128
+ configured_root: str | None = None,
129
+ session_id: str | None = None,
130
+ ) -> Path:
131
+ """Persist ``content`` verbatim with exclusive owner-only creation."""
132
+ root = private_root(configured_root)
133
+ directory, directory_fd = _open_session_dir(
134
+ root, session_id or current_session_id()
135
+ )
136
+ filename = f"{secrets.token_hex(6)}-{safe_filename(tool_name)}"
137
+ path = directory / filename
138
+ flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
139
+ descriptor = -1
140
+ try:
141
+ if directory_fd is None:
142
+ descriptor = os.open(path, flags, 0o600)
143
+ else:
144
+ descriptor = os.open(filename, flags, 0o600, dir_fd=directory_fd)
145
+ if hasattr(os, "fchmod"):
146
+ os.fchmod(descriptor, 0o600)
147
+ with os.fdopen(descriptor, "w", encoding="utf-8", newline="") as spill_file:
148
+ descriptor = -1
149
+ spill_file.write(content)
150
+ finally:
151
+ if descriptor >= 0:
152
+ os.close(descriptor)
153
+ if directory_fd is not None:
154
+ os.close(directory_fd)
155
+ return path
156
+
157
+
158
+ def _reset_state() -> None:
159
+ """Forget lazy process state; test cleanup remains the caller's job."""
160
+ global _default_root, _process_session_id
161
+ with _state_lock:
162
+ _default_root = None
163
+ _process_session_id = None
164
+
165
+
166
+ __all__ = [
167
+ "_reset_state",
168
+ "current_session_id",
169
+ "private_root",
170
+ "safe_filename",
171
+ "save_text",
172
+ "session_dir",
173
+ ]
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "code-puppy-core-plugins"
7
- version = "0.0.4"
7
+ version = "0.0.6"
8
8
  description = "Official plugin bundle for Code Puppy"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11,<3.15"
@@ -69,6 +69,7 @@ puppy_spinner = "code_puppy_core_plugins.puppy_spinner.register_callbacks"
69
69
  quick_resume = "code_puppy_core_plugins.quick_resume.register_callbacks"
70
70
  review_pr = "code_puppy_core_plugins.review_pr.register_callbacks"
71
71
  shell_safety = "code_puppy_core_plugins.shell_safety.register_callbacks"
72
+ spill = "code_puppy_core_plugins.spill.register_callbacks"
72
73
  stack_dump = "code_puppy_core_plugins.stack_dump.register_callbacks"
73
74
  statusline = "code_puppy_core_plugins.statusline.register_callbacks"
74
75
  steer_queue = "code_puppy_core_plugins.steer_queue.register_callbacks"