ha-mcp-dev 7.6.0.dev640__tar.gz → 7.6.0.dev641__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.
- {ha_mcp_dev-7.6.0.dev640/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.6.0.dev641}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/pyproject.toml +1 -1
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_bug_report.py +8 -2
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/usage_logger.py +71 -1
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/setup.cfg +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/settings.css +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/settings.js +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/settings_ui.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/best_practice_checker.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_base.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_config.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/validation_middleware.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/skill_loader.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/tests/test_env_manager.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "ha-mcp-dev"
|
|
7
|
-
version = "7.6.0.
|
|
7
|
+
version = "7.6.0.dev641"
|
|
8
8
|
description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13,<3.14"
|
|
@@ -508,7 +508,8 @@ class BugReportTools:
|
|
|
508
508
|
**OUTPUT:**
|
|
509
509
|
Returns both templates plus diagnostic data. Key fields:
|
|
510
510
|
- `runtime_bug_template`, `agent_behavior_template` — pick based on context
|
|
511
|
-
- `recent_logs
|
|
511
|
+
- `recent_logs` — recent ha-mcp tool calls (secret parameters redacted);
|
|
512
|
+
startup log entries are summarised in `formatted_report`, not returned raw
|
|
512
513
|
- `addon_logs` — addon container stdout/stderr (HA add-on installs only;
|
|
513
514
|
empty string otherwise)
|
|
514
515
|
- `suggested_title`, `duplicate_check_urls`, `anonymization_guide`
|
|
@@ -622,8 +623,13 @@ class BugReportTools:
|
|
|
622
623
|
return {
|
|
623
624
|
"success": True,
|
|
624
625
|
"diagnostic_info": diagnostic_info,
|
|
626
|
+
# ``recent_logs`` entries are redacted at the logging chokepoint
|
|
627
|
+
# (UsageLogger.log_tool_usage), so the tool parameters here carry no
|
|
628
|
+
# secrets. ``startup_logs`` come from a separate StartupLogCollector
|
|
629
|
+
# that is NOT redacted at source, so the raw entries are
|
|
630
|
+
# intentionally omitted — the sanitized view lives in
|
|
631
|
+
# ``formatted_report`` (via ``_format_startup_logs``).
|
|
625
632
|
"recent_logs": recent_logs,
|
|
626
|
-
"startup_logs": startup_logs,
|
|
627
633
|
"addon_logs": addon_logs,
|
|
628
634
|
"log_count": len(recent_logs),
|
|
629
635
|
"startup_log_count": len(startup_logs),
|
|
@@ -94,6 +94,72 @@ def get_startup_logs() -> list[dict[str, Any]]:
|
|
|
94
94
|
return _startup_collector.get_logs()
|
|
95
95
|
|
|
96
96
|
|
|
97
|
+
# Parameter keys whose values are masked before a tool call is recorded to the
|
|
98
|
+
# in-memory ring buffer or persisted to disk. Tool kwargs can carry secrets
|
|
99
|
+
# (alarm/lock ``code``, tokens, passwords); these must never reach the usage
|
|
100
|
+
# log, which ``ha_report_issue`` surfaces and which is written verbatim to
|
|
101
|
+
# plaintext ``mcp_usage.jsonl``. Matching is by key name (case-insensitive) and
|
|
102
|
+
# recursive, so a secret nested under a non-sensitive key — e.g.
|
|
103
|
+
# ``ha_call_service(data={"code": ...})`` — is caught while ``data`` siblings
|
|
104
|
+
# like ``entity_id``/``brightness`` survive for debugging.
|
|
105
|
+
_SENSITIVE_PARAM_KEYS = frozenset(
|
|
106
|
+
{
|
|
107
|
+
"code",
|
|
108
|
+
"pin",
|
|
109
|
+
"password",
|
|
110
|
+
"passwd",
|
|
111
|
+
"secret",
|
|
112
|
+
"token",
|
|
113
|
+
"access_token",
|
|
114
|
+
"refresh_token",
|
|
115
|
+
"api_key",
|
|
116
|
+
"apikey",
|
|
117
|
+
"client_secret",
|
|
118
|
+
"authorization",
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
# Suffix match only for families with a low false-positive rate. Deliberately
|
|
122
|
+
# excludes ``_code``/``_key`` so ``status_code``/``cache_key`` stay readable;
|
|
123
|
+
# the exact ``code``/``pin``/``api_key`` entries above already cover the real
|
|
124
|
+
# Home Assistant service-call surface.
|
|
125
|
+
_SENSITIVE_KEY_SUFFIXES = ("_token", "_secret", "_password", "_passwd")
|
|
126
|
+
_REDACTED_VALUE = "[REDACTED]"
|
|
127
|
+
_MAX_REDACT_DEPTH = 6
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _is_sensitive_key(key: Any) -> bool:
|
|
131
|
+
"""Return True if a parameter key's value should be masked."""
|
|
132
|
+
if not isinstance(key, str):
|
|
133
|
+
return False
|
|
134
|
+
lowered = key.lower()
|
|
135
|
+
return lowered in _SENSITIVE_PARAM_KEYS or lowered.endswith(_SENSITIVE_KEY_SUFFIXES)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _redact_parameters(value: Any, _depth: int = 0) -> Any:
|
|
139
|
+
"""Return a copy of ``value`` with sensitive values masked by key name.
|
|
140
|
+
|
|
141
|
+
Never mutates the input: it is the live tool ``kwargs`` dict, still
|
|
142
|
+
referenced by the caller after this returns. Recurses through nested
|
|
143
|
+
dicts/lists/tuples so secrets nested under non-sensitive keys are caught
|
|
144
|
+
(a tuple is returned as a list). Fails closed past ``_MAX_REDACT_DEPTH`` —
|
|
145
|
+
a subtree too deep to walk is masked wholesale rather than returned verbatim.
|
|
146
|
+
"""
|
|
147
|
+
if _depth > _MAX_REDACT_DEPTH:
|
|
148
|
+
return _REDACTED_VALUE
|
|
149
|
+
if isinstance(value, dict):
|
|
150
|
+
return {
|
|
151
|
+
key: (
|
|
152
|
+
_REDACTED_VALUE
|
|
153
|
+
if _is_sensitive_key(key)
|
|
154
|
+
else _redact_parameters(item, _depth + 1)
|
|
155
|
+
)
|
|
156
|
+
for key, item in value.items()
|
|
157
|
+
}
|
|
158
|
+
if isinstance(value, (list, tuple)):
|
|
159
|
+
return [_redact_parameters(item, _depth + 1) for item in value]
|
|
160
|
+
return value
|
|
161
|
+
|
|
162
|
+
|
|
97
163
|
@dataclass
|
|
98
164
|
class ToolUsageLog:
|
|
99
165
|
"""Single tool usage log entry."""
|
|
@@ -201,10 +267,14 @@ class UsageLogger:
|
|
|
201
267
|
if not self._enabled:
|
|
202
268
|
return
|
|
203
269
|
try:
|
|
270
|
+
# Mask secrets (alarm/lock codes, tokens, passwords) before the entry
|
|
271
|
+
# reaches the ring buffer or disk. Returns a copy — never mutates the
|
|
272
|
+
# caller's live kwargs dict.
|
|
273
|
+
redacted_parameters = _redact_parameters(parameters)
|
|
204
274
|
log_entry = ToolUsageLog(
|
|
205
275
|
timestamp=datetime.now(UTC).isoformat(),
|
|
206
276
|
tool_name=tool_name,
|
|
207
|
-
parameters=
|
|
277
|
+
parameters=redacted_parameters,
|
|
208
278
|
execution_time_ms=execution_time_ms,
|
|
209
279
|
success=success,
|
|
210
280
|
error_message=error_message,
|
|
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
|
|
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
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/resources/skills-vendor/README.md
RENAMED
|
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
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/best_practice_checker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_config.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_entities.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_overview.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_scenes.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/smart_search/_scoring.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_entry_flow.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_config_scripts.py
RENAMED
|
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
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/tools_voice_assistant.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/tools/validation_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/transforms/lite_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp/utils/kill_signal_diagnostics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev640 → ha_mcp_dev-7.6.0.dev641}/src/ha_mcp_dev.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|