topicgate 1.2.2__tar.gz → 1.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. topicgate-1.5.2/PKG-INFO +213 -0
  2. topicgate-1.5.2/README.md +174 -0
  3. {topicgate-1.2.2 → topicgate-1.5.2}/pyproject.toml +10 -3
  4. topicgate-1.5.2/src/topicgate/app/app_dependencies.py +292 -0
  5. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/broker_runtime_state.py +3 -12
  6. topicgate-1.5.2/src/topicgate/app/models/__init__.py +16 -0
  7. topicgate-1.5.2/src/topicgate/app/models/broker_inspection.py +22 -0
  8. topicgate-1.5.2/src/topicgate/app/models/expectation_health_report.py +123 -0
  9. topicgate-1.5.2/src/topicgate/app/models/support_bundle_export.py +8 -0
  10. topicgate-1.5.2/src/topicgate/app/models/topic_history.py +40 -0
  11. topicgate-1.5.2/src/topicgate/app/services/broker_health_monitor.py +84 -0
  12. topicgate-1.5.2/src/topicgate/app/services/broker_health_wait_service.py +242 -0
  13. topicgate-1.5.2/src/topicgate/app/services/broker_inspection_service.py +67 -0
  14. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/broker_profile_service.py +131 -52
  15. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/broker_snapshot_service.py +64 -30
  16. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/control_operation_service.py +21 -1
  17. topicgate-1.5.2/src/topicgate/app/services/diagnostic_profile_editor.py +202 -0
  18. topicgate-1.5.2/src/topicgate/app/services/diagnostic_profile_preview.py +31 -0
  19. topicgate-1.5.2/src/topicgate/app/services/diagnostic_profile_service.py +444 -0
  20. topicgate-1.5.2/src/topicgate/app/services/expectation_management_service.py +319 -0
  21. topicgate-1.5.2/src/topicgate/app/services/failure_history_service.py +159 -0
  22. topicgate-1.5.2/src/topicgate/app/services/finding_delta_service.py +303 -0
  23. topicgate-1.5.2/src/topicgate/app/services/health_expectation_service.py +665 -0
  24. topicgate-1.5.2/src/topicgate/app/services/health_query_service.py +300 -0
  25. topicgate-1.5.2/src/topicgate/app/services/health_report_service.py +163 -0
  26. topicgate-1.5.2/src/topicgate/app/services/history_recording_service.py +205 -0
  27. topicgate-1.5.2/src/topicgate/app/services/history_retention_service.py +52 -0
  28. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/mcp_setup_service.py +47 -3
  29. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/observation_cache_service.py +33 -57
  30. topicgate-1.5.2/src/topicgate/app/services/observation_query_service.py +55 -0
  31. topicgate-1.5.2/src/topicgate/app/services/observation_recorder.py +49 -0
  32. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/persistence_lifecycle.py +14 -2
  33. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/service_container.py +7 -1
  34. topicgate-1.5.2/src/topicgate/app/services/support_bundle_export_service.py +46 -0
  35. topicgate-1.5.2/src/topicgate/app/services/support_bundle_service.py +565 -0
  36. topicgate-1.5.2/src/topicgate/app/services/topic_history_service.py +153 -0
  37. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/topicgate_runtime.py +154 -48
  38. topicgate-1.5.2/src/topicgate/assets/icons/broker.svg +19 -0
  39. topicgate-1.5.2/src/topicgate/assets/icons/close.svg +14 -0
  40. topicgate-1.5.2/src/topicgate/assets/icons/create.svg +14 -0
  41. topicgate-1.5.2/src/topicgate/assets/icons/delete.svg +17 -0
  42. topicgate-1.5.2/src/topicgate/assets/icons/edit.svg +14 -0
  43. topicgate-1.5.2/src/topicgate/assets/icons/help.svg +15 -0
  44. topicgate-1.5.2/src/topicgate/assets/icons/observer-tree.svg +17 -0
  45. topicgate-1.5.2/src/topicgate/assets/icons/settings.svg +14 -0
  46. topicgate-1.5.2/src/topicgate/cli/topicgate_cli.py +274 -0
  47. topicgate-1.5.2/src/topicgate/core/interfaces/__init__.py +12 -0
  48. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/interfaces/broker_profile_store.py +0 -3
  49. topicgate-1.5.2/src/topicgate/core/interfaces/current_topic_reader.py +20 -0
  50. topicgate-1.5.2/src/topicgate/core/interfaces/diagnostic_pack.py +36 -0
  51. topicgate-1.5.2/src/topicgate/core/interfaces/diagnostic_profile_repositories.py +12 -0
  52. topicgate-1.5.2/src/topicgate/core/interfaces/health_action.py +7 -0
  53. topicgate-1.5.2/src/topicgate/core/interfaces/health_observation_sink.py +11 -0
  54. topicgate-1.5.2/src/topicgate/core/interfaces/health_repositories.py +83 -0
  55. topicgate-1.5.2/src/topicgate/core/interfaces/history_recording_store.py +14 -0
  56. topicgate-1.5.2/src/topicgate/core/interfaces/history_retention_store.py +12 -0
  57. topicgate-1.5.2/src/topicgate/core/interfaces/observation_history.py +18 -0
  58. topicgate-1.2.2/src/topicgate/core/interfaces/observer_repository.py → topicgate-1.5.2/src/topicgate/core/interfaces/observer_repo_metadata.py +12 -26
  59. topicgate-1.5.2/src/topicgate/core/interfaces/observer_repository.py +13 -0
  60. topicgate-1.5.2/src/topicgate/core/interfaces/stored_observation_administrator.py +21 -0
  61. topicgate-1.5.2/src/topicgate/core/interfaces/stored_observation_reader.py +36 -0
  62. topicgate-1.5.2/src/topicgate/core/interfaces/topic_message_recorder.py +23 -0
  63. topicgate-1.5.2/src/topicgate/core/models/broker_profile_summary.py +12 -0
  64. topicgate-1.5.2/src/topicgate/core/models/current_topic.py +36 -0
  65. topicgate-1.5.2/src/topicgate/core/models/diagnostic_profile.py +98 -0
  66. topicgate-1.5.2/src/topicgate/core/models/health/__init__.py +66 -0
  67. topicgate-1.5.2/src/topicgate/core/models/health/condition.py +320 -0
  68. topicgate-1.5.2/src/topicgate/core/models/health/condition_kind.py +11 -0
  69. topicgate-1.5.2/src/topicgate/core/models/health/condition_result.py +11 -0
  70. topicgate-1.5.2/src/topicgate/core/models/health/diagnostic_report.py +46 -0
  71. topicgate-1.5.2/src/topicgate/core/models/health/expectation_evaluation.py +16 -0
  72. topicgate-1.5.2/src/topicgate/core/models/health/expectation_failure.py +19 -0
  73. topicgate-1.5.2/src/topicgate/core/models/health/expectation_state.py +15 -0
  74. topicgate-1.5.2/src/topicgate/core/models/health/expectation_target.py +25 -0
  75. topicgate-1.5.2/src/topicgate/core/models/health/health_action_context.py +28 -0
  76. topicgate-1.5.2/src/topicgate/core/models/health/health_enums.py +17 -0
  77. topicgate-1.5.2/src/topicgate/core/models/health/health_expectation.py +55 -0
  78. topicgate-1.5.2/src/topicgate/core/models/health/health_transition.py +7 -0
  79. topicgate-1.5.2/src/topicgate/core/models/history_recording.py +22 -0
  80. topicgate-1.5.2/src/topicgate/core/models/history_retention.py +43 -0
  81. topicgate-1.5.2/src/topicgate/core/models/message_filter.py +25 -0
  82. topicgate-1.5.2/src/topicgate/core/models/observation_event.py +26 -0
  83. topicgate-1.5.2/src/topicgate/core/models/observation_status.py +8 -0
  84. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/observer_workspace.py +0 -2
  85. topicgate-1.5.2/src/topicgate/core/models/support_bundle.py +188 -0
  86. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/topic_message.py +1 -1
  87. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/mqtt_topics.py +5 -0
  88. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/observer_limits.py +0 -5
  89. topicgate-1.5.2/src/topicgate/gui/app.py +245 -0
  90. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/about_dialog.py +3 -0
  91. topicgate-1.5.2/src/topicgate/gui/components/broker_connection.py +378 -0
  92. topicgate-1.5.2/src/topicgate/gui/components/connection_controls.py +285 -0
  93. topicgate-1.5.2/src/topicgate/gui/components/diagnostic_profile_editor.py +225 -0
  94. topicgate-1.5.2/src/topicgate/gui/components/event_history_widget.py +286 -0
  95. topicgate-1.5.2/src/topicgate/gui/components/expectation_editor.py +652 -0
  96. topicgate-1.5.2/src/topicgate/gui/components/health_inspector.py +681 -0
  97. topicgate-1.5.2/src/topicgate/gui/components/history_settings_widget.py +209 -0
  98. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/mcp_setup_dialog.py +3 -0
  99. topicgate-1.5.2/src/topicgate/gui/components/observer_tree.py +374 -0
  100. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/onboarding_panel.py +3 -0
  101. topicgate-1.5.2/src/topicgate/gui/components/publish_pane.py +85 -0
  102. topicgate-1.5.2/src/topicgate/gui/components/quantity_editor.py +23 -0
  103. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/snapshot_panel.py +58 -66
  104. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/stored_observations_dialog.py +334 -39
  105. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/subscription_settings.py +49 -14
  106. topicgate-1.5.2/src/topicgate/gui/components/support_bundle_export_dialog.py +114 -0
  107. topicgate-1.5.2/src/topicgate/gui/components/topic_details.py +320 -0
  108. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/topic_metadata.py +26 -9
  109. topicgate-1.5.2/src/topicgate/gui/components/workspace_pane.py +112 -0
  110. topicgate-1.5.2/src/topicgate/gui/icons.py +29 -0
  111. topicgate-1.5.2/src/topicgate/gui/main_view_model.py +1638 -0
  112. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/main_window.py +628 -167
  113. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/observer_state_reader.py +0 -4
  114. topicgate-1.5.2/src/topicgate/gui/theme.py +107 -0
  115. topicgate-1.5.2/src/topicgate/infrastructure/database/alembic/versions/a91e5c7d4b20_add_health_expectation_pipeline.py +85 -0
  116. topicgate-1.5.2/src/topicgate/infrastructure/database/alembic/versions/b3e7d2c9f610_complete_expectation_lifecycle.py +101 -0
  117. topicgate-1.5.2/src/topicgate/infrastructure/database/alembic/versions/c4d8a7e1f302_add_diagnostic_profiles.py +128 -0
  118. topicgate-1.5.2/src/topicgate/infrastructure/database/alembic/versions/d5e9b8f20314_add_observation_history.py +39 -0
  119. topicgate-1.5.2/src/topicgate/infrastructure/database/alembic/versions/e6fa09131425_add_history_recording.py +31 -0
  120. topicgate-1.5.2/src/topicgate/infrastructure/database/alembic/versions/f70b1a242536_add_history_retention.py +42 -0
  121. topicgate-1.5.2/src/topicgate/infrastructure/database/mappers/diagnostic_profile_mapper.py +58 -0
  122. topicgate-1.5.2/src/topicgate/infrastructure/database/mappers/expectation_failure_mapper.py +42 -0
  123. topicgate-1.5.2/src/topicgate/infrastructure/database/mappers/expectation_state_mapper.py +31 -0
  124. topicgate-1.5.2/src/topicgate/infrastructure/database/mappers/health_expectation_mapper.py +343 -0
  125. topicgate-1.5.2/src/topicgate/infrastructure/database/mappers/observation_event_mapper.py +27 -0
  126. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/mappers/observer_workspace_mapper.py +1 -8
  127. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/mappers/topic_message_mapper.py +1 -0
  128. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/migrations.py +1 -1
  129. topicgate-1.5.2/src/topicgate/infrastructure/database/models/__init__.py +54 -0
  130. topicgate-1.5.2/src/topicgate/infrastructure/database/models/diagnostic_profile_row.py +30 -0
  131. topicgate-1.5.2/src/topicgate/infrastructure/database/models/expectation_failure_row.py +29 -0
  132. topicgate-1.5.2/src/topicgate/infrastructure/database/models/expectation_state_row.py +30 -0
  133. topicgate-1.5.2/src/topicgate/infrastructure/database/models/health_expectation_row.py +35 -0
  134. topicgate-1.5.2/src/topicgate/infrastructure/database/models/history_recording_row.py +25 -0
  135. topicgate-1.5.2/src/topicgate/infrastructure/database/models/history_retention_row.py +34 -0
  136. topicgate-1.5.2/src/topicgate/infrastructure/database/models/observation_event_row.py +37 -0
  137. topicgate-1.5.2/src/topicgate/infrastructure/diagnostic_packs/__init__.py +18 -0
  138. topicgate-1.5.2/src/topicgate/infrastructure/diagnostic_packs/registry.py +22 -0
  139. topicgate-1.5.2/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/__init__.py +16 -0
  140. topicgate-1.5.2/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/diagnostic_pack.py +79 -0
  141. topicgate-1.5.2/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/json_condition.py +55 -0
  142. topicgate-1.5.2/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/loader.py +91 -0
  143. topicgate-1.5.2/src/topicgate/infrastructure/diagnostic_packs/zigbee2mqtt/v1/pack.json +60 -0
  144. topicgate-1.5.2/src/topicgate/infrastructure/health_actions/log_health_action.py +17 -0
  145. topicgate-1.5.2/src/topicgate/infrastructure/health_actions/persist_failure_action.py +11 -0
  146. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/mqtt/callbacks/observer_repository_callbacks.py +3 -1
  147. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/repository/broker_repository.py +18 -0
  148. topicgate-1.5.2/src/topicgate/infrastructure/repository/diagnostic_profile_repository.py +100 -0
  149. topicgate-1.5.2/src/topicgate/infrastructure/repository/expectation_failure_repository.py +74 -0
  150. topicgate-1.5.2/src/topicgate/infrastructure/repository/expectation_state_repository.py +67 -0
  151. topicgate-1.5.2/src/topicgate/infrastructure/repository/health_expectation_repository.py +231 -0
  152. topicgate-1.5.2/src/topicgate/infrastructure/repository/history_recording_repository.py +67 -0
  153. topicgate-1.5.2/src/topicgate/infrastructure/repository/history_retention_repository.py +123 -0
  154. topicgate-1.5.2/src/topicgate/infrastructure/repository/observation_history_repository.py +67 -0
  155. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/repository/observer_mqtt_repository.py +96 -100
  156. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/repository/topic_message_repository.py +292 -87
  157. topicgate-1.5.2/src/topicgate/infrastructure/support_bundle_archive.py +35 -0
  158. topicgate-1.5.2/src/topicgate/mcp/api/broker_api.py +157 -0
  159. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/connection_api.py +2 -2
  160. topicgate-1.5.2/src/topicgate/mcp/api/expectation_api.py +173 -0
  161. topicgate-1.5.2/src/topicgate/mcp/api/health_api.py +133 -0
  162. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/mcp_api.py +0 -2
  163. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/publish_api.py +2 -2
  164. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/snapshot_api.py +4 -1
  165. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/subscription_api.py +7 -5
  166. topicgate-1.5.2/src/topicgate/mcp/api/support_bundle_api.py +49 -0
  167. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/topic_api.py +40 -7
  168. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/middleware/error_handling_middleware.py +5 -0
  169. topicgate-1.5.2/src/topicgate/mcp/requests/broker_creation.py +32 -0
  170. topicgate-1.5.2/src/topicgate/mcp/requests/expectation_requests.py +232 -0
  171. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/server.py +70 -10
  172. topicgate-1.5.2/src/topicgate/presentation/health_presentation.py +229 -0
  173. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/presentation/snapshot_presentation.py +27 -0
  174. topicgate-1.5.2/src/topicgate/presentation/support_bundle_representation.py +395 -0
  175. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/presentation/topic_presentation.py +111 -6
  176. topicgate-1.5.2/src/topicgate/processors/action_dispatcher.py +33 -0
  177. topicgate-1.5.2/src/topicgate/processors/condition_factory.py +80 -0
  178. topicgate-1.5.2/src/topicgate/processors/health_action_registry.py +12 -0
  179. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/processors/observation_retention_processor.py +4 -4
  180. topicgate-1.5.2/src/topicgate/processors/transition_tracker.py +55 -0
  181. topicgate-1.5.2/src/topicgate.egg-info/PKG-INFO +213 -0
  182. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate.egg-info/SOURCES.txt +151 -9
  183. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate.egg-info/entry_points.txt +3 -0
  184. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate.egg-info/requires.txt +1 -0
  185. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_app.py +57 -2
  186. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_app_dependencies.py +8 -2
  187. topicgate-1.5.2/tests/test_broker_config_repository.py +344 -0
  188. topicgate-1.5.2/tests/test_broker_health_evaluation.py +430 -0
  189. topicgate-1.5.2/tests/test_broker_inspection_service.py +69 -0
  190. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_broker_repository_persistence.py +37 -17
  191. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_broker_snapshot_service.py +40 -5
  192. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_dashboard_api.py +28 -16
  193. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_database_migrations.py +117 -1
  194. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_desktop_snapshot_states.py +41 -1
  195. topicgate-1.5.2/tests/test_diagnostic_profiles.py +196 -0
  196. topicgate-1.5.2/tests/test_event_history_gui.py +390 -0
  197. topicgate-1.5.2/tests/test_expectation_management.py +282 -0
  198. topicgate-1.5.2/tests/test_failure_history_service.py +147 -0
  199. topicgate-1.5.2/tests/test_finding_delta_service.py +312 -0
  200. topicgate-1.5.2/tests/test_gui.py +3563 -0
  201. topicgate-1.5.2/tests/test_health_database_models.py +59 -0
  202. topicgate-1.5.2/tests/test_health_expectation.py +144 -0
  203. topicgate-1.5.2/tests/test_health_mappers.py +168 -0
  204. topicgate-1.5.2/tests/test_health_mcp_api.py +124 -0
  205. topicgate-1.5.2/tests/test_health_pipeline.py +462 -0
  206. topicgate-1.5.2/tests/test_health_presentation.py +163 -0
  207. topicgate-1.5.2/tests/test_health_provisioning.py +553 -0
  208. topicgate-1.5.2/tests/test_health_query_service.py +231 -0
  209. topicgate-1.5.2/tests/test_health_report_service.py +100 -0
  210. topicgate-1.5.2/tests/test_health_repositories.py +107 -0
  211. topicgate-1.5.2/tests/test_health_wait_wire.py +103 -0
  212. topicgate-1.5.2/tests/test_history_recording_service.py +239 -0
  213. topicgate-1.5.2/tests/test_history_retention.py +137 -0
  214. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_main_view_model.py +593 -57
  215. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_mcp_apis.py +129 -21
  216. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_mcp_server_instructions.py +7 -0
  217. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_observation_cache_service.py +3 -1
  218. topicgate-1.5.2/tests/test_observation_history_repository.py +132 -0
  219. topicgate-1.5.2/tests/test_observation_query_service.py +76 -0
  220. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_observer_model_hydration.py +10 -22
  221. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_observer_repository.py +130 -44
  222. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_observer_workspace_mapper.py +1 -9
  223. topicgate-1.5.2/tests/test_paths.py +77 -0
  224. topicgate-1.5.2/tests/test_persistence_lifecycle.py +39 -0
  225. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_plugin_bundle.py +31 -1
  226. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_retention_administration.py +5 -2
  227. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_service_container.py +15 -0
  228. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_snapshot_presentation.py +19 -0
  229. topicgate-1.5.2/tests/test_support_bundle.py +545 -0
  230. topicgate-1.5.2/tests/test_support_bundle_mcp_api.py +151 -0
  231. topicgate-1.5.2/tests/test_topic_history_service.py +148 -0
  232. topicgate-1.5.2/tests/test_topic_message_repository.py +748 -0
  233. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_topic_presentation.py +51 -1
  234. topicgate-1.5.2/tests/test_topicgate_cli.py +190 -0
  235. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_topicgate_runtime.py +237 -18
  236. topicgate-1.5.2/tests/test_zigbee2mqtt_diagnostic_pack.py +188 -0
  237. topicgate-1.5.2/tests/test_zigbee2mqtt_scenario.py +120 -0
  238. topicgate-1.2.2/PKG-INFO +0 -236
  239. topicgate-1.2.2/README.md +0 -198
  240. topicgate-1.2.2/src/topicgate/app/app_dependencies.py +0 -148
  241. topicgate-1.2.2/src/topicgate/app/models/__init__.py +0 -1
  242. topicgate-1.2.2/src/topicgate/core/interfaces/topic_message_store.py +0 -13
  243. topicgate-1.2.2/src/topicgate/core/models/message_filter.py +0 -9
  244. topicgate-1.2.2/src/topicgate/core/models/observer_model.py +0 -22
  245. topicgate-1.2.2/src/topicgate/gui/app.py +0 -97
  246. topicgate-1.2.2/src/topicgate/gui/components/application_header.py +0 -137
  247. topicgate-1.2.2/src/topicgate/gui/components/connection_controls.py +0 -123
  248. topicgate-1.2.2/src/topicgate/gui/components/connection_status.py +0 -7
  249. topicgate-1.2.2/src/topicgate/gui/components/observer_tree.py +0 -434
  250. topicgate-1.2.2/src/topicgate/gui/components/publish_pane.py +0 -60
  251. topicgate-1.2.2/src/topicgate/gui/components/topic_details.py +0 -51
  252. topicgate-1.2.2/src/topicgate/gui/components/workspace_pane.py +0 -30
  253. topicgate-1.2.2/src/topicgate/gui/main_view_model.py +0 -814
  254. topicgate-1.2.2/src/topicgate/gui/theme.py +0 -61
  255. topicgate-1.2.2/src/topicgate/infrastructure/database/models/__init__.py +0 -25
  256. topicgate-1.2.2/src/topicgate/mcp/api/broker_api.py +0 -48
  257. topicgate-1.2.2/src/topicgate/processors/observer_model_mqtt_message_processor.py +0 -79
  258. topicgate-1.2.2/src/topicgate/processors/observer_model_processor.py +0 -223
  259. topicgate-1.2.2/src/topicgate.egg-info/PKG-INFO +0 -236
  260. topicgate-1.2.2/tests/test_broker_config_repository.py +0 -162
  261. topicgate-1.2.2/tests/test_gui.py +0 -1225
  262. topicgate-1.2.2/tests/test_observer_model_processor.py +0 -151
  263. topicgate-1.2.2/tests/test_observer_model_service.py +0 -153
  264. topicgate-1.2.2/tests/test_paths.py +0 -20
  265. topicgate-1.2.2/tests/test_persistence_lifecycle.py +0 -17
  266. topicgate-1.2.2/tests/test_topic_message_repository.py +0 -386
  267. {topicgate-1.2.2 → topicgate-1.5.2}/LICENCE +0 -0
  268. {topicgate-1.2.2 → topicgate-1.5.2}/setup.cfg +0 -0
  269. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/__init__.py +0 -0
  270. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/__main__.py +0 -0
  271. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/__init__.py +0 -0
  272. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/models/broker_snapshot.py +0 -0
  273. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/models/mcp_setup.py +0 -0
  274. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/__init__.py +0 -0
  275. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/broker_resolver.py +0 -0
  276. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/observation_retention_policy_service.py +0 -0
  277. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/app/services/service_item.py +0 -0
  278. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/assets/icon.png +0 -0
  279. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/assets/icon.svg +0 -0
  280. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/__init__.py +0 -0
  281. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/config/__init__.py +0 -0
  282. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/config/app_config.py +0 -0
  283. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/config/mqtt_config.py +0 -0
  284. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/interfaces/mqtt_message_processor.py +0 -0
  285. {topicgate-1.2.2/src/topicgate/core/interfaces → topicgate-1.5.2/src/topicgate/core/models}/__init__.py +0 -0
  286. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/broker_profile.py +0 -0
  287. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/broker_profile_identity.py +0 -0
  288. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/broker_summary.py +0 -0
  289. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/connection_status.py +0 -0
  290. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/mqtt_message.py +0 -0
  291. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/mqtt_observation.py +0 -0
  292. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/mqtt_state.py +0 -0
  293. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/observation_cache_administration.py +0 -0
  294. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/observation_deletion_preview.py +0 -0
  295. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/observation_retention_policy.py +0 -0
  296. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/models/subscription.py +0 -0
  297. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/core/payload_limits.py +0 -0
  298. {topicgate-1.2.2/src/topicgate/core/models → topicgate-1.5.2/src/topicgate/gui}/__init__.py +0 -0
  299. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/broker_state_reader.py +0 -0
  300. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/add_subscription_dialog.py +0 -0
  301. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/broker_settings_dialog.py +0 -0
  302. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/components/log_console.py +0 -0
  303. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/gui.py +0 -0
  304. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/gui/settings_migration.py +0 -0
  305. {topicgate-1.2.2/src/topicgate/gui → topicgate-1.5.2/src/topicgate/infrastructure}/__init__.py +0 -0
  306. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/credentials/__init__.py +0 -0
  307. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/credentials/credential_store.py +0 -0
  308. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/credentials/os_credential_store.py +0 -0
  309. {topicgate-1.2.2/src/topicgate/infrastructure → topicgate-1.5.2/src/topicgate/infrastructure/database}/__init__.py +0 -0
  310. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic/README +0 -0
  311. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic/env.py +0 -0
  312. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic/script.py.mako +0 -0
  313. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic/versions/7c3e9f1a2b4d_add_observation_retention_policy.py +0 -0
  314. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic/versions/93fa5748f4b5_initial_revision.py +0 -0
  315. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic/versions/b84d61a9c2e7_rename_retention_database_bytes.py +0 -0
  316. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic/versions/d2a4c6e8f010_add_control_operation_lease.py +0 -0
  317. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic/versions/f1490ca3b908_persist_latest_observed_mqtt_state.py +0 -0
  318. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/alembic.ini +0 -0
  319. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/base.py +0 -0
  320. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/database_context.py +0 -0
  321. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/mappers/broker_profile_mapper.py +0 -0
  322. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/mappers/config_mapper.py +0 -0
  323. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/mappers/mapper_helper.py +0 -0
  324. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/mappers/observation_retention_policy_mapper.py +0 -0
  325. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/mappers/subscription_mapper.py +0 -0
  326. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/models/app_config_row.py +0 -0
  327. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/models/broker_profile_row.py +0 -0
  328. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/models/mqtt_config_row.py +0 -0
  329. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/models/mqtt_message_row.py +0 -0
  330. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/models/observation_retention_policy_row.py +0 -0
  331. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/models/observer_workspace_row.py +0 -0
  332. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/database/models/subscription_row.py +0 -0
  333. {topicgate-1.2.2/src/topicgate/infrastructure/database → topicgate-1.5.2/src/topicgate/infrastructure/mqtt}/__init__.py +0 -0
  334. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/mqtt/async_callback_bridge.py +0 -0
  335. {topicgate-1.2.2/src/topicgate/infrastructure/mqtt → topicgate-1.5.2/src/topicgate/infrastructure/mqtt/callbacks}/__init__.py +0 -0
  336. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/mqtt/callbacks/basic_callbacks.py +0 -0
  337. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/mqtt/mqtt_callbacks.py +0 -0
  338. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/mqtt/mqtt_client.py +0 -0
  339. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/mqtt/mqtt_gate.py +0 -0
  340. {topicgate-1.2.2/src/topicgate/infrastructure/mqtt/callbacks → topicgate-1.5.2/src/topicgate/infrastructure/repository}/__init__.py +0 -0
  341. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/repository/broker_config_repository.py +0 -0
  342. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/repository/observation_retention_policy_repository.py +0 -0
  343. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/infrastructure/repository/subscription_repository.py +0 -0
  344. {topicgate-1.2.2/src/topicgate/infrastructure/repository → topicgate-1.5.2/src/topicgate/mcp}/__init__.py +0 -0
  345. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/dashboard_api.py +0 -0
  346. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/dashboard_snapshot.py +0 -0
  347. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/api/preview/dashboard_preview.py +0 -0
  348. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/capabilities.py +0 -0
  349. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/instructions.py +0 -0
  350. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/middleware/__init__.py +0 -0
  351. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/middleware/logging_middleware.py +0 -0
  352. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/mcp/models.py +0 -0
  353. {topicgate-1.2.2/src/topicgate/mcp → topicgate-1.5.2/src/topicgate/mcp/requests}/__init__.py +0 -0
  354. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/paths.py +0 -0
  355. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/presentation/__init__.py +0 -0
  356. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/presentation/retention_presentation.py +0 -0
  357. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/processors/__init__.py +0 -0
  358. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate/processors/subscription_manager.py +0 -0
  359. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate.egg-info/dependency_links.txt +0 -0
  360. {topicgate-1.2.2 → topicgate-1.5.2}/src/topicgate.egg-info/top_level.txt +0 -0
  361. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_async_callback_bridge.py +0 -0
  362. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_broker_resolver.py +0 -0
  363. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_control_operation_service.py +0 -0
  364. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_dashboard_dependencies.py +0 -0
  365. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_dashboard_preview.py +0 -0
  366. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_github_workflows.py +0 -0
  367. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_mcp_disconnected_startup.py +0 -0
  368. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_mcp_middleware.py +0 -0
  369. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_mcp_setup_service.py +0 -0
  370. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_migrate_app_versions.py +0 -0
  371. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_mqtt_callbacks.py +0 -0
  372. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_mqtt_client.py +0 -0
  373. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_mqtt_message_row.py +0 -0
  374. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_observation_retention_policy.py +0 -0
  375. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_observation_retention_policy_repository.py +0 -0
  376. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_observation_retention_policy_service.py +0 -0
  377. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_os_credential_store.py +0 -0
  378. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_settings_migration.py +0 -0
  379. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_snapshot_mcp_api.py +0 -0
  380. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_subscription.py +0 -0
  381. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_subscription_manager.py +0 -0
  382. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_subscription_mapper.py +0 -0
  383. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_subscription_repository.py +0 -0
  384. {topicgate-1.2.2 → topicgate-1.5.2}/tests/test_verify_distribution.py +0 -0
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: topicgate
3
+ Version: 1.5.2
4
+ Summary: Secure local access to your MQTT topics
5
+ License-Expression: MIT
6
+ Project-URL: Repository, https://github.com/Dumdart/TopicGate
7
+ Project-URL: Documentation, https://github.com/Dumdart/TopicGate/tree/main/docs
8
+ Project-URL: Issue Tracker, https://github.com/Dumdart/TopicGate/issues
9
+ Project-URL: Changelog, https://github.com/Dumdart/TopicGate/releases
10
+ Keywords: mqtt,iot,mcp,model-context-protocol,ai-agent,ai,desktop,windows,automation
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Information Technology
14
+ Classifier: Operating System :: Microsoft :: Windows
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Topic :: Home Automation
17
+ Classifier: Topic :: Internet
18
+ Classifier: Topic :: Software Development
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENCE
23
+ Requires-Dist: paho-mqtt
24
+ Requires-Dist: pyside6
25
+ Requires-Dist: qasync
26
+ Requires-Dist: sqlalchemy
27
+ Requires-Dist: alembic
28
+ Requires-Dist: keyring
29
+ Requires-Dist: fastmcp==3.4.7
30
+ Provides-Extra: apps
31
+ Requires-Dist: fastmcp[apps]==3.4.7; extra == "apps"
32
+ Requires-Dist: prefab-ui==0.20.2; extra == "apps"
33
+ Provides-Extra: test
34
+ Requires-Dist: keyrings.alt; extra == "test"
35
+ Requires-Dist: pytest; extra == "test"
36
+ Requires-Dist: pytest-xdist; extra == "test"
37
+ Requires-Dist: pytest-asyncio; extra == "test"
38
+ Dynamic: license-file
39
+
40
+ # TopicGate
41
+
42
+ <!-- mcp-name: io.github.Dumdart/topicgate -->
43
+
44
+ <p align="center">
45
+ <strong>Observe MQTT state. Define expectations. Check health.</strong><br />
46
+ A desktop MQTT observer and MCP server for people and AI agents.
47
+ </p>
48
+
49
+ <p align="center">
50
+ <img src="docs/images/desktop-observer.png" alt="TopicGate Desktop with a subscription tree, selected temperature payload, and broker health summary using sample data." width="100%" />
51
+ </p>
52
+
53
+ TopicGate stores broker credentials and observed MQTT state locally. Explore topics in Desktop or let an agent inspect them through MCP. In control mode, agents can create broker profiles, configure subscriptions and health expectations, then wait for evidence that the requested checks pass.
54
+
55
+ MCP is read-only by default. Profile creation, connection changes, subscription and expectation changes, fresh health evaluation, live observation, and publishing require control mode.
56
+
57
+ ## Features
58
+
59
+ - Desktop management for broker profiles, credentials, TLS, subscriptions, observations, and publishing.
60
+ - MCP access to broker health, subscriptions, and observed values with freshness and completeness metadata.
61
+ - Broker and topic expectations for connection status, expected values, numeric ranges, presence, absence, and freshness, with recorded failure history.
62
+ - A bounded agent health wait that uses the active connection without reconnecting or publishing test messages.
63
+ - MQTT `+` and `#` filters, multiple profiles, UTF-8/base64 payloads, and SQLite persistence.
64
+ - Password storage through the operating-system credential store; passwords are never exposed through MCP.
65
+ - Redacted, bounded support bundles through Desktop ZIP export or passive MCP JSON/Markdown access.
66
+
67
+ [Watch the demo](https://www.youtube.com/watch?v=_Qtc01kABkg)
68
+
69
+ For repeatable local screenshots, regression checks, and outreach demos without
70
+ physical hardware, use the [Zigbee2MQTT scenario](demo/zigbee2mqtt_scenario/README.md).
71
+
72
+ ## Get started
73
+
74
+ TopicGate requires Python 3.11+ and an MQTT 5-compatible broker.
75
+
76
+ 1. Follow [Install TopicGate by operating system](docs/install/OS_INSTALL.md).
77
+ 2. Run `topicgate-gui`.
78
+ 3. Configure a broker profile and add a bounded filter such as `home/+/temperature` or `devices/#`.
79
+ 4. Add TopicGate to your agent host using one of the [connection guides](#connect-an-agent) below. The host launches the MCP server.
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.
95
+
96
+ ## Connect an agent
97
+
98
+ Configure a broker in TopicGate Desktop for read-only use, or use the authorized [control provisioning and health workflow](docs/install/CONTROL_AND_HEALTH.md).
99
+
100
+ | Host | Guide |
101
+ | --- | --- |
102
+ | Codex | [Codex](docs/install/CODEX.md) |
103
+ | 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
+ | Cursor | [Cursor](docs/install/CURSOR.md) |
106
+
107
+ ## Observation semantics
108
+
109
+ TopicGate snapshots return the latest value it observed and retained, not authoritative broker history.
110
+
111
+ For individual receipts, open **History** in the workspace and use **Record messages**
112
+ for the displayed broker. Recording status appears before Search; enabling or disabling
113
+ recording leaves retention limits and saved receipts unchanged. Recording is off by
114
+ default for every broker. **History** and the read-only `get_topic_history` tool provide
115
+ cursor-paginated receipts with recording and retention limitations. Adjust limits under
116
+ **Stored observations → History settings** independently from latest values; large
117
+ limits may slow startup and queries.
118
+ See [observation history and retention](docs/OBSERVATION_HISTORY.md).
119
+
120
+ - **Live** values arrived in the current observation session.
121
+ - **Cached** or **stored** values came from local persistence.
122
+ - **Stale** values predate the requested observation window.
123
+ - Non-retained values appear only when published while TopicGate is observing.
124
+ - `received_at` records when TopicGate received a message.
125
+
126
+ Only the active broker is continuously connected. Check freshness, provenance, truncation, dropped-message count, and completeness when interpreting a snapshot.
127
+
128
+ Desktop starts with a simplified workspace. **View → Advanced mode** restores
129
+ snapshot diagnostics, storage administration, diagnostic profiles and specialist
130
+ fields. History and recording remain available in both modes. This saved GUI
131
+ preference does not change broker operations or MCP authorization; see the
132
+ [desktop mode matrix](docs/DESKTOP_UX.md#simplified-and-advanced-mode).
133
+
134
+ ## Health expectations
135
+
136
+ Define what healthy means for your broker and topics: an established connection, an expected status payload, a temperature range, or a maximum observation age. Desktop brings broker checks, topic checks, evidence, and failure history into one health view.
137
+
138
+ ![Health overview showing failed and unknown checks with evidence, using sample data.](docs/images/desktop-health.png)
139
+
140
+ *Sample health overview. A connected broker can still have failed or unknown checks; the connection badge alone does not establish health.*
141
+
142
+ Use **Health → Expectations** to browse all rules for the selected broker, with **All / Broker / Topic** scopes. Open a rule to edit it with its target selected, or use **Topic expectations** beside the selected topic. Configure expectations after adding a subscription that covers the topic. See the [desktop workspace guide and UX screenshots](docs/DESKTOP_UX.md).
143
+
144
+ <details>
145
+ <summary>See the broker expectation editor</summary>
146
+
147
+ ![Broker expectation editor with a connection-status condition, enabled setting, and failure-history actions.](docs/images/desktop-expectations.png)
148
+
149
+ *Sample broker expectation configuration.*
150
+
151
+ </details>
152
+
153
+ Health results distinguish **healthy**, **problem**, and **unknown**. A health wait succeeds only with complete evidence for the requested enabled expectations. Missing or stale evidence does not count as success. A retained message proves receipt, not that its publisher is currently alive; topic absence means not observed within TopicGate's scope.
154
+
155
+ ### Let an agent configure and verify health
156
+
157
+ With TopicGate 1.4+ and a control-mode server configured, try:
158
+
159
+ > 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
+
161
+ The agent creates or reuses the profile, activates it once, adds the subscription and expectation, then calls `wait_for_broker_health`. The selected broker remains active. A timeout reports the final available evidence; it does not by itself mean the broker is unhealthy.
162
+
163
+ Anonymous profile creation works through MCP. Profiles needing a password return `needs_credentials`; complete credential setup in Desktop before continuing. MCP accepts neither raw passwords nor credential references.
164
+
165
+ See [Control mode and expectation verification](docs/install/CONTROL_AND_HEALTH.md) for setup, exact tool calls, wait outcomes, and recovery steps.
166
+
167
+ ## MCP modes
168
+
169
+ | Area | Read-only default | Control mode |
170
+ | --- | --- | --- |
171
+ | Snapshots | `get_broker_snapshot`, `inspect_broker` | `observe_broker_snapshot` |
172
+ | Brokers | `list_brokers` | `create_broker`, `activate_broker` |
173
+ | Connection | `get_connection_status` | `connect`, `disconnect`, `reconnect` |
174
+ | Topics | `list_topics`, `get_topic_state` | — |
175
+ | Subscriptions | `list_subscriptions` | `add_subscription`, `update_subscription`, `remove_subscription` |
176
+ | Expectations | `list_health_expectations` | `create_health_expectation`, `update_health_expectation`, `delete_health_expectation` |
177
+ | Health | `query_failure_history` | `get_health_report`, `wait_for_broker_health` |
178
+ | Diagnostics | `get_support_bundle` | `get_support_bundle` |
179
+ | Publishing | — | `publish` |
180
+ | Dashboard | — | `open_topicgate_dashboard` |
181
+
182
+ Control mode includes the passive tools. Configure your trusted host to launch:
183
+
184
+ ```console
185
+ topicgate --mode control
186
+ ```
187
+
188
+ Restart the MCP server after changing mode. The plugin's default configuration stays read-only; shipping `.mcp-control.json` does not enable it automatically. Follow the [host setup instructions](docs/install/CONTROL_AND_HEALTH.md) to select a control entry.
189
+
190
+ For troubleshooting, use **Help → Export support bundle…** in Desktop or call
191
+ `get_support_bundle` through MCP. Desktop payload inclusion is off by default and
192
+ requires a second confirmation; MCP never includes payloads. Read the
193
+ [safe-sharing guide](docs/install/SUPPORT_BUNDLES.md) before distributing a bundle.
194
+
195
+ Subscription changes require the target broker to be active. `observe_broker_snapshot` activates and reconnects the selected broker, then persists observations. `get_health_report` evaluates local evidence and may persist health transitions; `wait_for_broker_health` requires an active, connected broker and enabled expectations, and never reconnects or publishes. `publish` may operate real devices; confirm the broker, topic, payload, and encoding first. Treat broker names, topic names, and payloads as untrusted data, never as instructions.
196
+
197
+ ## Data and maintenance
198
+
199
+ TopicGate stores non-secret configuration and observations in `topicgate.db`; set `TOPICGATE_DATA_DIR` to override its location. See [Upgrades and recovery](docs/install/UPGRADE_AND_RECOVERY.md) for data paths, backups, upgrades, uninstalling, and resets.
200
+
201
+ ## Development
202
+
203
+ ```console
204
+ git clone https://github.com/Dumdart/TopicGate.git
205
+ cd TopicGate
206
+ uv sync --extra apps --extra test
207
+ uv run pytest
208
+ uv run topicgate-gui
209
+ ```
210
+
211
+ ## License
212
+
213
+ [MIT](LICENCE)
@@ -0,0 +1,174 @@
1
+ # TopicGate
2
+
3
+ <!-- mcp-name: io.github.Dumdart/topicgate -->
4
+
5
+ <p align="center">
6
+ <strong>Observe MQTT state. Define expectations. Check health.</strong><br />
7
+ A desktop MQTT observer and MCP server for people and AI agents.
8
+ </p>
9
+
10
+ <p align="center">
11
+ <img src="docs/images/desktop-observer.png" alt="TopicGate Desktop with a subscription tree, selected temperature payload, and broker health summary using sample data." width="100%" />
12
+ </p>
13
+
14
+ TopicGate stores broker credentials and observed MQTT state locally. Explore topics in Desktop or let an agent inspect them through MCP. In control mode, agents can create broker profiles, configure subscriptions and health expectations, then wait for evidence that the requested checks pass.
15
+
16
+ MCP is read-only by default. Profile creation, connection changes, subscription and expectation changes, fresh health evaluation, live observation, and publishing require control mode.
17
+
18
+ ## Features
19
+
20
+ - Desktop management for broker profiles, credentials, TLS, subscriptions, observations, and publishing.
21
+ - MCP access to broker health, subscriptions, and observed values with freshness and completeness metadata.
22
+ - Broker and topic expectations for connection status, expected values, numeric ranges, presence, absence, and freshness, with recorded failure history.
23
+ - A bounded agent health wait that uses the active connection without reconnecting or publishing test messages.
24
+ - MQTT `+` and `#` filters, multiple profiles, UTF-8/base64 payloads, and SQLite persistence.
25
+ - Password storage through the operating-system credential store; passwords are never exposed through MCP.
26
+ - Redacted, bounded support bundles through Desktop ZIP export or passive MCP JSON/Markdown access.
27
+
28
+ [Watch the demo](https://www.youtube.com/watch?v=_Qtc01kABkg)
29
+
30
+ For repeatable local screenshots, regression checks, and outreach demos without
31
+ physical hardware, use the [Zigbee2MQTT scenario](demo/zigbee2mqtt_scenario/README.md).
32
+
33
+ ## Get started
34
+
35
+ TopicGate requires Python 3.11+ and an MQTT 5-compatible broker.
36
+
37
+ 1. Follow [Install TopicGate by operating system](docs/install/OS_INSTALL.md).
38
+ 2. Run `topicgate-gui`.
39
+ 3. Configure a broker profile and add a bounded filter such as `home/+/temperature` or `devices/#`.
40
+ 4. Add TopicGate to your agent host using one of the [connection guides](#connect-an-agent) below. The host launches the MCP server.
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.
56
+
57
+ ## Connect an agent
58
+
59
+ Configure a broker in TopicGate Desktop for read-only use, or use the authorized [control provisioning and health workflow](docs/install/CONTROL_AND_HEALTH.md).
60
+
61
+ | Host | Guide |
62
+ | --- | --- |
63
+ | Codex | [Codex](docs/install/CODEX.md) |
64
+ | 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
+ | Cursor | [Cursor](docs/install/CURSOR.md) |
67
+
68
+ ## Observation semantics
69
+
70
+ TopicGate snapshots return the latest value it observed and retained, not authoritative broker history.
71
+
72
+ For individual receipts, open **History** in the workspace and use **Record messages**
73
+ for the displayed broker. Recording status appears before Search; enabling or disabling
74
+ recording leaves retention limits and saved receipts unchanged. Recording is off by
75
+ default for every broker. **History** and the read-only `get_topic_history` tool provide
76
+ cursor-paginated receipts with recording and retention limitations. Adjust limits under
77
+ **Stored observations → History settings** independently from latest values; large
78
+ limits may slow startup and queries.
79
+ See [observation history and retention](docs/OBSERVATION_HISTORY.md).
80
+
81
+ - **Live** values arrived in the current observation session.
82
+ - **Cached** or **stored** values came from local persistence.
83
+ - **Stale** values predate the requested observation window.
84
+ - Non-retained values appear only when published while TopicGate is observing.
85
+ - `received_at` records when TopicGate received a message.
86
+
87
+ Only the active broker is continuously connected. Check freshness, provenance, truncation, dropped-message count, and completeness when interpreting a snapshot.
88
+
89
+ Desktop starts with a simplified workspace. **View → Advanced mode** restores
90
+ snapshot diagnostics, storage administration, diagnostic profiles and specialist
91
+ fields. History and recording remain available in both modes. This saved GUI
92
+ preference does not change broker operations or MCP authorization; see the
93
+ [desktop mode matrix](docs/DESKTOP_UX.md#simplified-and-advanced-mode).
94
+
95
+ ## Health expectations
96
+
97
+ Define what healthy means for your broker and topics: an established connection, an expected status payload, a temperature range, or a maximum observation age. Desktop brings broker checks, topic checks, evidence, and failure history into one health view.
98
+
99
+ ![Health overview showing failed and unknown checks with evidence, using sample data.](docs/images/desktop-health.png)
100
+
101
+ *Sample health overview. A connected broker can still have failed or unknown checks; the connection badge alone does not establish health.*
102
+
103
+ Use **Health → Expectations** to browse all rules for the selected broker, with **All / Broker / Topic** scopes. Open a rule to edit it with its target selected, or use **Topic expectations** beside the selected topic. Configure expectations after adding a subscription that covers the topic. See the [desktop workspace guide and UX screenshots](docs/DESKTOP_UX.md).
104
+
105
+ <details>
106
+ <summary>See the broker expectation editor</summary>
107
+
108
+ ![Broker expectation editor with a connection-status condition, enabled setting, and failure-history actions.](docs/images/desktop-expectations.png)
109
+
110
+ *Sample broker expectation configuration.*
111
+
112
+ </details>
113
+
114
+ Health results distinguish **healthy**, **problem**, and **unknown**. A health wait succeeds only with complete evidence for the requested enabled expectations. Missing or stale evidence does not count as success. A retained message proves receipt, not that its publisher is currently alive; topic absence means not observed within TopicGate's scope.
115
+
116
+ ### Let an agent configure and verify health
117
+
118
+ With TopicGate 1.4+ and a control-mode server configured, try:
119
+
120
+ > 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
+
122
+ The agent creates or reuses the profile, activates it once, adds the subscription and expectation, then calls `wait_for_broker_health`. The selected broker remains active. A timeout reports the final available evidence; it does not by itself mean the broker is unhealthy.
123
+
124
+ Anonymous profile creation works through MCP. Profiles needing a password return `needs_credentials`; complete credential setup in Desktop before continuing. MCP accepts neither raw passwords nor credential references.
125
+
126
+ See [Control mode and expectation verification](docs/install/CONTROL_AND_HEALTH.md) for setup, exact tool calls, wait outcomes, and recovery steps.
127
+
128
+ ## MCP modes
129
+
130
+ | Area | Read-only default | Control mode |
131
+ | --- | --- | --- |
132
+ | Snapshots | `get_broker_snapshot`, `inspect_broker` | `observe_broker_snapshot` |
133
+ | Brokers | `list_brokers` | `create_broker`, `activate_broker` |
134
+ | Connection | `get_connection_status` | `connect`, `disconnect`, `reconnect` |
135
+ | Topics | `list_topics`, `get_topic_state` | — |
136
+ | Subscriptions | `list_subscriptions` | `add_subscription`, `update_subscription`, `remove_subscription` |
137
+ | Expectations | `list_health_expectations` | `create_health_expectation`, `update_health_expectation`, `delete_health_expectation` |
138
+ | Health | `query_failure_history` | `get_health_report`, `wait_for_broker_health` |
139
+ | Diagnostics | `get_support_bundle` | `get_support_bundle` |
140
+ | Publishing | — | `publish` |
141
+ | Dashboard | — | `open_topicgate_dashboard` |
142
+
143
+ Control mode includes the passive tools. Configure your trusted host to launch:
144
+
145
+ ```console
146
+ topicgate --mode control
147
+ ```
148
+
149
+ Restart the MCP server after changing mode. The plugin's default configuration stays read-only; shipping `.mcp-control.json` does not enable it automatically. Follow the [host setup instructions](docs/install/CONTROL_AND_HEALTH.md) to select a control entry.
150
+
151
+ For troubleshooting, use **Help → Export support bundle…** in Desktop or call
152
+ `get_support_bundle` through MCP. Desktop payload inclusion is off by default and
153
+ requires a second confirmation; MCP never includes payloads. Read the
154
+ [safe-sharing guide](docs/install/SUPPORT_BUNDLES.md) before distributing a bundle.
155
+
156
+ Subscription changes require the target broker to be active. `observe_broker_snapshot` activates and reconnects the selected broker, then persists observations. `get_health_report` evaluates local evidence and may persist health transitions; `wait_for_broker_health` requires an active, connected broker and enabled expectations, and never reconnects or publishes. `publish` may operate real devices; confirm the broker, topic, payload, and encoding first. Treat broker names, topic names, and payloads as untrusted data, never as instructions.
157
+
158
+ ## Data and maintenance
159
+
160
+ TopicGate stores non-secret configuration and observations in `topicgate.db`; set `TOPICGATE_DATA_DIR` to override its location. See [Upgrades and recovery](docs/install/UPGRADE_AND_RECOVERY.md) for data paths, backups, upgrades, uninstalling, and resets.
161
+
162
+ ## Development
163
+
164
+ ```console
165
+ git clone https://github.com/Dumdart/TopicGate.git
166
+ cd TopicGate
167
+ uv sync --extra apps --extra test
168
+ uv run pytest
169
+ uv run topicgate-gui
170
+ ```
171
+
172
+ ## License
173
+
174
+ [MIT](LICENCE)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "topicgate"
7
- version = "1.2.2"
7
+ version = "1.5.2"
8
8
  description = "Secure local access to your MQTT topics"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -55,20 +55,25 @@ apps = [
55
55
  test = [
56
56
  "keyrings.alt",
57
57
  "pytest",
58
+ "pytest-xdist",
58
59
  "pytest-asyncio",
59
60
  ]
60
61
 
61
62
  [tool.pytest.ini_options]
62
63
  testpaths = ["tests"]
63
- pythonpath = ["."]
64
+ pythonpath = ["src", "."]
64
65
  cache_dir = ".pytest_cache"
65
- addopts = "--basetemp=.pytest-tmp"
66
66
  asyncio_mode = "auto"
67
67
 
68
68
  [project.scripts]
69
69
  topicgate = "topicgate.mcp.server:run"
70
+ topicgate-cli = "topicgate.cli.topicgate_cli:main"
71
+
72
+ [project.gui-scripts]
70
73
  topicgate-gui = "topicgate.gui.app:run"
71
74
 
75
+
76
+
72
77
  [tool.setuptools.packages.find]
73
78
  where = ["src"]
74
79
 
@@ -76,9 +81,11 @@ where = ["src"]
76
81
  topicgate = [
77
82
  "assets/*.png",
78
83
  "assets/*.svg",
84
+ "assets/icons/*.svg",
79
85
  "infrastructure/database/alembic.ini",
80
86
  "infrastructure/database/alembic/*.py",
81
87
  "infrastructure/database/alembic/*.mako",
82
88
  "infrastructure/database/alembic/README",
83
89
  "infrastructure/database/alembic/versions/*.py",
90
+ "infrastructure/diagnostic_packs/zigbee2mqtt/v1/*.json",
84
91
  ]