meshcode 2.10.94__tar.gz → 2.10.95__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.
- {meshcode-2.10.94 → meshcode-2.10.95}/PKG-INFO +1 -1
- meshcode-2.10.95/meshcode/__init__.py +82 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/meshcode_mcp/backend.py +92 -16
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/meshcode_mcp/server.py +52 -19
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode.egg-info/PKG-INFO +1 -1
- meshcode-2.10.95/meshcode.egg-info/PKG-INFO 2 +446 -0
- meshcode-2.10.95/meshcode.egg-info/SOURCES.txt +204 -0
- meshcode-2.10.95/meshcode.egg-info/dependency_links.txt +1 -0
- meshcode-2.10.95/meshcode.egg-info/entry_points.txt +3 -0
- meshcode-2.10.95/meshcode.egg-info/requires.txt +5 -0
- meshcode-2.10.95/meshcode.egg-info/top_level.txt +4 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/pyproject.toml +1 -1
- meshcode-2.10.94/meshcode/__init__.py +0 -82
- {meshcode-2.10.94 → meshcode-2.10.95}/README.md +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/ascii_art.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/cli.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/comms_v4.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/compat.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/error_hints.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/invites.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/launcher.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/launcher_install.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/preferences.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/quickstart.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/run_agent.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/secrets.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/self_update.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/setup_clients.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/supervisor.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode/upload.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/comms_v4.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/ascii_art.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/cli.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/comms_v4.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/compat.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/error_hints.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/invites.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/launcher.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/launcher_install.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/preferences.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/protocol_v2.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/quickstart.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/run_agent.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/secrets.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/self_update.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/setup_clients.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/supervisor.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/meshcode/upload.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/scripts/sentinel.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_core.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_migration_integrity.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_security_regressions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_sentinel.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-backend-wt/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/ascii_art.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/cli.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/comms_v4.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/compat.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/error_hints.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/invites.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/launcher.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/launcher_install.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/preferences.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/protocol_v2.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/quickstart.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/run_agent.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/secrets.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/self_update.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/setup_clients.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/supervisor.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/build/lib/meshcode/upload.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/comms_v4.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/ascii_art.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/cli.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/comms_v4.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/compat.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/error_hints.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/invites.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/launcher.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/launcher_install.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/preferences.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/protocol_v2.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/quickstart.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/run_agent.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/secrets.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/self_update.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/setup_clients.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/supervisor.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/meshcode/upload.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/scripts/sentinel.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_core.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_migration_integrity.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_security_regressions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_sentinel.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-noun-wt/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/comms_v4.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/ascii_art.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/cli.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/comms_v4.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/compat.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/error_hints.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/invites.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/launcher.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/launcher_install.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/preferences.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/protocol_v2.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/quickstart.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/run_agent.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/secrets.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/self_update.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/setup_clients.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/supervisor.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/meshcode/upload.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/scripts/sentinel.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_core.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_migration_integrity.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_security_regressions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_sentinel.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/meshcode-tasks-wt/tests/test_status_enum_coverage.py +0 -0
- /meshcode-2.10.94/meshcode.egg-info/SOURCES.txt → /meshcode-2.10.95/meshcode.egg-info/SOURCES 2.txt +0 -0
- /meshcode-2.10.94/meshcode.egg-info/dependency_links.txt → /meshcode-2.10.95/meshcode.egg-info/dependency_links 2.txt +0 -0
- /meshcode-2.10.94/meshcode.egg-info/entry_points.txt → /meshcode-2.10.95/meshcode.egg-info/entry_points 2.txt +0 -0
- /meshcode-2.10.94/meshcode.egg-info/requires.txt → /meshcode-2.10.95/meshcode.egg-info/requires 2.txt +0 -0
- /meshcode-2.10.94/meshcode.egg-info/top_level.txt → /meshcode-2.10.95/meshcode.egg-info/top_level 2.txt +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/setup.cfg +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_auto_update_hardening.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_core.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_exceptions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_migration_integrity.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_security_regressions.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_sentinel.py +0 -0
- {meshcode-2.10.94 → meshcode-2.10.95}/tests/test_status_enum_coverage.py +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""MeshCode — Real-time communication between AI agents."""
|
|
2
|
+
__version__ = "2.10.95"
|
|
3
|
+
|
|
4
|
+
# Exception hierarchy — eagerly imported (lightweight, no deps)
|
|
5
|
+
from meshcode.exceptions import ( # noqa: F401
|
|
6
|
+
MeshCodeError,
|
|
7
|
+
AuthError,
|
|
8
|
+
RPCError,
|
|
9
|
+
MeshCodeTimeoutError,
|
|
10
|
+
MeshCodeConnectionError,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# Public API — lazy imports to avoid heavy deps at import time
|
|
14
|
+
def __getattr__(name):
|
|
15
|
+
if name == "backend":
|
|
16
|
+
from meshcode.meshcode_mcp import backend
|
|
17
|
+
return backend
|
|
18
|
+
if name in _BACKEND_EXPORTS:
|
|
19
|
+
from meshcode.meshcode_mcp import backend
|
|
20
|
+
return getattr(backend, name)
|
|
21
|
+
if name in _SECRETS_EXPORTS:
|
|
22
|
+
from meshcode import secrets
|
|
23
|
+
return getattr(secrets, name)
|
|
24
|
+
raise AttributeError(f"module 'meshcode' has no attribute {name!r}")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Backend: core messaging & agent management
|
|
28
|
+
_BACKEND_EXPORTS = {
|
|
29
|
+
"send_message",
|
|
30
|
+
"read_inbox",
|
|
31
|
+
"count_pending",
|
|
32
|
+
"get_board",
|
|
33
|
+
"heartbeat",
|
|
34
|
+
"set_status",
|
|
35
|
+
"register_agent",
|
|
36
|
+
"get_project_id",
|
|
37
|
+
"sb_rpc",
|
|
38
|
+
"task_create",
|
|
39
|
+
"task_list",
|
|
40
|
+
"encrypt_payload",
|
|
41
|
+
"decrypt_payload",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Secrets: credential management
|
|
45
|
+
_SECRETS_EXPORTS = {
|
|
46
|
+
"get_api_key",
|
|
47
|
+
"set_api_key",
|
|
48
|
+
"list_profiles",
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
__all__ = [
|
|
52
|
+
"__version__",
|
|
53
|
+
"backend",
|
|
54
|
+
# Exceptions
|
|
55
|
+
"MeshCodeError",
|
|
56
|
+
"AuthError",
|
|
57
|
+
"RPCError",
|
|
58
|
+
"MeshCodeTimeoutError",
|
|
59
|
+
"MeshCodeConnectionError",
|
|
60
|
+
# Messaging
|
|
61
|
+
"send_message",
|
|
62
|
+
"read_inbox",
|
|
63
|
+
"count_pending",
|
|
64
|
+
# Agent management
|
|
65
|
+
"register_agent",
|
|
66
|
+
"get_project_id",
|
|
67
|
+
"get_board",
|
|
68
|
+
"heartbeat",
|
|
69
|
+
"set_status",
|
|
70
|
+
# Tasks
|
|
71
|
+
"task_create",
|
|
72
|
+
"task_list",
|
|
73
|
+
# Low-level
|
|
74
|
+
"sb_rpc",
|
|
75
|
+
# Encryption
|
|
76
|
+
"encrypt_payload",
|
|
77
|
+
"decrypt_payload",
|
|
78
|
+
# Credentials
|
|
79
|
+
"get_api_key",
|
|
80
|
+
"set_api_key",
|
|
81
|
+
"list_profiles",
|
|
82
|
+
]
|
|
@@ -826,14 +826,29 @@ def read_inbox(project_id: str, agent: str, mark_read: bool = True, api_key: Opt
|
|
|
826
826
|
for m in messages:
|
|
827
827
|
p = m.get("payload")
|
|
828
828
|
if isinstance(p, dict) and "_encrypted" in p:
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
829
|
+
msg_aad = p.get("_aad", project_id)
|
|
830
|
+
from_project_marker = p.get("_from_project")
|
|
831
|
+
decrypted = None
|
|
832
|
+
# Cross-mesh: payload tagged with sender's project.
|
|
833
|
+
# Fetch per-link shared key (NOT local mesh key).
|
|
834
|
+
if from_project_marker and from_project_marker != project_id:
|
|
835
|
+
link_key = get_link_shared_key(api_key, project_id, from_project_marker)
|
|
836
|
+
if link_key:
|
|
837
|
+
decrypted = decrypt_payload(p["_encrypted"], link_key, aad=msg_aad)
|
|
838
|
+
# Decrypt fail → key rotation; refetch once.
|
|
839
|
+
if decrypted is None:
|
|
840
|
+
link_key = get_link_shared_key(api_key, project_id, from_project_marker, bypass_cache=True)
|
|
841
|
+
if link_key:
|
|
842
|
+
decrypted = decrypt_payload(p["_encrypted"], link_key, aad=msg_aad)
|
|
843
|
+
# In-mesh OR no _from_project marker (legacy): local key.
|
|
844
|
+
if decrypted is None:
|
|
845
|
+
if mesh_key is None:
|
|
846
|
+
mesh_key = get_mesh_key(api_key, project_id)
|
|
847
|
+
if mesh_key:
|
|
848
|
+
decrypted = decrypt_payload(p["_encrypted"], mesh_key, aad=msg_aad)
|
|
849
|
+
if decrypted is not None:
|
|
850
|
+
m["payload"] = decrypted
|
|
851
|
+
m["_was_encrypted"] = True
|
|
837
852
|
if mark_read and messages:
|
|
838
853
|
import datetime as _dt
|
|
839
854
|
now = _dt.datetime.now(_dt.timezone.utc)
|
|
@@ -872,14 +887,25 @@ def read_inbox(project_id: str, agent: str, mark_read: bool = True, api_key: Opt
|
|
|
872
887
|
for m in messages:
|
|
873
888
|
p = m.get("payload")
|
|
874
889
|
if isinstance(p, dict) and "_encrypted" in p:
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
if
|
|
881
|
-
|
|
882
|
-
|
|
890
|
+
msg_aad = p.get("_aad", project_id)
|
|
891
|
+
from_project_marker = p.get("_from_project")
|
|
892
|
+
decrypted = None
|
|
893
|
+
if from_project_marker and from_project_marker != project_id:
|
|
894
|
+
link_key = get_link_shared_key(api_key, project_id, from_project_marker)
|
|
895
|
+
if link_key:
|
|
896
|
+
decrypted = decrypt_payload(p["_encrypted"], link_key, aad=msg_aad)
|
|
897
|
+
if decrypted is None:
|
|
898
|
+
link_key = get_link_shared_key(api_key, project_id, from_project_marker, bypass_cache=True)
|
|
899
|
+
if link_key:
|
|
900
|
+
decrypted = decrypt_payload(p["_encrypted"], link_key, aad=msg_aad)
|
|
901
|
+
if decrypted is None:
|
|
902
|
+
if mesh_key is None:
|
|
903
|
+
mesh_key = get_mesh_key(api_key, project_id)
|
|
904
|
+
if mesh_key:
|
|
905
|
+
decrypted = decrypt_payload(p["_encrypted"], mesh_key, aad=msg_aad)
|
|
906
|
+
if decrypted is not None:
|
|
907
|
+
m["payload"] = decrypted
|
|
908
|
+
m["_was_encrypted"] = True
|
|
883
909
|
if mark_read and messages:
|
|
884
910
|
for m in messages:
|
|
885
911
|
marked = False
|
|
@@ -983,6 +1009,56 @@ def get_mesh_key(api_key: str, project_id: str) -> Optional[str]:
|
|
|
983
1009
|
return None
|
|
984
1010
|
|
|
985
1011
|
|
|
1012
|
+
# Per-link shared key cache (cross-mesh encrypted msgs). Keyed by
|
|
1013
|
+
# (my_project, other_project) tuple. Populated on demand when an encrypted
|
|
1014
|
+
# cross-mesh message arrives. Cache invalidates on decrypt failure (rotation).
|
|
1015
|
+
_link_key_cache: Dict[tuple, tuple] = {} # (my_proj, other_proj) -> (hex_key, expiry_ts)
|
|
1016
|
+
_LINK_KEY_CACHE_TTL = 600
|
|
1017
|
+
_LINK_KEY_CACHE_MAX = 64
|
|
1018
|
+
|
|
1019
|
+
|
|
1020
|
+
def get_link_shared_key(api_key: str, my_project: str, other_project: str,
|
|
1021
|
+
bypass_cache: bool = False) -> Optional[str]:
|
|
1022
|
+
"""Retrieve the per-link symmetric encryption key (hex-encoded AES-256).
|
|
1023
|
+
|
|
1024
|
+
Used for cross-mesh encrypted messages — backend `mc_get_link_shared_key`
|
|
1025
|
+
returns a key SHARED by both ends of the link, so encrypt-on-sender +
|
|
1026
|
+
decrypt-on-recipient roundtrips cleanly. `my_project` and `other_project`
|
|
1027
|
+
accept either project name OR project_id; the RPC resolves both.
|
|
1028
|
+
|
|
1029
|
+
Set `bypass_cache=True` after a decrypt failure to handle key rotation
|
|
1030
|
+
(`mc_rotate_link_shared_key`).
|
|
1031
|
+
"""
|
|
1032
|
+
cache_key = (my_project, other_project)
|
|
1033
|
+
if not bypass_cache:
|
|
1034
|
+
entry = _link_key_cache.get(cache_key)
|
|
1035
|
+
if entry and entry[1] > _time.time():
|
|
1036
|
+
return entry[0]
|
|
1037
|
+
_link_key_cache.pop(cache_key, None)
|
|
1038
|
+
result = sb_rpc("mc_get_link_shared_key", {
|
|
1039
|
+
"p_api_key": api_key,
|
|
1040
|
+
"p_my_project": my_project,
|
|
1041
|
+
"p_other_project": other_project,
|
|
1042
|
+
})
|
|
1043
|
+
if isinstance(result, dict) and result.get("ok"):
|
|
1044
|
+
try:
|
|
1045
|
+
import base64 as _b64
|
|
1046
|
+
hex_key = _b64.b64decode(result["shared_encryption_key_b64"]).hex()
|
|
1047
|
+
except Exception:
|
|
1048
|
+
return None
|
|
1049
|
+
if len(_link_key_cache) >= _LINK_KEY_CACHE_MAX:
|
|
1050
|
+
now = _time.time()
|
|
1051
|
+
expired = [k for k, v in _link_key_cache.items() if v[1] <= now]
|
|
1052
|
+
for k in expired:
|
|
1053
|
+
del _link_key_cache[k]
|
|
1054
|
+
if len(_link_key_cache) >= _LINK_KEY_CACHE_MAX:
|
|
1055
|
+
oldest = min(_link_key_cache, key=lambda k: _link_key_cache[k][1])
|
|
1056
|
+
del _link_key_cache[oldest]
|
|
1057
|
+
_link_key_cache[cache_key] = (hex_key, _time.time() + _LINK_KEY_CACHE_TTL)
|
|
1058
|
+
return hex_key
|
|
1059
|
+
return None
|
|
1060
|
+
|
|
1061
|
+
|
|
986
1062
|
def encrypt_payload(payload: Dict, hex_key: str, aad: Optional[str] = None) -> str:
|
|
987
1063
|
"""Encrypt a JSON payload using AES-256-GCM with optional AAD.
|
|
988
1064
|
|
|
@@ -2006,23 +2006,36 @@ def meshcode_send(to: str, message: Any, in_reply_to: Optional[str] = None,
|
|
|
2006
2006
|
return {"error": "sensitive messages must use encrypted=True for cross-mesh"}
|
|
2007
2007
|
api_key = _get_api_key()
|
|
2008
2008
|
|
|
2009
|
-
#
|
|
2010
|
-
#
|
|
2011
|
-
#
|
|
2009
|
+
# Cross-mesh encryption: per-link symmetric AES-256-GCM key (backend
|
|
2010
|
+
# commit cc6a988 / mig 2026-05-04). Old `mc_get_cross_mesh_key`
|
|
2011
|
+
# returned target's per-mesh key, which empirically failed to decrypt
|
|
2012
|
+
# on recipient (incident 2026-05-04 chief@mesh-dev). New
|
|
2013
|
+
# `mc_get_link_shared_key` returns a key SHARED by sender + recipient
|
|
2014
|
+
# via the link record — both sides resolve to the same bytes, so
|
|
2015
|
+
# encryption roundtrips cleanly. Tag payload with _from_project so the
|
|
2016
|
+
# recipient knows to fetch the link key (not its local mesh key) on
|
|
2017
|
+
# decrypt.
|
|
2012
2018
|
if encrypted:
|
|
2013
|
-
key_result = be.sb_rpc("
|
|
2019
|
+
key_result = be.sb_rpc("mc_get_link_shared_key", {
|
|
2014
2020
|
"p_api_key": api_key,
|
|
2015
|
-
"
|
|
2016
|
-
"
|
|
2017
|
-
"p_agent_name": AGENT_NAME,
|
|
2021
|
+
"p_my_project": PROJECT_NAME,
|
|
2022
|
+
"p_other_project": target_meshwork,
|
|
2018
2023
|
})
|
|
2019
2024
|
if not isinstance(key_result, dict) or not key_result.get("ok"):
|
|
2020
|
-
err = key_result.get("error", "unknown") if isinstance(key_result, dict) else "RPC failed"
|
|
2025
|
+
err = key_result.get("error_code") or key_result.get("error", "unknown") if isinstance(key_result, dict) else "RPC failed"
|
|
2021
2026
|
return {"error": f"cross-mesh encryption failed: {err}"}
|
|
2022
|
-
|
|
2027
|
+
link_key_b64 = key_result["shared_encryption_key_b64"]
|
|
2028
|
+
link_id = key_result.get("link_id", "")
|
|
2023
2029
|
tgt_project_id = key_result.get("target_project_id", "")
|
|
2024
|
-
|
|
2025
|
-
|
|
2030
|
+
import base64 as _b64
|
|
2031
|
+
link_key_hex = _b64.b64decode(link_key_b64).hex()
|
|
2032
|
+
encrypted_data = be.encrypt_payload(payload, link_key_hex, aad=link_id or tgt_project_id)
|
|
2033
|
+
payload = {
|
|
2034
|
+
"_encrypted": encrypted_data,
|
|
2035
|
+
"_aad": link_id or tgt_project_id,
|
|
2036
|
+
"_from_project": PROJECT_NAME,
|
|
2037
|
+
"_link_id": link_id,
|
|
2038
|
+
}
|
|
2026
2039
|
|
|
2027
2040
|
result = be.sb_rpc("mc_send_cross_mesh", {
|
|
2028
2041
|
"p_api_key": api_key,
|
|
@@ -2688,20 +2701,40 @@ def _mark_realtime_msgs_read_in_db(messages: List[Dict[str, Any]]) -> None:
|
|
|
2688
2701
|
async def _meshcode_wait_inner(actual_timeout: int, include_acks: bool) -> Dict[str, Any]:
|
|
2689
2702
|
|
|
2690
2703
|
def _return_from_buffered(buffered: List[Dict[str, Any]]) -> Optional[Dict[str, Any]]:
|
|
2691
|
-
# Auto-decrypt encrypted payloads
|
|
2704
|
+
# Auto-decrypt encrypted payloads. Cross-mesh msgs carry _from_project
|
|
2705
|
+
# marker → use per-link shared key. In-mesh → local mesh key.
|
|
2692
2706
|
_mesh_key = None
|
|
2707
|
+
_api_key = _get_api_key()
|
|
2693
2708
|
for msg in buffered:
|
|
2694
2709
|
p = msg.get("payload")
|
|
2695
2710
|
if isinstance(p, dict) and "_encrypted" in p:
|
|
2696
|
-
|
|
2711
|
+
_msg_aad = p.get("_aad", PROJECT_NAME)
|
|
2712
|
+
_from_proj = p.get("_from_project")
|
|
2713
|
+
_decrypted = None
|
|
2714
|
+
if _from_proj and _from_proj != PROJECT_NAME:
|
|
2697
2715
|
try:
|
|
2698
|
-
|
|
2716
|
+
_link_key = be.get_link_shared_key(_api_key, PROJECT_NAME, _from_proj)
|
|
2717
|
+
if _link_key:
|
|
2718
|
+
_decrypted = be.decrypt_payload(p["_encrypted"], _link_key, aad=_msg_aad)
|
|
2719
|
+
if _decrypted is None:
|
|
2720
|
+
_link_key = be.get_link_shared_key(_api_key, PROJECT_NAME, _from_proj, bypass_cache=True)
|
|
2721
|
+
if _link_key:
|
|
2722
|
+
_decrypted = be.decrypt_payload(p["_encrypted"], _link_key, aad=_msg_aad)
|
|
2699
2723
|
except Exception:
|
|
2700
|
-
|
|
2701
|
-
if
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2724
|
+
pass
|
|
2725
|
+
if _decrypted is None:
|
|
2726
|
+
if _mesh_key is None:
|
|
2727
|
+
try:
|
|
2728
|
+
_mesh_key = be.get_mesh_key(_api_key, _PROJECT_ID) or ""
|
|
2729
|
+
except Exception:
|
|
2730
|
+
_mesh_key = ""
|
|
2731
|
+
if _mesh_key:
|
|
2732
|
+
try:
|
|
2733
|
+
_decrypted = be.decrypt_payload(p["_encrypted"], _mesh_key, aad=_msg_aad)
|
|
2734
|
+
except Exception:
|
|
2735
|
+
_decrypted = None
|
|
2736
|
+
if _decrypted is not None:
|
|
2737
|
+
msg["payload"] = _decrypted
|
|
2705
2738
|
deduped = _filter_and_mark(buffered)
|
|
2706
2739
|
if not deduped:
|
|
2707
2740
|
return None
|