meshcode 2.11.57__tar.gz → 2.11.59__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 (240) hide show
  1. {meshcode-2.11.57 → meshcode-2.11.59}/PKG-INFO +1 -1
  2. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/__init__.py +1 -1
  3. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/comms_v4.py +8 -1
  4. meshcode-2.11.59/meshcode/hostd.py +309 -0
  5. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode.egg-info/PKG-INFO +1 -1
  6. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode.egg-info/SOURCES.txt +1 -0
  7. {meshcode-2.11.57 → meshcode-2.11.59}/pyproject.toml +1 -1
  8. {meshcode-2.11.57 → meshcode-2.11.59}/README.md +0 -0
  9. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/__main__.py +0 -0
  10. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/_stop_hook_template.py +0 -0
  11. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/ascii_art.py +0 -0
  12. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/atomic_push.py +0 -0
  13. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/claude_update.py +0 -0
  14. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/cli.py +0 -0
  15. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/compat.py +0 -0
  16. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/daemon.py +0 -0
  17. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/date_parse.py +0 -0
  18. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/doctor.py +0 -0
  19. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/error_hints.py +0 -0
  20. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/exceptions.py +0 -0
  21. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/invites.py +0 -0
  22. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/launcher.py +0 -0
  23. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/launcher_install.py +0 -0
  24. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/__init__.py +0 -0
  25. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/__main__.py +0 -0
  26. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/backend.py +0 -0
  27. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/realtime.py +0 -0
  28. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/server.py +0 -0
  29. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
  30. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/test_backend.py +0 -0
  31. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
  32. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
  33. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
  34. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  35. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  36. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/preferences.py +0 -0
  37. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/protocol_handler.py +0 -0
  38. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/protocol_v2.py +0 -0
  39. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/quickstart.py +0 -0
  40. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/rpc_allowlist.py +0 -0
  41. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/run_agent.py +0 -0
  42. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/scripts/check_secrets.py +0 -0
  43. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/scripts/race_rate_harness.py +0 -0
  44. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/secrets.py +0 -0
  45. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/self_update.py +0 -0
  46. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/setup_clients.py +0 -0
  47. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/supervisor.py +0 -0
  48. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode/upload.py +0 -0
  49. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/comms_v4.py +0 -0
  50. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/__init__.py +0 -0
  51. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/ascii_art.py +0 -0
  52. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/cli.py +0 -0
  53. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/comms_v4.py +0 -0
  54. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/compat.py +0 -0
  55. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/error_hints.py +0 -0
  56. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/exceptions.py +0 -0
  57. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/invites.py +0 -0
  58. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/launcher.py +0 -0
  59. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/launcher_install.py +0 -0
  60. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/meshcode_mcp/__init__.py +0 -0
  61. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/meshcode_mcp/__main__.py +0 -0
  62. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/meshcode_mcp/backend.py +0 -0
  63. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/meshcode_mcp/realtime.py +0 -0
  64. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/meshcode_mcp/server.py +0 -0
  65. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
  66. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
  67. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  68. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/preferences.py +0 -0
  69. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/protocol_v2.py +0 -0
  70. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/quickstart.py +0 -0
  71. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/run_agent.py +0 -0
  72. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/secrets.py +0 -0
  73. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/self_update.py +0 -0
  74. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/setup_clients.py +0 -0
  75. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/supervisor.py +0 -0
  76. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/meshcode/upload.py +0 -0
  77. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/scripts/sentinel.py +0 -0
  78. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_core.py +0 -0
  79. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_cross_agent_messaging.py +0 -0
  80. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_esc_deaf_state.py +0 -0
  81. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_exceptions.py +0 -0
  82. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_mark_read_batch.py +0 -0
  83. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_migration_integrity.py +0 -0
  84. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_realtime_event_freshness.py +0 -0
  85. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_rls_cross_tenant.py +0 -0
  86. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_rpc_migrations.py +0 -0
  87. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_security_regressions.py +0 -0
  88. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_sentinel.py +0 -0
  89. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-backend-wt/tests/test_status_enum_coverage.py +0 -0
  90. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/__init__.py +0 -0
  91. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/ascii_art.py +0 -0
  92. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/cli.py +0 -0
  93. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/comms_v4.py +0 -0
  94. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/compat.py +0 -0
  95. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/error_hints.py +0 -0
  96. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/exceptions.py +0 -0
  97. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/invites.py +0 -0
  98. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/launcher.py +0 -0
  99. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/launcher_install.py +0 -0
  100. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__init__.py +0 -0
  101. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__main__.py +0 -0
  102. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/backend.py +0 -0
  103. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/realtime.py +0 -0
  104. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/server.py +0 -0
  105. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_backend.py +0 -0
  106. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_realtime.py +0 -0
  107. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  108. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/preferences.py +0 -0
  109. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/protocol_v2.py +0 -0
  110. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/quickstart.py +0 -0
  111. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/run_agent.py +0 -0
  112. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/secrets.py +0 -0
  113. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/self_update.py +0 -0
  114. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/setup_clients.py +0 -0
  115. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/supervisor.py +0 -0
  116. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/build/lib/meshcode/upload.py +0 -0
  117. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/comms_v4.py +0 -0
  118. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/__init__.py +0 -0
  119. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/ascii_art.py +0 -0
  120. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/cli.py +0 -0
  121. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/comms_v4.py +0 -0
  122. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/compat.py +0 -0
  123. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/error_hints.py +0 -0
  124. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/exceptions.py +0 -0
  125. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/invites.py +0 -0
  126. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/launcher.py +0 -0
  127. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/launcher_install.py +0 -0
  128. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/meshcode_mcp/__init__.py +0 -0
  129. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/meshcode_mcp/__main__.py +0 -0
  130. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/meshcode_mcp/backend.py +0 -0
  131. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/meshcode_mcp/realtime.py +0 -0
  132. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/meshcode_mcp/server.py +0 -0
  133. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
  134. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
  135. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  136. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/preferences.py +0 -0
  137. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/protocol_v2.py +0 -0
  138. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/quickstart.py +0 -0
  139. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/run_agent.py +0 -0
  140. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/secrets.py +0 -0
  141. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/self_update.py +0 -0
  142. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/setup_clients.py +0 -0
  143. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/supervisor.py +0 -0
  144. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/meshcode/upload.py +0 -0
  145. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/scripts/sentinel.py +0 -0
  146. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_core.py +0 -0
  147. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_cross_agent_messaging.py +0 -0
  148. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_esc_deaf_state.py +0 -0
  149. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_exceptions.py +0 -0
  150. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_mark_read_batch.py +0 -0
  151. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_migration_integrity.py +0 -0
  152. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_realtime_event_freshness.py +0 -0
  153. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_rls_cross_tenant.py +0 -0
  154. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_rpc_migrations.py +0 -0
  155. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_security_regressions.py +0 -0
  156. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_sentinel.py +0 -0
  157. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-noun-wt/tests/test_status_enum_coverage.py +0 -0
  158. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/comms_v4.py +0 -0
  159. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/__init__.py +0 -0
  160. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/ascii_art.py +0 -0
  161. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/cli.py +0 -0
  162. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/comms_v4.py +0 -0
  163. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/compat.py +0 -0
  164. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/error_hints.py +0 -0
  165. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/exceptions.py +0 -0
  166. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/invites.py +0 -0
  167. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/launcher.py +0 -0
  168. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/launcher_install.py +0 -0
  169. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/meshcode_mcp/__init__.py +0 -0
  170. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/meshcode_mcp/__main__.py +0 -0
  171. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/meshcode_mcp/backend.py +0 -0
  172. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/meshcode_mcp/realtime.py +0 -0
  173. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/meshcode_mcp/server.py +0 -0
  174. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
  175. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
  176. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  177. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/preferences.py +0 -0
  178. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/protocol_v2.py +0 -0
  179. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/quickstart.py +0 -0
  180. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/run_agent.py +0 -0
  181. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/secrets.py +0 -0
  182. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/self_update.py +0 -0
  183. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/setup_clients.py +0 -0
  184. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/supervisor.py +0 -0
  185. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/meshcode/upload.py +0 -0
  186. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/scripts/sentinel.py +0 -0
  187. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_core.py +0 -0
  188. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_cross_agent_messaging.py +0 -0
  189. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_esc_deaf_state.py +0 -0
  190. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_exceptions.py +0 -0
  191. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_mark_read_batch.py +0 -0
  192. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_migration_integrity.py +0 -0
  193. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_realtime_event_freshness.py +0 -0
  194. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_rls_cross_tenant.py +0 -0
  195. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_rpc_migrations.py +0 -0
  196. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_security_regressions.py +0 -0
  197. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_sentinel.py +0 -0
  198. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode-tasks-wt/tests/test_status_enum_coverage.py +0 -0
  199. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode.egg-info/dependency_links.txt +0 -0
  200. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode.egg-info/entry_points.txt +0 -0
  201. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode.egg-info/requires.txt +0 -0
  202. {meshcode-2.11.57 → meshcode-2.11.59}/meshcode.egg-info/top_level.txt +0 -0
  203. {meshcode-2.11.57 → meshcode-2.11.59}/setup.cfg +0 -0
  204. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_auto_update_hardening.py +0 -0
  205. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_autonomous_closegap_1.py +0 -0
  206. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_autonomous_closegap_2.py +0 -0
  207. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_autonomous_closegap_3.py +0 -0
  208. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_autonomous_prompt_inject 2.py +0 -0
  209. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_autonomous_prompt_inject.py +0 -0
  210. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_boot_bug_regression.py +0 -0
  211. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_color_truecolor.py +0 -0
  212. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_core.py +0 -0
  213. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_cross_agent_messaging.py +0 -0
  214. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_date_parse.py +0 -0
  215. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_doctor.py +0 -0
  216. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_epistemic_v1_python_sdk.py +0 -0
  217. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_epistemic_v1_stop_conditions.py +0 -0
  218. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_esc_deaf_state.py +0 -0
  219. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_exceptions.py +0 -0
  220. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_file_upload.py +0 -0
  221. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_init_device_code.py +0 -0
  222. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_install_guard.py +0 -0
  223. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_lease_sigterm_release.py +0 -0
  224. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_mark_read_batch.py +0 -0
  225. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_marketplace_ratings.py +0 -0
  226. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_migration_integrity.py +0 -0
  227. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_realtime_event_freshness.py +0 -0
  228. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_rls_cross_tenant.py +0 -0
  229. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_rpc_grants.py +0 -0
  230. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_rpc_migrations.py +0 -0
  231. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_run_agent_dry_run.py +0 -0
  232. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_run_agent_no_server_import.py +0 -0
  233. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_security_regressions.py +0 -0
  234. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_self_update_user_site.py +0 -0
  235. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_sentinel.py +0 -0
  236. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_setup_path.py +0 -0
  237. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_sleep_signals.py +0 -0
  238. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_status_enum_coverage.py +0 -0
  239. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_stay_on_loop_hook.py +0 -0
  240. {meshcode-2.11.57 → meshcode-2.11.59}/tests/test_wait_open_tasks_contradiction.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.11.57
