topicgate 1.5.2__tar.gz → 1.5.3__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.
- {topicgate-1.5.2/src/topicgate.egg-info → topicgate-1.5.3}/PKG-INFO +20 -33
- {topicgate-1.5.2 → topicgate-1.5.3}/README.md +19 -32
- {topicgate-1.5.2 → topicgate-1.5.3}/pyproject.toml +1 -1
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/app_dependencies.py +2 -0
- topicgate-1.5.3/src/topicgate/app/integration_dependencies.py +17 -0
- topicgate-1.5.3/src/topicgate/app/models/integration.py +84 -0
- topicgate-1.5.3/src/topicgate/app/ports/__init__.py +1 -0
- topicgate-1.5.3/src/topicgate/app/ports/integration_platform.py +21 -0
- topicgate-1.5.3/src/topicgate/app/services/integration_service.py +108 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/mcp_setup_service.py +8 -1
- topicgate-1.5.3/src/topicgate/cli/_common.py +23 -0
- topicgate-1.5.3/src/topicgate/cli/integration_commands.py +99 -0
- topicgate-1.5.3/src/topicgate/cli/platform_commands/__init__.py +1 -0
- topicgate-1.5.3/src/topicgate/cli/platform_commands/integration.py +103 -0
- topicgate-1.5.3/src/topicgate/cli/profile_commands.py +171 -0
- topicgate-1.5.3/src/topicgate/cli/subscription_commands.py +128 -0
- topicgate-1.5.3/src/topicgate/cli/topicgate_cli.py +35 -0
- topicgate-1.5.3/src/topicgate/infrastructure/integrations/__init__.py +1 -0
- topicgate-1.5.3/src/topicgate/infrastructure/integrations/_plugin_cli.py +254 -0
- topicgate-1.5.3/src/topicgate/infrastructure/integrations/claude.py +212 -0
- topicgate-1.5.3/src/topicgate/infrastructure/integrations/codex.py +304 -0
- topicgate-1.5.3/src/topicgate/infrastructure/integrations/copilot.py +135 -0
- topicgate-1.5.3/src/topicgate/infrastructure/integrations/cursor.py +190 -0
- {topicgate-1.5.2 → topicgate-1.5.3/src/topicgate.egg-info}/PKG-INFO +20 -33
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate.egg-info/SOURCES.txt +24 -0
- topicgate-1.5.3/tests/test_claude_integration.py +170 -0
- topicgate-1.5.3/tests/test_codex_integration.py +191 -0
- topicgate-1.5.3/tests/test_copilot_integration.py +129 -0
- topicgate-1.5.3/tests/test_cursor_integration.py +136 -0
- topicgate-1.5.3/tests/test_integration_dependencies.py +28 -0
- topicgate-1.5.3/tests/test_integration_service.py +149 -0
- topicgate-1.5.3/tests/test_plugin_cli_integration.py +21 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_topicgate_cli.py +81 -0
- topicgate-1.5.2/src/topicgate/cli/topicgate_cli.py +0 -274
- {topicgate-1.5.2 → topicgate-1.5.3}/LICENCE +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/setup.cfg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/__main__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/broker_runtime_state.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/models/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/models/broker_inspection.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/models/broker_snapshot.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/models/expectation_health_report.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/models/mcp_setup.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/models/support_bundle_export.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/models/topic_history.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/broker_health_monitor.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/broker_health_wait_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/broker_inspection_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/broker_profile_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/broker_resolver.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/broker_snapshot_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/control_operation_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/diagnostic_profile_editor.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/diagnostic_profile_preview.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/diagnostic_profile_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/expectation_management_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/failure_history_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/finding_delta_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/health_expectation_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/health_query_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/health_report_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/history_recording_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/history_retention_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/observation_cache_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/observation_query_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/observation_recorder.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/observation_retention_policy_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/persistence_lifecycle.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/service_container.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/service_item.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/support_bundle_export_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/support_bundle_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/services/topic_history_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/app/topicgate_runtime.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icon.png +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icon.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icons/broker.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icons/close.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icons/create.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icons/delete.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icons/edit.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icons/help.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icons/observer-tree.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/assets/icons/settings.svg +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/config/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/config/app_config.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/config/mqtt_config.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/broker_profile_store.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/current_topic_reader.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/diagnostic_pack.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/diagnostic_profile_repositories.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/health_action.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/health_observation_sink.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/health_repositories.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/history_recording_store.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/history_retention_store.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/mqtt_message_processor.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/observation_history.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/observer_repo_metadata.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/observer_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/stored_observation_administrator.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/stored_observation_reader.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/interfaces/topic_message_recorder.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/broker_profile.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/broker_profile_identity.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/broker_profile_summary.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/broker_summary.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/connection_status.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/current_topic.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/diagnostic_profile.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/condition.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/condition_kind.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/condition_result.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/diagnostic_report.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/expectation_evaluation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/expectation_failure.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/expectation_state.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/expectation_target.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/health_action_context.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/health_enums.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/health_expectation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/health/health_transition.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/history_recording.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/history_retention.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/message_filter.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/mqtt_message.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/mqtt_observation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/mqtt_state.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/observation_cache_administration.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/observation_deletion_preview.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/observation_event.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/observation_retention_policy.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/observation_status.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/observer_workspace.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/subscription.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/support_bundle.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/models/topic_message.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/mqtt_topics.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/observer_limits.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/core/payload_limits.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/app.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/broker_state_reader.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/about_dialog.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/add_subscription_dialog.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/broker_connection.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/broker_settings_dialog.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/connection_controls.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/diagnostic_profile_editor.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/event_history_widget.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/expectation_editor.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/health_inspector.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/history_settings_widget.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/log_console.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/mcp_setup_dialog.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/observer_tree.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/onboarding_panel.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/publish_pane.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/quantity_editor.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/snapshot_panel.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/stored_observations_dialog.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/subscription_settings.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/support_bundle_export_dialog.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/topic_details.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/topic_metadata.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/components/workspace_pane.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/gui.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/icons.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/main_view_model.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/main_window.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/observer_state_reader.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/settings_migration.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/gui/theme.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/credentials/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/credentials/credential_store.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/credentials/os_credential_store.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/README +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/env.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/script.py.mako +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/7c3e9f1a2b4d_add_observation_retention_policy.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/93fa5748f4b5_initial_revision.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/a91e5c7d4b20_add_health_expectation_pipeline.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/b3e7d2c9f610_complete_expectation_lifecycle.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/b84d61a9c2e7_rename_retention_database_bytes.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/c4d8a7e1f302_add_diagnostic_profiles.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/d2a4c6e8f010_add_control_operation_lease.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/d5e9b8f20314_add_observation_history.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/e6fa09131425_add_history_recording.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/f1490ca3b908_persist_latest_observed_mqtt_state.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic/versions/f70b1a242536_add_history_retention.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/alembic.ini +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/base.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/database_context.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/broker_profile_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/config_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/diagnostic_profile_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/expectation_failure_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/expectation_state_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/health_expectation_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/mapper_helper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/observation_event_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/observation_retention_policy_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/observer_workspace_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/subscription_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/mappers/topic_message_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/migrations.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/app_config_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/broker_profile_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/diagnostic_profile_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/expectation_failure_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/expectation_state_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/health_expectation_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/history_recording_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/history_retention_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/mqtt_config_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/mqtt_message_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/observation_event_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/observation_retention_policy_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/observer_workspace_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/database/models/subscription_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/diagnostic_packs/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/diagnostic_packs/registry.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/diagnostic_pack.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/json_condition.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/loader.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/v1/pack.json +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/health_actions/log_health_action.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/health_actions/persist_failure_action.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/mqtt/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/mqtt/async_callback_bridge.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/mqtt/callbacks/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/mqtt/callbacks/basic_callbacks.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/mqtt/callbacks/observer_repository_callbacks.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/mqtt/mqtt_callbacks.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/mqtt/mqtt_client.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/mqtt/mqtt_gate.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/broker_config_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/broker_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/diagnostic_profile_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/expectation_failure_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/expectation_state_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/health_expectation_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/history_recording_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/history_retention_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/observation_history_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/observation_retention_policy_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/observer_mqtt_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/subscription_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/repository/topic_message_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/infrastructure/support_bundle_archive.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/broker_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/connection_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/dashboard_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/dashboard_snapshot.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/expectation_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/health_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/mcp_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/preview/dashboard_preview.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/publish_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/snapshot_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/subscription_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/support_bundle_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/api/topic_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/capabilities.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/instructions.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/middleware/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/middleware/error_handling_middleware.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/middleware/logging_middleware.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/models.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/requests/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/requests/broker_creation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/requests/expectation_requests.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/mcp/server.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/paths.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/presentation/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/presentation/health_presentation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/presentation/retention_presentation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/presentation/snapshot_presentation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/presentation/support_bundle_representation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/presentation/topic_presentation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/processors/__init__.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/processors/action_dispatcher.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/processors/condition_factory.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/processors/health_action_registry.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/processors/observation_retention_processor.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/processors/subscription_manager.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate/processors/transition_tracker.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate.egg-info/dependency_links.txt +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate.egg-info/entry_points.txt +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate.egg-info/requires.txt +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/src/topicgate.egg-info/top_level.txt +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_app.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_app_dependencies.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_async_callback_bridge.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_broker_config_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_broker_health_evaluation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_broker_inspection_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_broker_repository_persistence.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_broker_resolver.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_broker_snapshot_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_control_operation_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_dashboard_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_dashboard_dependencies.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_dashboard_preview.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_database_migrations.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_desktop_snapshot_states.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_diagnostic_profiles.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_event_history_gui.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_expectation_management.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_failure_history_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_finding_delta_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_github_workflows.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_gui.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_database_models.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_expectation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_mappers.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_mcp_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_pipeline.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_presentation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_provisioning.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_query_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_report_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_repositories.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_health_wait_wire.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_history_recording_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_history_retention.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_main_view_model.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_mcp_apis.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_mcp_disconnected_startup.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_mcp_middleware.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_mcp_server_instructions.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_mcp_setup_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_migrate_app_versions.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_mqtt_callbacks.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_mqtt_client.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_mqtt_message_row.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observation_cache_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observation_history_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observation_query_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observation_retention_policy.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observation_retention_policy_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observation_retention_policy_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observer_model_hydration.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observer_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_observer_workspace_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_os_credential_store.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_paths.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_persistence_lifecycle.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_plugin_bundle.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_retention_administration.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_service_container.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_settings_migration.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_snapshot_mcp_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_snapshot_presentation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_subscription.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_subscription_manager.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_subscription_mapper.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_subscription_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_support_bundle.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_support_bundle_mcp_api.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_topic_history_service.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_topic_message_repository.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_topic_presentation.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_topicgate_runtime.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_verify_distribution.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_zigbee2mqtt_diagnostic_pack.py +0 -0
- {topicgate-1.5.2 → topicgate-1.5.3}/tests/test_zigbee2mqtt_scenario.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: topicgate
|
|
3
|
-
Version: 1.5.
|
|
3
|
+
Version: 1.5.3
|
|
4
4
|
Summary: Secure local access to your MQTT topics
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Repository, https://github.com/Dumdart/TopicGate
|
|
@@ -71,38 +71,29 @@ physical hardware, use the [Zigbee2MQTT scenario](demo/zigbee2mqtt_scenario/READ
|
|
|
71
71
|
|
|
72
72
|
## Get started
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
The default MCP configuration is:
|
|
82
|
-
|
|
83
|
-
```json
|
|
84
|
-
{
|
|
85
|
-
"mcpServers": {
|
|
86
|
-
"topicgate": {
|
|
87
|
-
"command": "topicgate",
|
|
88
|
-
"args": ["--mode", "read-only"]
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
If `topicgate` is not on the host's `PATH`, use the absolute executable path shown by TopicGate Desktop's MCP setup page.
|
|
74
|
+
1. [Install TopicGate for your operating system](docs/install/OS_INSTALL.md).
|
|
75
|
+
2. Run `topicgate-gui` to open **TopicGate Desktop**.
|
|
76
|
+
3. Add a broker profile, enter its credentials locally, connect, and add a bounded subscription such as `home/+/temperature`.
|
|
77
|
+
4. If you want AI access, connect your agent host using a guide below. Desktop works without an agent or MCP configuration.
|
|
78
|
+
5. Keep **read-only mode**, the default for the MCP server and plugin.
|
|
79
|
+
6. Only when you need agent-driven changes, explicitly [enable control mode](docs/install/CONTROL_AND_HEALTH.md) in a trusted environment.
|
|
95
80
|
|
|
96
81
|
## Connect an agent
|
|
97
82
|
|
|
98
|
-
|
|
83
|
+
A **plugin integration** loads TopicGate's agent skills and MCP configuration.
|
|
84
|
+
An **MCP-only integration** connects the MCP server without TopicGate's skills.
|
|
85
|
+
Install the application first; installing a plugin does not install TopicGate or enable control mode.
|
|
99
86
|
|
|
100
|
-
| Host |
|
|
87
|
+
| Host | Plugin and MCP-only setup |
|
|
101
88
|
| --- | --- |
|
|
102
89
|
| Codex | [Codex](docs/install/CODEX.md) |
|
|
103
90
|
| Claude Code | [Claude Code](docs/install/CLAUDE_CODE.md) |
|
|
104
|
-
| VS Code / GitHub Copilot | [VS Code and GitHub Copilot](docs/install/VSCODE_COPILOT.md) |
|
|
105
91
|
| Cursor | [Cursor](docs/install/CURSOR.md) |
|
|
92
|
+
| VS Code / GitHub Copilot CLI | [VS Code and GitHub Copilot](docs/install/VSCODE_COPILOT.md) |
|
|
93
|
+
|
|
94
|
+
The host normally starts the MCP server. Restart it and start a new agent session
|
|
95
|
+
after changing MCP configuration. **Help → MCP setup...** in TopicGate Desktop
|
|
96
|
+
provides the resolved executable, data directory, and a configuration to copy.
|
|
106
97
|
|
|
107
98
|
## Observation semantics
|
|
108
99
|
|
|
@@ -154,7 +145,7 @@ Health results distinguish **healthy**, **problem**, and **unknown**. A health w
|
|
|
154
145
|
|
|
155
146
|
### Let an agent configure and verify health
|
|
156
147
|
|
|
157
|
-
With
|
|
148
|
+
With control mode explicitly enabled, try:
|
|
158
149
|
|
|
159
150
|
> Create or reuse an anonymous broker named Lab at localhost:1883 without TLS. Activate it, subscribe to devices/#, and add an expectation that devices/status equals the UTF-8 value online. Wait up to 30 seconds for health and report any failed or unknown checks. Do not publish a test message.
|
|
160
151
|
|
|
@@ -171,7 +162,7 @@ See [Control mode and expectation verification](docs/install/CONTROL_AND_HEALTH.
|
|
|
171
162
|
| Snapshots | `get_broker_snapshot`, `inspect_broker` | `observe_broker_snapshot` |
|
|
172
163
|
| Brokers | `list_brokers` | `create_broker`, `activate_broker` |
|
|
173
164
|
| Connection | `get_connection_status` | `connect`, `disconnect`, `reconnect` |
|
|
174
|
-
| Topics | `list_topics`, `get_topic_state` | — |
|
|
165
|
+
| Topics | `list_topics`, `get_topic_state`, `get_topic_history` | — |
|
|
175
166
|
| Subscriptions | `list_subscriptions` | `add_subscription`, `update_subscription`, `remove_subscription` |
|
|
176
167
|
| Expectations | `list_health_expectations` | `create_health_expectation`, `update_health_expectation`, `delete_health_expectation` |
|
|
177
168
|
| Health | `query_failure_history` | `get_health_report`, `wait_for_broker_health` |
|
|
@@ -179,13 +170,9 @@ See [Control mode and expectation verification](docs/install/CONTROL_AND_HEALTH.
|
|
|
179
170
|
| Publishing | — | `publish` |
|
|
180
171
|
| Dashboard | — | `open_topicgate_dashboard` |
|
|
181
172
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
```console
|
|
185
|
-
topicgate --mode control
|
|
186
|
-
```
|
|
173
|
+
The optional dashboard also requires the `apps` package extra and a host that supports MCP apps.
|
|
187
174
|
|
|
188
|
-
|
|
175
|
+
Control mode includes the passive tools. The plugin's default configuration stays read-only; shipping `.mcp-control.json` does not enable it automatically. Follow [Control mode and health](docs/install/CONTROL_AND_HEALTH.md) to configure and restart the server.
|
|
189
176
|
|
|
190
177
|
For troubleshooting, use **Help → Export support bundle…** in Desktop or call
|
|
191
178
|
`get_support_bundle` through MCP. Desktop payload inclusion is off by default and
|
|
@@ -32,38 +32,29 @@ physical hardware, use the [Zigbee2MQTT scenario](demo/zigbee2mqtt_scenario/READ
|
|
|
32
32
|
|
|
33
33
|
## Get started
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
The default MCP configuration is:
|
|
43
|
-
|
|
44
|
-
```json
|
|
45
|
-
{
|
|
46
|
-
"mcpServers": {
|
|
47
|
-
"topicgate": {
|
|
48
|
-
"command": "topicgate",
|
|
49
|
-
"args": ["--mode", "read-only"]
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
If `topicgate` is not on the host's `PATH`, use the absolute executable path shown by TopicGate Desktop's MCP setup page.
|
|
35
|
+
1. [Install TopicGate for your operating system](docs/install/OS_INSTALL.md).
|
|
36
|
+
2. Run `topicgate-gui` to open **TopicGate Desktop**.
|
|
37
|
+
3. Add a broker profile, enter its credentials locally, connect, and add a bounded subscription such as `home/+/temperature`.
|
|
38
|
+
4. If you want AI access, connect your agent host using a guide below. Desktop works without an agent or MCP configuration.
|
|
39
|
+
5. Keep **read-only mode**, the default for the MCP server and plugin.
|
|
40
|
+
6. Only when you need agent-driven changes, explicitly [enable control mode](docs/install/CONTROL_AND_HEALTH.md) in a trusted environment.
|
|
56
41
|
|
|
57
42
|
## Connect an agent
|
|
58
43
|
|
|
59
|
-
|
|
44
|
+
A **plugin integration** loads TopicGate's agent skills and MCP configuration.
|
|
45
|
+
An **MCP-only integration** connects the MCP server without TopicGate's skills.
|
|
46
|
+
Install the application first; installing a plugin does not install TopicGate or enable control mode.
|
|
60
47
|
|
|
61
|
-
| Host |
|
|
48
|
+
| Host | Plugin and MCP-only setup |
|
|
62
49
|
| --- | --- |
|
|
63
50
|
| Codex | [Codex](docs/install/CODEX.md) |
|
|
64
51
|
| Claude Code | [Claude Code](docs/install/CLAUDE_CODE.md) |
|
|
65
|
-
| VS Code / GitHub Copilot | [VS Code and GitHub Copilot](docs/install/VSCODE_COPILOT.md) |
|
|
66
52
|
| Cursor | [Cursor](docs/install/CURSOR.md) |
|
|
53
|
+
| VS Code / GitHub Copilot CLI | [VS Code and GitHub Copilot](docs/install/VSCODE_COPILOT.md) |
|
|
54
|
+
|
|
55
|
+
The host normally starts the MCP server. Restart it and start a new agent session
|
|
56
|
+
after changing MCP configuration. **Help → MCP setup...** in TopicGate Desktop
|
|
57
|
+
provides the resolved executable, data directory, and a configuration to copy.
|
|
67
58
|
|
|
68
59
|
## Observation semantics
|
|
69
60
|
|
|
@@ -115,7 +106,7 @@ Health results distinguish **healthy**, **problem**, and **unknown**. A health w
|
|
|
115
106
|
|
|
116
107
|
### Let an agent configure and verify health
|
|
117
108
|
|
|
118
|
-
With
|
|
109
|
+
With control mode explicitly enabled, try:
|
|
119
110
|
|
|
120
111
|
> Create or reuse an anonymous broker named Lab at localhost:1883 without TLS. Activate it, subscribe to devices/#, and add an expectation that devices/status equals the UTF-8 value online. Wait up to 30 seconds for health and report any failed or unknown checks. Do not publish a test message.
|
|
121
112
|
|
|
@@ -132,7 +123,7 @@ See [Control mode and expectation verification](docs/install/CONTROL_AND_HEALTH.
|
|
|
132
123
|
| Snapshots | `get_broker_snapshot`, `inspect_broker` | `observe_broker_snapshot` |
|
|
133
124
|
| Brokers | `list_brokers` | `create_broker`, `activate_broker` |
|
|
134
125
|
| Connection | `get_connection_status` | `connect`, `disconnect`, `reconnect` |
|
|
135
|
-
| Topics | `list_topics`, `get_topic_state` | — |
|
|
126
|
+
| Topics | `list_topics`, `get_topic_state`, `get_topic_history` | — |
|
|
136
127
|
| Subscriptions | `list_subscriptions` | `add_subscription`, `update_subscription`, `remove_subscription` |
|
|
137
128
|
| Expectations | `list_health_expectations` | `create_health_expectation`, `update_health_expectation`, `delete_health_expectation` |
|
|
138
129
|
| Health | `query_failure_history` | `get_health_report`, `wait_for_broker_health` |
|
|
@@ -140,13 +131,9 @@ See [Control mode and expectation verification](docs/install/CONTROL_AND_HEALTH.
|
|
|
140
131
|
| Publishing | — | `publish` |
|
|
141
132
|
| Dashboard | — | `open_topicgate_dashboard` |
|
|
142
133
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
```console
|
|
146
|
-
topicgate --mode control
|
|
147
|
-
```
|
|
134
|
+
The optional dashboard also requires the `apps` package extra and a host that supports MCP apps.
|
|
148
135
|
|
|
149
|
-
|
|
136
|
+
Control mode includes the passive tools. The plugin's default configuration stays read-only; shipping `.mcp-control.json` does not enable it automatically. Follow [Control mode and health](docs/install/CONTROL_AND_HEALTH.md) to configure and restart the server.
|
|
150
137
|
|
|
151
138
|
For troubleshooting, use **Help → Export support bundle…** in Desktop or call
|
|
152
139
|
`get_support_bundle` through MCP. Desktop payload inclusion is off by default and
|
|
@@ -28,6 +28,7 @@ from topicgate.app.services.broker_snapshot_service import BrokerSnapshotService
|
|
|
28
28
|
from topicgate.app.services.broker_resolver import BrokerResolver
|
|
29
29
|
from topicgate.app.services.control_operation_service import ControlOperationService
|
|
30
30
|
from topicgate.app.services.mcp_setup_service import McpSetupService
|
|
31
|
+
from topicgate.app.services.integration_service import IntegrationService
|
|
31
32
|
from topicgate.app.broker_runtime_state import BrokerRuntimeState
|
|
32
33
|
from topicgate.app.services.support_bundle_export_service import (
|
|
33
34
|
SupportBundleExporter,
|
|
@@ -252,6 +253,7 @@ class AppDependencies:
|
|
|
252
253
|
active_broker_reader=self.broker_profiles.get_profile_summary,
|
|
253
254
|
subscriptions_reader=self.broker_profiles.list_subscriptions,
|
|
254
255
|
)
|
|
256
|
+
self.integration_service = IntegrationService(self.mcp_setup.information)
|
|
255
257
|
self.support_bundle_service = SupportBundleService(
|
|
256
258
|
self.runtime,
|
|
257
259
|
self.snapshot_service,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from topicgate.app.services.integration_service import IntegrationService
|
|
4
|
+
from topicgate.app.services.mcp_setup_service import McpSetupService
|
|
5
|
+
from topicgate.paths import prepare_database_path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class IntegrationDependencies:
|
|
9
|
+
"""Build integration-only dependencies without opening the TopicGate DB."""
|
|
10
|
+
|
|
11
|
+
def __init__(self, data_dir: Path | None = None) -> None:
|
|
12
|
+
database_path = prepare_database_path(data_dir)
|
|
13
|
+
information = McpSetupService.resolve_information(
|
|
14
|
+
database_path.parent,
|
|
15
|
+
database_path,
|
|
16
|
+
)
|
|
17
|
+
self.integration_service = IntegrationService(information)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from enum import StrEnum
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class McpMode(StrEnum):
|
|
6
|
+
READ_ONLY = "read-only"
|
|
7
|
+
CONTROL = "control"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass(frozen=True)
|
|
11
|
+
class McpServerState:
|
|
12
|
+
name: str
|
|
13
|
+
command: str
|
|
14
|
+
arguments: tuple[str, ...]
|
|
15
|
+
environment: tuple[tuple[str, str], ...] = ()
|
|
16
|
+
source: str | None = None
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def mode(self) -> McpMode | None:
|
|
20
|
+
value: str | None = None
|
|
21
|
+
for index, argument in enumerate(self.arguments):
|
|
22
|
+
if argument == "--mode":
|
|
23
|
+
value = (
|
|
24
|
+
self.arguments[index + 1]
|
|
25
|
+
if index + 1 < len(self.arguments)
|
|
26
|
+
else None
|
|
27
|
+
)
|
|
28
|
+
elif argument.startswith("--mode="):
|
|
29
|
+
value = argument.removeprefix("--mode=")
|
|
30
|
+
try:
|
|
31
|
+
return McpMode(value)
|
|
32
|
+
except (TypeError, ValueError):
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class PlatformIntegrationState:
|
|
38
|
+
platform: str
|
|
39
|
+
available: bool
|
|
40
|
+
marketplace_configured: bool = False
|
|
41
|
+
plugin_installed: bool = False
|
|
42
|
+
plugin_version: str | None = None
|
|
43
|
+
servers: tuple[McpServerState, ...] = ()
|
|
44
|
+
issues: tuple[str, ...] = ()
|
|
45
|
+
plugin_enabled: bool | None = None
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class IntegrationActionKind(StrEnum):
|
|
49
|
+
ADD_MARKETPLACE = "add_marketplace"
|
|
50
|
+
REFRESH_MARKETPLACE = "refresh_marketplace"
|
|
51
|
+
INSTALL_PLUGIN = "install_plugin"
|
|
52
|
+
REMOVE_SERVER = "remove_server"
|
|
53
|
+
CONFIGURE_SERVER = "configure_server"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass(frozen=True)
|
|
57
|
+
class IntegrationAction:
|
|
58
|
+
kind: IntegrationActionKind
|
|
59
|
+
target: str
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True)
|
|
63
|
+
class IntegrationSpec:
|
|
64
|
+
platform: str
|
|
65
|
+
mode: McpMode
|
|
66
|
+
package_version: str
|
|
67
|
+
server_name: str
|
|
68
|
+
command: str
|
|
69
|
+
arguments: tuple[str, ...]
|
|
70
|
+
environment: tuple[tuple[str, str], ...]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True)
|
|
74
|
+
class IntegrationPlan:
|
|
75
|
+
desired: IntegrationSpec
|
|
76
|
+
current: PlatformIntegrationState
|
|
77
|
+
actions: tuple[IntegrationAction, ...]
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@dataclass(frozen=True)
|
|
81
|
+
class IntegrationResult:
|
|
82
|
+
state: PlatformIntegrationState
|
|
83
|
+
changed: bool
|
|
84
|
+
messages: tuple[str, ...] = ()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Application ports implemented by external integration adapters."""
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
|
|
3
|
+
from topicgate.app.models.integration import (
|
|
4
|
+
IntegrationPlan,
|
|
5
|
+
IntegrationResult,
|
|
6
|
+
IntegrationSpec,
|
|
7
|
+
PlatformIntegrationState,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class IntegrationPlatform(Protocol):
|
|
12
|
+
@property
|
|
13
|
+
def name(self) -> str: ...
|
|
14
|
+
|
|
15
|
+
def inspect(self) -> PlatformIntegrationState: ...
|
|
16
|
+
|
|
17
|
+
def plan(self, desired: IntegrationSpec) -> IntegrationPlan: ...
|
|
18
|
+
|
|
19
|
+
def apply(self, plan: IntegrationPlan) -> IntegrationResult: ...
|
|
20
|
+
|
|
21
|
+
def remove(self) -> IntegrationResult: ...
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from dataclasses import replace
|
|
2
|
+
|
|
3
|
+
from topicgate.app.models.integration import (
|
|
4
|
+
IntegrationActionKind,
|
|
5
|
+
IntegrationResult,
|
|
6
|
+
IntegrationSpec,
|
|
7
|
+
McpMode,
|
|
8
|
+
PlatformIntegrationState,
|
|
9
|
+
)
|
|
10
|
+
from topicgate.app.models.mcp_setup import McpSetupInformation
|
|
11
|
+
from topicgate.app.ports.integration_platform import IntegrationPlatform
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class IntegrationService:
|
|
15
|
+
"""Converge supported agent hosts on one TopicGate integration."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, information: McpSetupInformation):
|
|
18
|
+
self._information = information
|
|
19
|
+
|
|
20
|
+
def install(
|
|
21
|
+
self,
|
|
22
|
+
platform: IntegrationPlatform,
|
|
23
|
+
mode: McpMode = McpMode.READ_ONLY,
|
|
24
|
+
) -> IntegrationResult:
|
|
25
|
+
plan = platform.plan(self._specification(platform, mode))
|
|
26
|
+
if not plan.actions:
|
|
27
|
+
return IntegrationResult(
|
|
28
|
+
state=plan.current,
|
|
29
|
+
changed=False,
|
|
30
|
+
messages=(f"{platform.name} integration is already configured.",),
|
|
31
|
+
)
|
|
32
|
+
return platform.apply(plan)
|
|
33
|
+
|
|
34
|
+
def uninstall(self, platform: IntegrationPlatform) -> IntegrationResult:
|
|
35
|
+
return platform.remove()
|
|
36
|
+
|
|
37
|
+
def status(self, platform: IntegrationPlatform) -> PlatformIntegrationState:
|
|
38
|
+
state = platform.inspect()
|
|
39
|
+
if not state.available:
|
|
40
|
+
return state
|
|
41
|
+
|
|
42
|
+
configured_modes = {
|
|
43
|
+
server.mode for server in state.servers if server.mode is not None
|
|
44
|
+
}
|
|
45
|
+
mode = (
|
|
46
|
+
configured_modes.pop()
|
|
47
|
+
if len(configured_modes) == 1
|
|
48
|
+
else McpMode.READ_ONLY
|
|
49
|
+
)
|
|
50
|
+
plan = platform.plan(self._specification(platform, mode))
|
|
51
|
+
issues = list(state.issues)
|
|
52
|
+
action_kinds = {action.kind for action in plan.actions}
|
|
53
|
+
if IntegrationActionKind.ADD_MARKETPLACE in action_kinds:
|
|
54
|
+
issues.append("TopicGate marketplace is not configured.")
|
|
55
|
+
if (
|
|
56
|
+
state.plugin_installed
|
|
57
|
+
and state.plugin_enabled is not False
|
|
58
|
+
and IntegrationActionKind.INSTALL_PLUGIN in action_kinds
|
|
59
|
+
):
|
|
60
|
+
issues.append(
|
|
61
|
+
"TopicGate plugin version does not match the installed "
|
|
62
|
+
f"TopicGate package {self._information.version}."
|
|
63
|
+
)
|
|
64
|
+
if (
|
|
65
|
+
state.servers
|
|
66
|
+
and IntegrationActionKind.CONFIGURE_SERVER in action_kinds
|
|
67
|
+
):
|
|
68
|
+
issues.append(
|
|
69
|
+
"TopicGate MCP configuration does not match the resolved "
|
|
70
|
+
"executable, mode, or data directory."
|
|
71
|
+
)
|
|
72
|
+
return replace(state, issues=tuple(dict.fromkeys(issues)))
|
|
73
|
+
|
|
74
|
+
def repair(
|
|
75
|
+
self,
|
|
76
|
+
platform: IntegrationPlatform,
|
|
77
|
+
mode: McpMode | None = None,
|
|
78
|
+
) -> IntegrationResult:
|
|
79
|
+
if mode is None:
|
|
80
|
+
state = platform.inspect()
|
|
81
|
+
configured_modes = {
|
|
82
|
+
server.mode for server in state.servers if server.mode is not None
|
|
83
|
+
}
|
|
84
|
+
mode = (
|
|
85
|
+
configured_modes.pop()
|
|
86
|
+
if len(configured_modes) == 1
|
|
87
|
+
else McpMode.READ_ONLY
|
|
88
|
+
)
|
|
89
|
+
return self.install(platform, mode)
|
|
90
|
+
|
|
91
|
+
def _specification(
|
|
92
|
+
self,
|
|
93
|
+
platform: IntegrationPlatform,
|
|
94
|
+
mode: McpMode,
|
|
95
|
+
) -> IntegrationSpec:
|
|
96
|
+
return IntegrationSpec(
|
|
97
|
+
platform=platform.name,
|
|
98
|
+
mode=mode,
|
|
99
|
+
package_version=self._information.version,
|
|
100
|
+
server_name="topicgate",
|
|
101
|
+
command=self._information.command,
|
|
102
|
+
arguments=(
|
|
103
|
+
*self._information.command_prefix_arguments,
|
|
104
|
+
"--mode",
|
|
105
|
+
mode.value,
|
|
106
|
+
),
|
|
107
|
+
environment=(("TOPICGATE_DATA_DIR", str(self._information.data_path)),),
|
|
108
|
+
)
|
|
@@ -46,6 +46,13 @@ class McpSetupService:
|
|
|
46
46
|
self._broker_reader = broker_reader
|
|
47
47
|
self._active_broker_reader = active_broker_reader
|
|
48
48
|
self._subscriptions_reader = subscriptions_reader
|
|
49
|
+
self.information = self.resolve_information(data_path, database_path)
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def resolve_information(
|
|
53
|
+
data_path: Path,
|
|
54
|
+
database_path: Path,
|
|
55
|
+
) -> McpSetupInformation:
|
|
49
56
|
executable = shutil.which("topicgate")
|
|
50
57
|
if executable:
|
|
51
58
|
command = str(Path(executable).resolve())
|
|
@@ -57,7 +64,7 @@ class McpSetupService:
|
|
|
57
64
|
installed_version = version("topicgate")
|
|
58
65
|
except PackageNotFoundError:
|
|
59
66
|
installed_version = "development"
|
|
60
|
-
|
|
67
|
+
return McpSetupInformation(
|
|
61
68
|
version=installed_version,
|
|
62
69
|
executable_path=Path(command),
|
|
63
70
|
data_path=data_path.resolve(),
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Shared types and output helpers for TopicGate CLI commands."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from collections.abc import Callable
|
|
5
|
+
from typing import Protocol
|
|
6
|
+
|
|
7
|
+
from topicgate.app.app_dependencies import AppDependencies
|
|
8
|
+
from topicgate.app.services.integration_service import IntegrationService
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
DependenciesFactory = Callable[[], AppDependencies]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class IntegrationDependencies(Protocol):
|
|
15
|
+
integration_service: IntegrationService
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
IntegrationDependenciesFactory = Callable[[], IntegrationDependencies]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def print_error(error: Exception) -> None:
|
|
22
|
+
message = error.args[0] if isinstance(error, KeyError) else str(error)
|
|
23
|
+
print(f"Error: {message}", file=sys.stderr)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from collections.abc import Callable
|
|
3
|
+
from functools import partial
|
|
4
|
+
|
|
5
|
+
from topicgate.cli._common import IntegrationDependenciesFactory
|
|
6
|
+
from topicgate.cli.platform_commands.integration import (
|
|
7
|
+
PlatformFactory,
|
|
8
|
+
integration_install,
|
|
9
|
+
integration_repair,
|
|
10
|
+
integration_status,
|
|
11
|
+
integration_uninstall,
|
|
12
|
+
)
|
|
13
|
+
from topicgate.infrastructure.integrations.claude import ClaudeIntegration
|
|
14
|
+
from topicgate.infrastructure.integrations.codex import CodexIntegration
|
|
15
|
+
from topicgate.infrastructure.integrations.copilot import CopilotIntegration
|
|
16
|
+
from topicgate.infrastructure.integrations.cursor import CursorIntegration
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _platforms() -> tuple[tuple[str, str, PlatformFactory], ...]:
|
|
20
|
+
return (
|
|
21
|
+
("codex", "Codex", CodexIntegration),
|
|
22
|
+
("claude", "Claude Code", ClaudeIntegration),
|
|
23
|
+
("cursor", "Cursor", CursorIntegration),
|
|
24
|
+
("copilot", "GitHub Copilot CLI", CopilotIntegration),
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _platform_parser(
|
|
29
|
+
parser: argparse.ArgumentParser,
|
|
30
|
+
handler: Callable[..., int],
|
|
31
|
+
dependencies_factory: IntegrationDependenciesFactory,
|
|
32
|
+
*,
|
|
33
|
+
include_mode: bool,
|
|
34
|
+
) -> None:
|
|
35
|
+
platforms = parser.add_subparsers(dest="integration_platform", required=True)
|
|
36
|
+
for name, display_name, platform_factory in _platforms():
|
|
37
|
+
platform_parser = platforms.add_parser(
|
|
38
|
+
name,
|
|
39
|
+
help=f"Manage the {display_name} integration",
|
|
40
|
+
)
|
|
41
|
+
if include_mode:
|
|
42
|
+
platform_parser.add_argument(
|
|
43
|
+
"--mode",
|
|
44
|
+
choices=("read-only", "control"),
|
|
45
|
+
default=None,
|
|
46
|
+
help="MCP capability mode; install defaults to read-only",
|
|
47
|
+
)
|
|
48
|
+
platform_parser.set_defaults(
|
|
49
|
+
handler=partial(
|
|
50
|
+
handler,
|
|
51
|
+
dependencies_factory=dependencies_factory,
|
|
52
|
+
platform_factory=platform_factory,
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def configure_integration_commands(
|
|
58
|
+
parser: argparse.ArgumentParser,
|
|
59
|
+
dependencies_factory: IntegrationDependenciesFactory,
|
|
60
|
+
) -> None:
|
|
61
|
+
commands = parser.add_subparsers(dest="integration_command", required=True)
|
|
62
|
+
|
|
63
|
+
install_parser = commands.add_parser(
|
|
64
|
+
"install", help="Install or update an integration"
|
|
65
|
+
)
|
|
66
|
+
_platform_parser(
|
|
67
|
+
install_parser,
|
|
68
|
+
integration_install,
|
|
69
|
+
dependencies_factory,
|
|
70
|
+
include_mode=True,
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
status_parser = commands.add_parser("status", help="Inspect an integration")
|
|
74
|
+
_platform_parser(
|
|
75
|
+
status_parser,
|
|
76
|
+
integration_status,
|
|
77
|
+
dependencies_factory,
|
|
78
|
+
include_mode=False,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
repair_parser = commands.add_parser(
|
|
82
|
+
"repair", help="Repair an integration without changing its mode"
|
|
83
|
+
)
|
|
84
|
+
_platform_parser(
|
|
85
|
+
repair_parser,
|
|
86
|
+
integration_repair,
|
|
87
|
+
dependencies_factory,
|
|
88
|
+
include_mode=True,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
uninstall_parser = commands.add_parser(
|
|
92
|
+
"uninstall", help="Remove an integration"
|
|
93
|
+
)
|
|
94
|
+
_platform_parser(
|
|
95
|
+
uninstall_parser,
|
|
96
|
+
integration_uninstall,
|
|
97
|
+
dependencies_factory,
|
|
98
|
+
include_mode=False,
|
|
99
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Platform-specific TopicGate CLI command handlers."""
|