code-puppy 0.0.596__tar.gz → 0.0.598__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.
- {code_puppy-0.0.596 → code_puppy-0.0.598}/PKG-INFO +1 -1
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/cli_runner.py +9 -24
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/colors_menu.py +0 -2
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/config.py +0 -2
- code_puppy-0.0.598/code_puppy/plugins/herdr/README.md +81 -0
- code_puppy-0.0.598/code_puppy/plugins/herdr/__init__.py +9 -0
- code_puppy-0.0.598/code_puppy/plugins/herdr/client.py +157 -0
- code_puppy-0.0.598/code_puppy/plugins/herdr/register_callbacks.py +116 -0
- code_puppy-0.0.598/code_puppy/plugins/herdr/reporter.py +130 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/picker.py +0 -1
- {code_puppy-0.0.596 → code_puppy-0.0.598}/pyproject.toml +1 -1
- {code_puppy-0.0.596 → code_puppy-0.0.598}/.gitignore +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/LICENSE +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/__main__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_builder.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_compaction.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_diagnostics.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_history.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_key_listeners.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_non_streaming_render.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_run_signals.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_runtime.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/_steer_processor.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/agent_code_puppy.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/agent_creator_agent.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/agent_helios.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/agent_manager.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/agent_planning.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/agent_qa_kitten.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/base_agent.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/event_stream_handler.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/json_agent.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/run_stats.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/smooth_stream.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/agents/subagent_stream_handler.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/chatgpt_codex_client.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/claude_cache_client.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/add_model_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/agent_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/attachments.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/autosave_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/autosave_search.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/clipboard.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/command_handler.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/command_registry.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/config_apply.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/config_commands.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/core_commands.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/diff_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/file_index.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/file_path_completion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/judges_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/load_context_completion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/base.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/catalog_server_installer.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/custom_server_form.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/custom_server_installer.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/edit_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/handler.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/help_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/install_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/install_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/list_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/logs_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/remove_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/restart_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/search_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/silence_warning_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/start_all_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/start_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/status_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/stop_all_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/stop_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp/wizard_utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp_binding_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/mcp_completion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/model_picker_completion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/model_settings_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/onboarding_slides.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/onboarding_wizard.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/pagination.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/pin_command_completion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/prompt_toolkit_completion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/session_commands.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/set_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/set_menu_catalog.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/set_menu_render.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/set_menu_schema.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/set_menu_settings.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/set_menu_shims.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/set_menu_values.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/shell_passthrough.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/skills_completion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/uc_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/command_line/wiggum_state.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/error_logging.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/gemini_code_assist.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/gemini_model.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/aliases.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/engine.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/executor.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/matcher.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/models.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/registry.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/hook_engine/validator.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/http_utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/keymap.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/list_filtering.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/main.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/agent_bindings.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/async_lifecycle.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/blocking_startup.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/captured_stdio_server.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/circuit_breaker.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/config_wizard.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/dashboard.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/error_isolation.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/examples/retry_example.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/health_monitor.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/managed_server.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/manager.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/mcp_logs.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/registry.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/retry_manager.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/server_registry_catalog.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/status_tracker.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/system_tools.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_/tool_arg_coercion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_prompts/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/mcp_prompts/hook_creator.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/bar_painters.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/bar_rendering.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/bottom_bar.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/bus.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/commands.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/editor_actions.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/editor_completion.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/editor_display.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/editor_history.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/editor_keys.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/editor_paste.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/line_editor.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/markdown_patches.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/message_queue.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/messages.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/pause_controller.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/prompt_prefix_style.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/queue_console.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/renderers.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/rich_renderer.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/run_ui.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/run_ui_wiring.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/spinner/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/messaging/subagent_console.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/model_descriptions.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/model_factory.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/model_switching.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/model_utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/models.json +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/models_dev_api.json +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/models_dev_parser.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/discovery.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/downloader.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/enabled_skills.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/installer.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/metadata.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/prompt_builder.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/remote_catalog.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/skill_catalog.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/skill_commands.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/skills_install_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/agent_skills/skills_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/aws_bedrock/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/aws_bedrock/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/aws_bedrock/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/aws_bedrock/utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/azure_foundry/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/azure_foundry/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/azure_foundry/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/azure_foundry/discovery.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/azure_foundry/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/azure_foundry/token.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/azure_foundry/utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/btw/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/btw/inline_view.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/btw/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/btw/side_query.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/chatgpt_oauth/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/chatgpt_oauth/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/chatgpt_oauth/oauth_flow.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/chatgpt_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/chatgpt_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/chatgpt_oauth/utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_hooks/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_hooks/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_hooks/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/SETUP.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/fast_mode.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/prompt_handler.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/test_fast_mode.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/test_plugin.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/token_refresh_heartbeat.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/claude_code_oauth/utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/code_puppy_agent/SKILL.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/code_puppy_agent/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/code_puppy_agent/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/context_indicator/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/context_indicator/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/context_indicator/usage.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/copilot_auth/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/copilot_auth/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/copilot_auth/reasoning_client.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/copilot_auth/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/copilot_auth/utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/customizable_commands/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/customizable_commands/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/cancel.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/commands.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/lifecycle.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/runtime.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/startup_lock.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/workflow_ids.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/dbos_durable_exec/wrapper.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/destructive_command_guard/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/destructive_command_guard/detector.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/destructive_command_guard/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/emoji_filter/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/emoji_filter/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/emoji_filter/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/emoji_filter/stripper.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/example_custom_command/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/example_custom_command/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/file_permission_handler/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/file_permission_handler/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/force_push_guard/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/force_push_guard/detector.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/force_push_guard/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/force_push_guard/test_detector.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/frontend_emitter/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/frontend_emitter/emitter.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/frontend_emitter/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/frontend_emitter/session_context.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/hook_creator/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/hook_creator/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/hook_manager/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/hook_manager/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/hook_manager/hooks_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/hook_manager/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/oauth_puppy_html.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/obsidian_agent/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/obsidian_agent/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/obsidian_agent/agent_obsidian.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/obsidian_agent/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/ollama/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/ollama/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/ollama_setup/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/ollama_setup/completer.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/ollama_setup/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/plugin_list/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/plugin_list/plugin_contributions.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/plugin_list/plugin_meta.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/plugin_list/plugin_text_utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/plugin_list/plugins_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/plugin_list/plugins_menu_render.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/plugin_list/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/pop_command/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/pop_command/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/prompt_newline/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/prompt_newline/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/prompt_newline/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/prune/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/prune/prune_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/prune/prune_model.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/prune/prune_render.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/prune/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/commands.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/kennel.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/packer.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/recorder.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/retriever.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/schema.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/state.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/tools.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_kennel/wings.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_spinner/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/puppy_spinner/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/quick_resume/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/quick_resume/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/review_pr/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/review_pr/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/shell_safety/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/shell_safety/agent_shell_safety.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/shell_safety/command_cache.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/shell_safety/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/statusline/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/statusline/config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/statusline/payload.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/statusline/prompt_patch.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/statusline/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/statusline/runner.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/statusline/statusline_command.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/steer_queue/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/steer_queue/queue_menu.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/steer_queue/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/subagent_panel/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/subagent_panel/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/subagent_panel/coalesce_patch.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/subagent_panel/panel_render.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/subagent_panel/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/subagent_panel/resume_repaint.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/subagent_panel/state.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/switch_agent_resume/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/switch_agent_resume/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/README.md +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/bundled_palettes.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/content_styles.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/osc_palette.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/rich_themes.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/theme/themes.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/token_ratio_learner/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/token_ratio_learner/ratios.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/token_ratio_learner/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/universal_constructor/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/universal_constructor/models.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/universal_constructor/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/universal_constructor/registry.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/universal_constructor/sandbox.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/wide_completion_menu/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/wide_completion_menu/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/wiggum/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/wiggum/judge.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/wiggum/judge_config.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/wiggum/register_callbacks.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/plugins/wiggum/state.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/provider_credentials.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/provider_identity.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/pydantic_patches.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/reopenable_async_client.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/round_robin_model.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/session_lifecycle.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/session_migration.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/session_storage.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/status_display.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/summarization_agent.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/terminal_utils.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/agent_tools.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/constants.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/demo_tui.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/handler.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/models.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/registration.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/renderers.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/terminal_ui.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/theme.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/ask_user_question/tui_loop.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/__init__.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_control.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_interactions.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_locator_resolver.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_locators.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_manager.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_navigation.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_page_snapshot.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_screenshot.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_scripts.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_semantic_interactions.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/browser/browser_workflows.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/command_runner.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/common.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/display.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/file_modifications.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/file_operations.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/image_tools.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/model_tools.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/skills_tools.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/subagent_context.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/subagent_invocation.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/tools_content.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/tools/universal_constructor.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/undo_manager.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/uvx_detection.py +0 -0
- {code_puppy-0.0.596 → code_puppy-0.0.598}/code_puppy/version_checker.py +0 -0
|
@@ -625,26 +625,6 @@ def _persistent_prompt_parts() -> tuple:
|
|
|
625
625
|
return ">>> ", []
|
|
626
626
|
|
|
627
627
|
|
|
628
|
-
def _user_prompt_echo(task: str):
|
|
629
|
-
"""Transcript echo for a submitted prompt, banner-tagged.
|
|
630
|
-
|
|
631
|
-
The persistent editor clears its row on submit, so scrollback needs
|
|
632
|
-
a record of what was asked. A bare ``> `` marker looked like an
|
|
633
|
-
orphaned prompt row (especially on Windows); tag it like every other
|
|
634
|
-
transcript block (AGENT RESPONSE, SHELL COMMAND, ...) instead.
|
|
635
|
-
Built with ``Text`` (not markup) so bracket-y input renders as-is.
|
|
636
|
-
"""
|
|
637
|
-
from rich.text import Text
|
|
638
|
-
|
|
639
|
-
from code_puppy.config import get_banner_color
|
|
640
|
-
|
|
641
|
-
color = get_banner_color("user_prompt")
|
|
642
|
-
echo = Text("\n")
|
|
643
|
-
echo.append(" USER ", style=f"bold white on {color}")
|
|
644
|
-
echo.append(f" {task}", style="bold")
|
|
645
|
-
return echo
|
|
646
|
-
|
|
647
|
-
|
|
648
628
|
def _interactive_sigint_guard(_sig, _frame):
|
|
649
629
|
"""Baseline SIGINT handler for the interactive REPL.
|
|
650
630
|
|
|
@@ -877,6 +857,8 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
877
857
|
|
|
878
858
|
try:
|
|
879
859
|
if persistent_prompt:
|
|
860
|
+
from rich.text import Text as _EchoText
|
|
861
|
+
|
|
880
862
|
from code_puppy.messaging.run_ui import (
|
|
881
863
|
set_idle_prompt_prefix,
|
|
882
864
|
wait_for_idle_submission,
|
|
@@ -896,16 +878,19 @@ async def interactive_mode(message_renderer, initial_command: str = None) -> Non
|
|
|
896
878
|
queued_task = _get_pc().pop_next_steer_queued()
|
|
897
879
|
if queued_task is not None:
|
|
898
880
|
task = queued_task
|
|
899
|
-
emit_info(
|
|
881
|
+
emit_info(_EchoText(f"\n> {task}", style="bold"))
|
|
900
882
|
emit_info("⏭ running queued prompt")
|
|
901
883
|
else:
|
|
902
884
|
# Raises EOFError on Ctrl+D-with-empty-buffer, which the
|
|
903
885
|
# existing quit branch below handles.
|
|
904
886
|
task = await wait_for_idle_submission()
|
|
905
|
-
# Echo into the transcript
|
|
887
|
+
# Echo into the transcript: the editor clears its row
|
|
888
|
+
# on submit, so scrollback needs the record of what was
|
|
889
|
+
# asked. JUST the user's text (bold, '> ' marker) --
|
|
906
890
|
# repeating the whole prompt chrome doubled every
|
|
907
|
-
# line's noise
|
|
908
|
-
|
|
891
|
+
# line's noise. Text() (not markup) so bracket-y input
|
|
892
|
+
# renders as-is.
|
|
893
|
+
emit_info(_EchoText(f"\n> {task}", style="bold"))
|
|
909
894
|
else:
|
|
910
895
|
# Use prompt_toolkit for enhanced input with path completion
|
|
911
896
|
try:
|
|
@@ -38,7 +38,6 @@ BANNER_DISPLAY_INFO = {
|
|
|
38
38
|
"universal_constructor": ("UNIVERSAL CONSTRUCTOR", "🔧"),
|
|
39
39
|
"terminal_tool": ("TERMINAL TOOL", "🖥️"),
|
|
40
40
|
"llm_judge": ("LLM JUDGE", "⚖️"),
|
|
41
|
-
"user_prompt": ("USER", "🧑"),
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
# Sample content to show after each banner
|
|
@@ -60,7 +59,6 @@ BANNER_SAMPLE_CONTENT = {
|
|
|
60
59
|
"universal_constructor": "action=create tool_name=api.weather\n✅ Created successfully",
|
|
61
60
|
"terminal_tool": "$ chromium --headless\nBrowser terminal session started",
|
|
62
61
|
"llm_judge": "🎯 Verdict: Complete ✅\nGoal verified — all tests pass.",
|
|
63
|
-
"user_prompt": "Fix the flaky test in tests/test_api.py",
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
# Available background colors grouped by theme
|
|
@@ -1701,8 +1701,6 @@ DEFAULT_BANNER_COLORS = {
|
|
|
1701
1701
|
"shell_passthrough": "medium_sea_green", # Green - user's own shell commands
|
|
1702
1702
|
# LLM Judge - goal-mode verdict (distinct from agent reasoning)
|
|
1703
1703
|
"llm_judge": "gold3", # Gold - judicial authority / gavel
|
|
1704
|
-
# Transcript echo of the user's submitted prompt (persistent prompt path)
|
|
1705
|
-
"user_prompt": "dark_green", # Green - the human speaks
|
|
1706
1704
|
}
|
|
1707
1705
|
|
|
1708
1706
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# herdr integration
|
|
2
|
+
|
|
3
|
+
Makes code-puppy a first-class citizen in
|
|
4
|
+
[**herdr**](https://herdr.dev), a terminal workspace manager for coding
|
|
5
|
+
agents. When you run several agents at once, herdr's sidebar rolls each
|
|
6
|
+
one up to a single glanceable state -- who's **working**, who's
|
|
7
|
+
**blocked** waiting on you, and who's **done** -- so you always know
|
|
8
|
+
which pane needs attention.
|
|
9
|
+
|
|
10
|
+
This plugin teaches code-puppy to report that state authoritatively.
|
|
11
|
+
|
|
12
|
+
## What it does
|
|
13
|
+
|
|
14
|
+
herdr injects three environment variables into every pane it owns:
|
|
15
|
+
|
|
16
|
+
| variable | meaning |
|
|
17
|
+
| ------------------- | ----------------------------------------- |
|
|
18
|
+
| `HERDR_ENV=1` | this shell is running inside a herdr pane |
|
|
19
|
+
| `HERDR_SOCKET_PATH` | herdr's local control socket |
|
|
20
|
+
| `HERDR_PANE_ID` | the pane this process owns (e.g. `w1:p1`) |
|
|
21
|
+
|
|
22
|
+
On startup the plugin checks for those. If they're absent it does
|
|
23
|
+
**nothing** -- zero overhead, zero output, no behaviour change. If
|
|
24
|
+
they're present it opens a background reporter that maps code-puppy's
|
|
25
|
+
lifecycle callbacks onto herdr's three semantic states:
|
|
26
|
+
|
|
27
|
+
| code-puppy event | herdr state |
|
|
28
|
+
| ----------------------------------------------- | ----------- |
|
|
29
|
+
| `agent_run_start`, `user_prompt_submit` | `working` |
|
|
30
|
+
| `pre_tool_call` (most tools), `post_tool_call` | `working` |
|
|
31
|
+
| `ask_user_question`, file-permission prompts | `blocked` |
|
|
32
|
+
| `interactive_turn_end`, `agent_run_cancel` | `idle` |
|
|
33
|
+
| `startup`, `session_end`, `shutdown` | `idle` |
|
|
34
|
+
|
|
35
|
+
Sub-agent runs fire the same start/end hooks as the root run, so the
|
|
36
|
+
reporter refcounts active runs and only falls `idle` when the whole turn
|
|
37
|
+
hands control back to you (mirroring the `puppy_spinner` plugin).
|
|
38
|
+
|
|
39
|
+
## No install needed on the herdr side
|
|
40
|
+
|
|
41
|
+
Because this plugin ships with code-puppy and self-activates inside a
|
|
42
|
+
pane, there is nothing to run -- `herdr integration install` is **not**
|
|
43
|
+
required for code-puppy. Just start code-puppy inside herdr:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
herdr # start / attach herdr
|
|
47
|
+
code-puppy # (or: pup) -- herdr picks up its state automatically
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
herdr also recognises the `code-puppy` / `pup` process on its own and
|
|
51
|
+
reads the on-screen approval prompts, so even with this plugin disabled
|
|
52
|
+
you still get detection. The plugin upgrades that from screen-scraped
|
|
53
|
+
guessing to authoritative, event-driven state.
|
|
54
|
+
|
|
55
|
+
## Blocked detection is shared with herdr
|
|
56
|
+
|
|
57
|
+
Not every interactive prompt in code-puppy flows through a callback
|
|
58
|
+
(shell-command approval, for instance, prompts from inside the tool).
|
|
59
|
+
The plugin reports the prompts it *can* see, and herdr's screen manifest
|
|
60
|
+
independently detects any visible approval UI and overrides a stale
|
|
61
|
+
`working` -- which is exactly why this plugin does **not** claim herdr
|
|
62
|
+
"full lifecycle authority". Belt and suspenders.
|
|
63
|
+
|
|
64
|
+
## Design notes
|
|
65
|
+
|
|
66
|
+
* **Never disturbs the agent.** All socket I/O happens on a daemon
|
|
67
|
+
worker thread; the sync file-permission hot-path just enqueues and
|
|
68
|
+
returns. The permission observer always returns `None`, so it can
|
|
69
|
+
never accidentally veto a file operation.
|
|
70
|
+
* **Edge-triggered + deduped.** Only state *changes* hit the socket.
|
|
71
|
+
* **Fail-soft.** A missing/closed socket, a departed herdr, a full
|
|
72
|
+
queue -- all are swallowed to the debug log. Reporting your state is
|
|
73
|
+
never worth crashing your agent over.
|
|
74
|
+
|
|
75
|
+
## Files
|
|
76
|
+
|
|
77
|
+
| file | responsibility |
|
|
78
|
+
| ----------------------- | ------------------------------------------- |
|
|
79
|
+
| `client.py` | herdr socket transport (JSON, worker thread)|
|
|
80
|
+
| `reporter.py` | event -> state machine (refcount + dedup) |
|
|
81
|
+
| `register_callbacks.py` | callback wiring + env activation guard |
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""herdr integration plugin for code-puppy.
|
|
2
|
+
|
|
3
|
+
Reports semantic agent state (working / blocked / idle) to a herdr pane
|
|
4
|
+
over herdr's local socket. Inert unless running inside herdr.
|
|
5
|
+
|
|
6
|
+
See ``register_callbacks.py`` for the wiring and ``README.md`` for docs.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
__all__: list[str] = []
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""Fire-and-forget client for the herdr pane socket.
|
|
2
|
+
|
|
3
|
+
herdr (https://herdr.dev) is a terminal workspace manager for coding
|
|
4
|
+
agents. When code-puppy runs inside a herdr pane, herdr injects three
|
|
5
|
+
environment variables:
|
|
6
|
+
|
|
7
|
+
* ``HERDR_ENV=1`` -- marks the pane as herdr-managed
|
|
8
|
+
* ``HERDR_SOCKET_PATH`` -- path to herdr's local control socket
|
|
9
|
+
* ``HERDR_PANE_ID`` -- the pane this process owns (e.g. ``w1:p1``)
|
|
10
|
+
|
|
11
|
+
This module speaks herdr's newline-delimited JSON socket protocol just
|
|
12
|
+
far enough to call ``pane.report_agent`` / ``pane.report_agent_session``.
|
|
13
|
+
It never reads a reply and never raises into the caller: reporting agent
|
|
14
|
+
state must never be able to disturb the agent itself. Delivery happens on
|
|
15
|
+
a single daemon worker thread so the (sync) permission hot-path and the
|
|
16
|
+
async run loop both enqueue in O(1) and move on.
|
|
17
|
+
|
|
18
|
+
Windows named-pipe transport is intentionally out of scope; herdr's
|
|
19
|
+
Windows build is beta and ``AF_UNIX`` is the contract everywhere else.
|
|
20
|
+
When the socket is unavailable the client is simply inactive.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import json
|
|
26
|
+
import logging
|
|
27
|
+
import os
|
|
28
|
+
import queue
|
|
29
|
+
import socket
|
|
30
|
+
import threading
|
|
31
|
+
import time
|
|
32
|
+
from typing import Any, Dict, Optional
|
|
33
|
+
|
|
34
|
+
logger = logging.getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
#: source tag herdr attributes these reports to. The ``herdr:`` prefix is
|
|
37
|
+
#: the convention herdr uses for its own official integrations.
|
|
38
|
+
SOURCE = "herdr:codepuppy"
|
|
39
|
+
#: agent label; must match herdr's ``agent_label(Agent::CodePuppy)``.
|
|
40
|
+
AGENT = "codepuppy"
|
|
41
|
+
|
|
42
|
+
_CONNECT_TIMEOUT_S = 0.5
|
|
43
|
+
_QUEUE_MAX = 256
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class HerdrClient:
|
|
47
|
+
"""Enqueues agent-state reports and drains them on a worker thread."""
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
socket_path: Optional[str] = None,
|
|
52
|
+
pane_id: Optional[str] = None,
|
|
53
|
+
) -> None:
|
|
54
|
+
self._socket_path = socket_path or os.environ.get("HERDR_SOCKET_PATH")
|
|
55
|
+
self._pane_id = pane_id or os.environ.get("HERDR_PANE_ID")
|
|
56
|
+
self._active = bool(
|
|
57
|
+
os.environ.get("HERDR_ENV") == "1"
|
|
58
|
+
and self._socket_path
|
|
59
|
+
and self._pane_id
|
|
60
|
+
and hasattr(socket, "AF_UNIX")
|
|
61
|
+
)
|
|
62
|
+
self._queue: "queue.Queue[Optional[Dict[str, Any]]]" = queue.Queue(
|
|
63
|
+
maxsize=_QUEUE_MAX
|
|
64
|
+
)
|
|
65
|
+
self._seq_lock = threading.Lock()
|
|
66
|
+
# Monotonic, process-unique sequence. herdr uses seq to discard
|
|
67
|
+
# out-of-order reports, so it must only ever increase.
|
|
68
|
+
self._seq = int(time.time() * 1000) * 1000
|
|
69
|
+
self._worker: Optional[threading.Thread] = None
|
|
70
|
+
if self._active:
|
|
71
|
+
self._start_worker()
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def active(self) -> bool:
|
|
75
|
+
return self._active
|
|
76
|
+
|
|
77
|
+
def _start_worker(self) -> None:
|
|
78
|
+
self._worker = threading.Thread(
|
|
79
|
+
target=self._run,
|
|
80
|
+
name="herdr-reporter",
|
|
81
|
+
daemon=True,
|
|
82
|
+
)
|
|
83
|
+
self._worker.start()
|
|
84
|
+
|
|
85
|
+
def _next_seq(self) -> int:
|
|
86
|
+
with self._seq_lock:
|
|
87
|
+
self._seq += 1
|
|
88
|
+
return self._seq
|
|
89
|
+
|
|
90
|
+
def _enqueue(self, method: str, params: Dict[str, Any]) -> None:
|
|
91
|
+
if not self._active:
|
|
92
|
+
return
|
|
93
|
+
envelope = {
|
|
94
|
+
"id": f"{SOURCE}:{self._next_seq()}",
|
|
95
|
+
"method": method,
|
|
96
|
+
"params": {
|
|
97
|
+
"pane_id": self._pane_id,
|
|
98
|
+
"source": SOURCE,
|
|
99
|
+
"agent": AGENT,
|
|
100
|
+
"seq": self._next_seq(),
|
|
101
|
+
**params,
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
try:
|
|
105
|
+
self._queue.put_nowait(envelope)
|
|
106
|
+
except queue.Full:
|
|
107
|
+
# State is edge-triggered and deduped upstream; dropping a
|
|
108
|
+
# report under extreme backpressure is harmless (herdr keeps
|
|
109
|
+
# the last state it saw).
|
|
110
|
+
logger.debug("herdr report queue full; dropping report")
|
|
111
|
+
|
|
112
|
+
def report_state(self, state: str, agent_session_id: Optional[str] = None) -> None:
|
|
113
|
+
"""Report a semantic state: ``working`` / ``blocked`` / ``idle``."""
|
|
114
|
+
params: Dict[str, Any] = {"state": state}
|
|
115
|
+
if agent_session_id:
|
|
116
|
+
params["agent_session_id"] = agent_session_id
|
|
117
|
+
self._enqueue("pane.report_agent", params)
|
|
118
|
+
|
|
119
|
+
def report_session(self, agent_session_id: str) -> None:
|
|
120
|
+
"""Report native session identity so herdr can restore context."""
|
|
121
|
+
if not agent_session_id:
|
|
122
|
+
return
|
|
123
|
+
self._enqueue(
|
|
124
|
+
"pane.report_agent_session",
|
|
125
|
+
{"agent_session_id": agent_session_id},
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
def close(self) -> None:
|
|
129
|
+
"""Signal the worker to drain and stop. Best-effort, non-blocking."""
|
|
130
|
+
if not self._active:
|
|
131
|
+
return
|
|
132
|
+
try:
|
|
133
|
+
self._queue.put_nowait(None)
|
|
134
|
+
except queue.Full:
|
|
135
|
+
pass
|
|
136
|
+
|
|
137
|
+
def _run(self) -> None:
|
|
138
|
+
while True:
|
|
139
|
+
envelope = self._queue.get()
|
|
140
|
+
if envelope is None:
|
|
141
|
+
return
|
|
142
|
+
self._send(envelope)
|
|
143
|
+
|
|
144
|
+
def _send(self, envelope: Dict[str, Any]) -> None:
|
|
145
|
+
try:
|
|
146
|
+
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
|
|
147
|
+
sock.settimeout(_CONNECT_TIMEOUT_S)
|
|
148
|
+
sock.connect(self._socket_path) # type: ignore[arg-type]
|
|
149
|
+
payload = (json.dumps(envelope) + "\n").encode("utf-8")
|
|
150
|
+
sock.sendall(payload)
|
|
151
|
+
except (OSError, ValueError) as exc:
|
|
152
|
+
# herdr may have exited, or the pane was closed. Neither is
|
|
153
|
+
# our problem to solve; stay quiet on the diagnostic channel.
|
|
154
|
+
logger.debug("herdr report failed: %s", exc)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
__all__ = ["HerdrClient", "SOURCE", "AGENT"]
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""herdr integration -- report code-puppy's state to a herdr pane.
|
|
2
|
+
|
|
3
|
+
This built-in plugin is a no-op unless code-puppy is running inside a
|
|
4
|
+
`herdr <https://herdr.dev>`_ pane (detected via the ``HERDR_ENV`` /
|
|
5
|
+
``HERDR_SOCKET_PATH`` / ``HERDR_PANE_ID`` environment variables herdr
|
|
6
|
+
injects). When it is, it reports semantic agent state -- ``working`` /
|
|
7
|
+
``blocked`` / ``idle`` -- over herdr's local socket so herdr's sidebar
|
|
8
|
+
can roll code-puppy up alongside every other agent in the fleet.
|
|
9
|
+
|
|
10
|
+
Because the integration ships with code-puppy and self-activates, there
|
|
11
|
+
is nothing to install on the herdr side: ``herdr integration install``
|
|
12
|
+
is not needed for code-puppy.
|
|
13
|
+
|
|
14
|
+
Callback -> state mapping (see reporter.py for the arbitration rules):
|
|
15
|
+
|
|
16
|
+
* ``startup`` / ``session_end`` / ``shutdown`` .......... idle
|
|
17
|
+
* ``user_prompt_submit`` / ``agent_run_start`` ......... working
|
|
18
|
+
* ``pre_tool_call`` (non-ask) / ``post_tool_call`` ..... working
|
|
19
|
+
* ``pre_tool_call`` (ask_user_question) / permission ... blocked
|
|
20
|
+
* ``interactive_turn_end`` / ``interactive_turn_cancel`` idle
|
|
21
|
+
* ``agent_run_cancel`` ................................. idle
|
|
22
|
+
* ``agent_run_end`` ................................... idle (depth 0)
|
|
23
|
+
|
|
24
|
+
Handlers are plain sync functions that swallow every argument: the
|
|
25
|
+
callback dispatcher passes hook args positionally and runs sync
|
|
26
|
+
callbacks happily from both async and worker-thread contexts, so
|
|
27
|
+
signature-proofing with ``*args`` is the robust choice.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from __future__ import annotations
|
|
31
|
+
|
|
32
|
+
import logging
|
|
33
|
+
|
|
34
|
+
from code_puppy.callbacks import register_callback
|
|
35
|
+
|
|
36
|
+
from .client import HerdrClient
|
|
37
|
+
from .reporter import HerdrReporter
|
|
38
|
+
|
|
39
|
+
logger = logging.getLogger(__name__)
|
|
40
|
+
|
|
41
|
+
_client = HerdrClient()
|
|
42
|
+
_reporter = HerdrReporter(_client)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _arg(args: tuple, index: int):
|
|
46
|
+
return args[index] if len(args) > index else None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _on_startup(*_args, **_kw) -> None:
|
|
50
|
+
_reporter.on_startup()
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _on_user_prompt(*args, **_kw) -> None:
|
|
54
|
+
# (prompt, session_id=None)
|
|
55
|
+
_reporter.on_user_prompt(_arg(args, 1))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _on_run_start(*args, **_kw) -> None:
|
|
59
|
+
# (agent_name, model_name, session_id=None)
|
|
60
|
+
_reporter.on_run_start(_arg(args, 2))
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _on_run_end(*args, **_kw) -> None:
|
|
64
|
+
# (agent_name, model_name, session_id=None, ...)
|
|
65
|
+
_reporter.on_run_end(_arg(args, 2))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _on_run_cancel(*_args, **_kw) -> None:
|
|
69
|
+
_reporter.on_run_cancel()
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _on_turn_end(*_args, **_kw) -> None:
|
|
73
|
+
_reporter.on_turn_end()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _on_pre_tool_call(*args, **_kw) -> None:
|
|
77
|
+
# (tool_name, tool_args, context=None)
|
|
78
|
+
tool_name = _arg(args, 0) or ""
|
|
79
|
+
_reporter.on_tool_call(str(tool_name))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _on_post_tool_call(*_args, **_kw) -> None:
|
|
83
|
+
_reporter.on_tool_done()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _on_file_permission(*_args, **_kw):
|
|
87
|
+
# SYNC callback. code-puppy treats every non-None result as a
|
|
88
|
+
# grant/deny vote (``any(not r for r in results if r is not None)``),
|
|
89
|
+
# so we MUST return None -- we only observe, never veto.
|
|
90
|
+
_reporter.on_permission_prompt()
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _on_shutdown(*_args, **_kw) -> None:
|
|
95
|
+
_reporter.on_shutdown()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
if _reporter.active:
|
|
99
|
+
register_callback("startup", _on_startup)
|
|
100
|
+
register_callback("user_prompt_submit", _on_user_prompt)
|
|
101
|
+
register_callback("agent_run_start", _on_run_start)
|
|
102
|
+
register_callback("agent_run_end", _on_run_end)
|
|
103
|
+
register_callback("agent_run_cancel", _on_run_cancel)
|
|
104
|
+
register_callback("interactive_turn_end", _on_turn_end)
|
|
105
|
+
register_callback("interactive_turn_cancel", _on_turn_end)
|
|
106
|
+
register_callback("pre_tool_call", _on_pre_tool_call)
|
|
107
|
+
register_callback("post_tool_call", _on_post_tool_call)
|
|
108
|
+
register_callback("file_permission", _on_file_permission)
|
|
109
|
+
register_callback("session_end", _on_shutdown)
|
|
110
|
+
register_callback("shutdown", _on_shutdown)
|
|
111
|
+
logger.debug("herdr plugin active for pane %s", _client._pane_id)
|
|
112
|
+
else:
|
|
113
|
+
logger.debug("herdr plugin inactive (not running inside a herdr pane)")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
__all__ = ["HerdrClient", "HerdrReporter"]
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"""Map code-puppy lifecycle events onto herdr's three semantic states.
|
|
2
|
+
|
|
3
|
+
herdr models every agent as ``working`` / ``blocked`` / ``idle``. This
|
|
4
|
+
reporter is the single writer of that state for the pane, so it keeps the
|
|
5
|
+
edge-triggering and arbitration rules in one place:
|
|
6
|
+
|
|
7
|
+
* **working** -- a top-level run or a tool call is in flight.
|
|
8
|
+
* **blocked** -- code-puppy is waiting on the human (permission prompt,
|
|
9
|
+
``ask_user_question``). This is best-effort: not every interactive
|
|
10
|
+
prompt routes through a callback (shell-command approval does not), so
|
|
11
|
+
herdr's screen manifest remains the authority that can override a stale
|
|
12
|
+
``working`` when a prompt is visible. We deliberately do **not** claim
|
|
13
|
+
herdr full-lifecycle authority for exactly this reason.
|
|
14
|
+
* **idle** -- the turn handed control back to the human.
|
|
15
|
+
|
|
16
|
+
Sub-agents fire the same ``agent_run_start`` / ``agent_run_end`` hooks as
|
|
17
|
+
the root agent, so a naive "end == idle" mapping would flip the pane idle
|
|
18
|
+
while the root run is still going. We refcount active runs (the same
|
|
19
|
+
pattern the puppy_spinner plugin uses) and only trust the interactive
|
|
20
|
+
turn boundary for idle.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import logging
|
|
26
|
+
import threading
|
|
27
|
+
from typing import Optional
|
|
28
|
+
|
|
29
|
+
from .client import HerdrClient
|
|
30
|
+
|
|
31
|
+
logger = logging.getLogger(__name__)
|
|
32
|
+
|
|
33
|
+
WORKING = "working"
|
|
34
|
+
BLOCKED = "blocked"
|
|
35
|
+
IDLE = "idle"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class HerdrReporter:
|
|
39
|
+
"""Thread-safe, dedup-ing bridge from callbacks to :class:`HerdrClient`."""
|
|
40
|
+
|
|
41
|
+
def __init__(self, client: HerdrClient) -> None:
|
|
42
|
+
self._client = client
|
|
43
|
+
self._lock = threading.Lock()
|
|
44
|
+
self._run_depth = 0
|
|
45
|
+
self._last_state: Optional[str] = None
|
|
46
|
+
self._session_id: Optional[str] = None
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def active(self) -> bool:
|
|
50
|
+
return self._client.active
|
|
51
|
+
|
|
52
|
+
# -- state emission -------------------------------------------------
|
|
53
|
+
|
|
54
|
+
def _emit(self, state: str) -> None:
|
|
55
|
+
"""Send *state* only when it changes (edge-triggered)."""
|
|
56
|
+
with self._lock:
|
|
57
|
+
if state == self._last_state:
|
|
58
|
+
return
|
|
59
|
+
self._last_state = state
|
|
60
|
+
session_id = self._session_id
|
|
61
|
+
self._client.report_state(state, session_id)
|
|
62
|
+
|
|
63
|
+
def _remember_session(self, session_id: Optional[str]) -> None:
|
|
64
|
+
if not session_id:
|
|
65
|
+
return
|
|
66
|
+
with self._lock:
|
|
67
|
+
new = session_id != self._session_id
|
|
68
|
+
self._session_id = session_id
|
|
69
|
+
if new:
|
|
70
|
+
self._client.report_session(session_id)
|
|
71
|
+
|
|
72
|
+
# -- lifecycle handlers (all sync; safe from async or worker threads) --
|
|
73
|
+
|
|
74
|
+
def on_startup(self) -> None:
|
|
75
|
+
self._emit(IDLE)
|
|
76
|
+
|
|
77
|
+
def on_user_prompt(self, session_id: Optional[str] = None) -> None:
|
|
78
|
+
self._remember_session(session_id)
|
|
79
|
+
self._emit(WORKING)
|
|
80
|
+
|
|
81
|
+
def on_run_start(self, session_id: Optional[str] = None) -> None:
|
|
82
|
+
self._remember_session(session_id)
|
|
83
|
+
with self._lock:
|
|
84
|
+
self._run_depth += 1
|
|
85
|
+
self._emit(WORKING)
|
|
86
|
+
|
|
87
|
+
def on_run_end(self, session_id: Optional[str] = None) -> None:
|
|
88
|
+
self._remember_session(session_id)
|
|
89
|
+
with self._lock:
|
|
90
|
+
self._run_depth = max(0, self._run_depth - 1)
|
|
91
|
+
depth = self._run_depth
|
|
92
|
+
# Only the outermost run finishing means the model stopped. The
|
|
93
|
+
# interactive turn boundary is the true idle signal, but headless
|
|
94
|
+
# (`-p`) runs never fire it, so falling idle at depth 0 keeps
|
|
95
|
+
# non-interactive panes honest too.
|
|
96
|
+
if depth == 0:
|
|
97
|
+
self._emit(IDLE)
|
|
98
|
+
|
|
99
|
+
def on_run_cancel(self) -> None:
|
|
100
|
+
with self._lock:
|
|
101
|
+
self._run_depth = 0
|
|
102
|
+
self._emit(IDLE)
|
|
103
|
+
|
|
104
|
+
def on_turn_end(self) -> None:
|
|
105
|
+
with self._lock:
|
|
106
|
+
self._run_depth = 0
|
|
107
|
+
self._emit(IDLE)
|
|
108
|
+
|
|
109
|
+
def on_tool_call(self, tool_name: str) -> None:
|
|
110
|
+
# ask_user_question parks the agent on the human -> blocked.
|
|
111
|
+
# Everything else is active work.
|
|
112
|
+
if tool_name == "ask_user_question":
|
|
113
|
+
self._emit(BLOCKED)
|
|
114
|
+
else:
|
|
115
|
+
self._emit(WORKING)
|
|
116
|
+
|
|
117
|
+
def on_tool_done(self) -> None:
|
|
118
|
+
# A tool completing means we are moving again (this is also what
|
|
119
|
+
# clears a blocked ask_user_question / a resolved file prompt).
|
|
120
|
+
self._emit(WORKING)
|
|
121
|
+
|
|
122
|
+
def on_permission_prompt(self) -> None:
|
|
123
|
+
self._emit(BLOCKED)
|
|
124
|
+
|
|
125
|
+
def on_shutdown(self) -> None:
|
|
126
|
+
self._emit(IDLE)
|
|
127
|
+
self._client.close()
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
__all__ = ["HerdrReporter", "WORKING", "BLOCKED", "IDLE"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|