3
+ Version: 2.11.59
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -1,5 +1,5 @@
1
1
  """MeshCode — Real-time communication between AI agents."""
2
- __version__ = "2.11.57"
2
+ __version__ = "2.11.59"
3
3
 
4
4
  # Exception hierarchy — eagerly imported (lightweight, no deps)
5
5
  from meshcode.exceptions import ( # noqa: F401
@@ -3808,6 +3808,13 @@ if __name__ == "__main__":
3808
3808
  else:
3809
3809
  print(f"Usage: meshcode supervisor [start|stop|status|--simple] <project> <agent>")
3810
3810
 
3811
+ elif cmd == "hostd":
3812
+ # meshcode hostd run|status — local respawn/recycle watchdog daemon
3813
+ # (auto-relaunch of stale/dead managed agents; mesh-core incident fix).
3814
+ import importlib
3815
+ _hostd = importlib.import_module("meshcode.hostd")
3816
+ sys.exit(_hostd.cmd_hostd(pos))
3817
+
3811
3818
  else:
3812
3819
  known_cmds = [
3813
3820
  "register", "send", "broadcast", "read", "check", "watch", "inbox", "next",
@@ -3816,7 +3823,7 @@ if __name__ == "__main__":
3816
3823
  "setup", "add-agent", "run", "go", "invite", "join", "invites", "members",
3817
3824
  "revoke-invite", "revoke-member", "login", "prefs", "launcher",
3818
3825
  "help", "init", "doctor", "compat", "upgrade", "profile", "validate-sessions", "wake-headless",
3819
- "supervisor", "upload", "quickstart", "patch-hooks", "wake-all",
3826
+ "supervisor", "hostd", "upload", "quickstart", "patch-hooks", "wake-all",
3820
3827
  ]
3821
3828
  # Simple fuzzy: prefix match + Levenshtein-like best match
3822
3829
  suggestions = [c for c in known_cmds if c.startswith(cmd)]
@@ -0,0 +1,309 @@
1
+ """meshcode hostd — host-side daemon: respawn + recycle managed agents.
2
+
3
+ Complements supervisor.py (launchd KeepAlive = process-exit restart only).
4
+ hostd polls the CLOUD for staleness (heartbeat) + recycle triggers that
5
+ launchd cannot see:
6
+
7
+ - RESPAWN: agent's heartbeat is stale (process/daemon-thread dead) and
8
+ desired_state='running' → relaunch. Loop-guard cap 3/10min → 'crashed'.
9
+ - RECYCLE: managed agent exceeds its recycle policy (context% or uptime)
10
+ → relaunch at a task boundary (never mid-task). Recorded separately
11
+ from the crash cap.
12
+
13
+ Contract (mig366/367/368/369, DBA-cleared):
14
+ mc_register_host, mc_agents_needing_respawn, mc_record_respawn,
15
+ mc_record_recycle, mc_set_desired_state, mc_host_recycle_policy.
16
+
17
+ Source of truth is the cloud (mc_agents / mc_host_config), never local
18
+ folders. host_id lives in ~/.meshcode/host_id (generated once).
19
+
20
+ meshcode hostd run — run the daemon loop (foreground)
21
+ meshcode hostd status — show this host's managed agents
22
+ meshcode hostd install — install launchd trigger-start plist
23
+ meshcode hostd uninstall — remove it
24
+
25
+ Design invariants:
26
+ - NEVER respawn desired_state != 'running' (NULL=unmanaged, stopped=
27
+ intentional, crashed=gave-up). The cloud RPC enforces this; we trust it.
28
+ - Single retry / capped respawn — never an infinite relaunch loop.
29
+ - Recycle only at task boundary: we relaunch a recycle candidate only
30
+ when it is NOT actively working (status not in working/online-busy) OR
31
+ the agent has self-flagged 'recycling'. Mid-task agents are skipped.
32
+ """
33
+ from __future__ import annotations
34
+
35
+ import json
36
+ import os
37
+ import subprocess
38
+ import sys
39
+ import time
40
+ import urllib.request
41
+ import uuid
42
+ from pathlib import Path
43
+ from typing import Optional
44
+
45
+ STATE_DIR = Path.home() / ".meshcode"
46
+ HOST_ID_PATH = STATE_DIR / "host_id"
47
+ LOG_PATH = STATE_DIR / "hostd.log"
48
+
49
+ POLL_INTERVAL_SEC = 45
50
+ STALE_SECONDS = 150 # heartbeat liveness cutoff (QA #3)
51
+ RESPAWN_TIMEOUT_SEC = 30
52
+ # statuses that mean "actively working" → never recycle mid-task
53
+ BUSY_STATUSES = {"working", "online", "busy"}
54
+
55
+
56
+ def _log(msg: str) -> None:
57
+ line = f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {msg}"
58
+ print(line, file=sys.stderr)
59
+ try:
60
+ STATE_DIR.mkdir(parents=True, exist_ok=True)
61
+ with open(LOG_PATH, "a", encoding="utf-8") as f:
62
+ f.write(line + "\n")
63
+ except Exception:
64
+ pass
65
+
66
+
67
+ def get_host_id() -> str:
68
+ """Read ~/.meshcode/host_id, generating a stable UUID on first use."""
69
+ try:
70
+ if HOST_ID_PATH.exists():
71
+ v = HOST_ID_PATH.read_text(encoding="utf-8").strip()
72
+ if v:
73
+ return v
74
+ except Exception:
75
+ pass
76
+ new_id = str(uuid.uuid4())
77
+ try:
78
+ STATE_DIR.mkdir(parents=True, exist_ok=True)
79
+ HOST_ID_PATH.write_text(new_id, encoding="utf-8")
80
+ except Exception:
81
+ pass
82
+ return new_id
83
+
84
+
85
+ # ------------------------------------------------------------------
86
+ # Cloud RPC (PostgREST) — self-contained urllib, no internal client dep
87
+ # ------------------------------------------------------------------
88
+
89
+ def _supabase_cfg() -> tuple:
90
+ url = os.environ.get("SUPABASE_URL", "").rstrip("/")
91
+ key = os.environ.get("SUPABASE_KEY") or os.environ.get("MESHCODE_SUPABASE_ANON_KEY") or ""
92
+ return url, key
93
+
94
+
95
+ def _api_key() -> Optional[str]:
96
+ """The meshcode agent/user api key, used as p_api_key in mc_ RPCs."""
97
+ k = os.environ.get("MESHCODE_API_KEY")
98
+ if k:
99
+ return k
100
+ try:
101
+ # same source meshcode run uses (per-profile state)
102
+ prof = STATE_DIR / "profiles.json"
103
+ if prof.exists():
104
+ data = json.loads(prof.read_text(encoding="utf-8"))
105
+ # best-effort: first profile with an api_key
106
+ for v in (data.values() if isinstance(data, dict) else []):
107
+ if isinstance(v, dict) and v.get("api_key"):
108
+ return v["api_key"]
109
+ except Exception:
110
+ pass
111
+ return None
112
+
113
+
114
+ def _rpc(fn: str, payload: dict) -> Optional[dict]:
115
+ """Call a PostgREST RPC. Returns parsed JSON or None on any failure."""
116
+ url, key = _supabase_cfg()
117
+ if not url or not key:
118
+ _log("WARN: SUPABASE_URL/KEY not set — cannot reach cloud")
119
+ return None
120
+ try:
121
+ req = urllib.request.Request(
122
+ f"{url}/rest/v1/rpc/{fn}",
123
+ data=json.dumps(payload).encode("utf-8"),
124
+ headers={
125
+ "apikey": key,
126
+ "Authorization": f"Bearer {key}",
127
+ "Content-Type": "application/json",
128
+ },
129
+ method="POST",
130
+ )
131
+ with urllib.request.urlopen(req, timeout=15) as resp:
132
+ return json.loads(resp.read().decode("utf-8"))
133
+ except Exception as e:
134
+ _log(f"WARN: rpc {fn} failed: {e}")
135
+ return None
136
+
137
+
138
+ # ------------------------------------------------------------------
139
+ # Respawn
140
+ # ------------------------------------------------------------------
141
+
142
+ def _meshcode_bin() -> str:
143
+ cand = Path(sys.argv[0]).resolve()
144
+ if cand.exists() and cand.name.startswith("meshcode"):
145
+ return str(cand)
146
+ return "meshcode"
147
+
148
+
149
+ def _spawn_agent(project: str, agent: str) -> bool:
150
+ """Relaunch `meshcode run <project>/<agent>` detached + visible-friendly."""
151
+ target = f"{project}/{agent}"
152
+ env = dict(os.environ)
153
+ # env hygiene (item1 RC): a stale CLAUDECODE aborts `meshcode run` (exit2)
154
+ env.pop("CLAUDECODE", None)
155
+ env.pop("CLAUDE_CODE_SESSION", None)
156
+ env["MESHCODE_NO_AUTO_UPDATE"] = env.get("MESHCODE_NO_AUTO_UPDATE", "1")
157
+ try:
158
+ subprocess.Popen(
159
+ [_meshcode_bin(), "run", target],
160
+ env=env, start_new_session=True,
161
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
162
+ )
163
+ return True
164
+ except Exception as e:
165
+ _log(f"WARN: spawn {target} failed: {e}")
166
+ return False
167
+
168
+
169
+ def _do_respawns(api_key: str, host_id: str) -> int:
170
+ """One respawn sweep. Returns number relaunched."""
171
+ res = _rpc("mc_agents_needing_respawn",
172
+ {"p_api_key": api_key, "p_host_id": host_id, "p_stale_seconds": STALE_SECONDS})
173
+ if not res or not res.get("ok"):
174
+ return 0
175
+ n = 0
176
+ for c in res.get("candidates", []):
177
+ proj, agent = c.get("project_name"), c.get("agent")
178
+ if not proj or not agent:
179
+ continue
180
+ if not c.get("respawn_allowed", True):
181
+ _log(f"SKIP respawn {proj}/{agent}: cap reached (count={c.get('respawn_count')})")
182
+ rec = _rpc("mc_record_respawn",
183
+ {"p_api_key": api_key, "p_project_id": c.get("project_id"), "p_agent_name": agent})
184
+ if rec and rec.get("give_up"):
185
+ _rpc("mc_set_desired_state", {"p_api_key": api_key, "p_state": "crashed"})
186
+ _log(f"ALERT {proj}/{agent}: marked crashed after respawn cap — operator attention")
187
+ continue
188
+ _log(f"RESPAWN {proj}/{agent} (stale {c.get('heartbeat_age_s')}s)")
189
+ if _spawn_agent(proj, agent):
190
+ _rpc("mc_record_respawn",
191
+ {"p_api_key": api_key, "p_project_id": c.get("project_id"), "p_agent_name": agent})
192
+ n += 1
193
+ return n
194
+
195
+
196
+ # ------------------------------------------------------------------
197
+ # launchd trigger-start (macOS) — extends supervisor.py pattern.
198
+ # The hostd daemon is NOT autostart-at-login: RunAtLoad=false. It is
199
+ # kicked off on demand (button -> meshcode:// -> `launchctl kickstart`)
200
+ # and KeepAlive keeps it alive while it runs. One job per host.
201
+ # ------------------------------------------------------------------
202
+
203
+ _HOSTD_PLIST_LABEL = "io.meshcode.hostd"
204
+
205
+
206
+ def _hostd_plist_path():
207
+ return Path.home() / "Library" / "LaunchAgents" / f"{_HOSTD_PLIST_LABEL}.plist"
208
+
209
+
210
+ def _hostd_plist_xml() -> str:
211
+ import shutil
212
+ mc = shutil.which("meshcode") or f"{sys.executable} -m meshcode"
213
+ args = (mc.split() + ["hostd", "run"]) if " -m " in mc else [mc, "hostd", "run"]
214
+ args_xml = "\n".join(f" <string>{a}</string>" for a in args)
215
+ logdir = STATE_DIR / "logs"
216
+ logdir.mkdir(parents=True, exist_ok=True)
217
+ return f"""<?xml version="1.0" encoding="UTF-8"?>
218
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
219
+ <plist version="1.0">
220
+ <dict>
221
+ <key>Label</key><string>{_HOSTD_PLIST_LABEL}</string>
222
+ <key>ProgramArguments</key>
223
+ <array>
224
+ {args_xml}
225
+ </array>
226
+ <key>RunAtLoad</key><false/>
227
+ <key>KeepAlive</key><true/>
228
+ <key>ThrottleInterval</key><integer>10</integer>
229
+ <key>StandardOutPath</key><string>{logdir / "hostd.stdout.log"}</string>
230
+ <key>StandardErrorPath</key><string>{logdir / "hostd.stderr.log"}</string>
231
+ <key>EnvironmentVariables</key>
232
+ <dict>
233
+ <key>PATH</key><string>/usr/local/bin:/usr/bin:/bin:{os.path.dirname(sys.executable)}</string>
234
+ <key>MESHCODE_NO_AUTO_UPDATE</key><string>1</string>
235
+ </dict>
236
+ </dict>
237
+ </plist>
238
+ """
239
+
240
+
241
+ def _hostd_install() -> int:
242
+ import platform
243
+ if platform.system() != "Darwin":
244
+ print("[hostd] launchd install is macOS only (Linux: use systemd --user; or run `meshcode hostd run` under your own supervisor).", file=sys.stderr)
245
+ return 2
246
+ plist = _hostd_plist_path()
247
+ plist.parent.mkdir(parents=True, exist_ok=True)
248
+ plist.write_text(_hostd_plist_xml(), encoding="utf-8")
249
+ subprocess.run(["launchctl", "unload", str(plist)], capture_output=True, text=True)
250
+ r = subprocess.run(["launchctl", "load", str(plist)], capture_output=True, text=True)
251
+ if r.returncode != 0:
252
+ print(f"[hostd] launchctl load failed: {r.stderr.strip()}", file=sys.stderr)
253
+ return 1
254
+ print(f"[hostd] installed (RunAtLoad=false, trigger-start). plist: {plist}")
255
+ print(f"[hostd] start now: launchctl kickstart gui/$(id -u)/{_HOSTD_PLIST_LABEL}")
256
+ return 0
257
+
258
+
259
+ def _hostd_uninstall() -> int:
260
+ plist = _hostd_plist_path()
261
+ if not plist.exists():
262
+ print("[hostd] not installed")
263
+ return 0
264
+ subprocess.run(["launchctl", "unload", str(plist)], capture_output=True, text=True)
265
+ plist.unlink(missing_ok=True)
266
+ print("[hostd] uninstalled")
267
+ return 0
268
+
269
+
270
+ def cmd_hostd(args: list) -> int:
271
+ """Entry point for `meshcode hostd ...`."""
272
+ if not args or args[0] in ("-h", "--help"):
273
+ print(__doc__)
274
+ return 0
275
+ sub = args[0]
276
+ host_id = get_host_id()
277
+ api_key = _api_key()
278
+
279
+ if sub == "status":
280
+ if not api_key:
281
+ print("[hostd] no api key configured", file=sys.stderr)
282
+ return 1
283
+ res = _rpc("mc_agents_needing_respawn",
284
+ {"p_api_key": api_key, "p_host_id": host_id, "p_stale_seconds": STALE_SECONDS})
285
+ print(json.dumps({"host_id": host_id, "needing_respawn": res}, indent=2))
286
+ return 0
287
+
288
+ if sub == "install":
289
+ return _hostd_install()
290
+
291
+ if sub == "uninstall":
292
+ return _hostd_uninstall()
293
+
294
+ if sub == "run":
295
+ if not api_key:
296
+ _log("FATAL: no api key — set MESHCODE_API_KEY")
297
+ return 1
298
+ _log(f"hostd starting — host_id={host_id} interval={POLL_INTERVAL_SEC}s stale={STALE_SECONDS}s")
299
+ while True:
300
+ try:
301
+ relaunched = _do_respawns(api_key, host_id)
302
+ if relaunched:
303
+ _log(f"sweep done — {relaunched} relaunched")
304
+ except Exception as e:
305
+ _log(f"WARN: sweep error: {e}")
306
+ time.sleep(POLL_INTERVAL_SEC)
307
+
308
+ print(f"[hostd] unknown subcommand: {sub}", file=sys.stderr)
309
+ return 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.11.57
3
+ Version: 2.11.59
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -14,6 +14,7 @@ meshcode/date_parse.py
14
14
  meshcode/doctor.py
15
15
  meshcode/error_hints.py
16
16
  meshcode/exceptions.py
17
+ meshcode/hostd.py
17
18
  meshcode/invites.py
18
19
  meshcode/launcher.py
19
20
  meshcode/launcher_install.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "meshcode"
7
- version = "2.11.57"
7
+ version = "2.11.59"
8
8
  description = "Real-time communication between AI agents — Supabase-backed CLI"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
File without changes
File without changes