meshcode 2.11.73__tar.gz → 2.11.75__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 (268) hide show
  1. {meshcode-2.11.73 → meshcode-2.11.75}/PKG-INFO +1 -1
  2. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/__init__.py +1 -1
  3. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/claude_update.py +6 -1
  4. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/comms_v4.py +10 -0
  5. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/hostd.py +115 -6
  6. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/self_update.py +63 -2
  7. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/PKG-INFO +1 -1
  8. {meshcode-2.11.73 → meshcode-2.11.75}/pyproject.toml +1 -1
  9. {meshcode-2.11.73 → meshcode-2.11.75}/README.md +0 -0
  10. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/__main__.py +0 -0
  11. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/_stop_hook_template.py +0 -0
  12. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/ascii_art.py +0 -0
  13. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/atomic_push.py +0 -0
  14. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/cli.py +0 -0
  15. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/compat.py +0 -0
  16. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/daemon.py +0 -0
  17. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/date_parse.py +0 -0
  18. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/doctor.py +0 -0
  19. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/error_hints.py +0 -0
  20. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/exceptions.py +0 -0
  21. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/hostd 3.py +0 -0
  22. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/invites.py +0 -0
  23. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/launcher.py +0 -0
  24. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/launcher_install.py +0 -0
  25. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/__init__.py +0 -0
  26. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/__main__.py +0 -0
  27. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/backend.py +0 -0
  28. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/realtime.py +0 -0
  29. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/server.py +0 -0
  30. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
  31. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/test_backend.py +0 -0
  32. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
  33. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
  34. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
  35. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/test_realtime.py +0 -0
  36. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  37. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/preferences.py +0 -0
  38. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/protocol_handler.py +0 -0
  39. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/protocol_v2.py +0 -0
  40. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/quickstart.py +0 -0
  41. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/rpc_allowlist.py +0 -0
  42. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/run_agent.py +0 -0
  43. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/scripts/check_secrets.py +0 -0
  44. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/scripts/race_rate_harness.py +0 -0
  45. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/secrets.py +0 -0
  46. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/setup_clients.py +0 -0
  47. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/supervisor.py +0 -0
  48. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/up.py +0 -0
  49. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode/upload.py +0 -0
  50. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/comms_v4.py +0 -0
  51. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/__init__.py +0 -0
  52. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/ascii_art.py +0 -0
  53. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/cli.py +0 -0
  54. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/comms_v4.py +0 -0
  55. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/compat.py +0 -0
  56. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/error_hints.py +0 -0
  57. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/exceptions.py +0 -0
  58. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/invites.py +0 -0
  59. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/launcher.py +0 -0
  60. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/launcher_install.py +0 -0
  61. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/meshcode_mcp/__init__.py +0 -0
  62. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/meshcode_mcp/__main__.py +0 -0
  63. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/meshcode_mcp/backend.py +0 -0
  64. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/meshcode_mcp/realtime.py +0 -0
  65. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/meshcode_mcp/server.py +0 -0
  66. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
  67. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
  68. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  69. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/preferences.py +0 -0
  70. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/protocol_v2.py +0 -0
  71. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/quickstart.py +0 -0
  72. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/run_agent.py +0 -0
  73. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/secrets.py +0 -0
  74. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/self_update.py +0 -0
  75. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/setup_clients.py +0 -0
  76. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/supervisor.py +0 -0
  77. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/meshcode/upload.py +0 -0
  78. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/scripts/sentinel.py +0 -0
  79. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_core.py +0 -0
  80. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_cross_agent_messaging.py +0 -0
  81. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_esc_deaf_state.py +0 -0
  82. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_exceptions.py +0 -0
  83. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_mark_read_batch.py +0 -0
  84. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_migration_integrity.py +0 -0
  85. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_realtime_event_freshness.py +0 -0
  86. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_rls_cross_tenant.py +0 -0
  87. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_rpc_migrations.py +0 -0
  88. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_security_regressions.py +0 -0
  89. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_sentinel.py +0 -0
  90. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-backend-wt/tests/test_status_enum_coverage.py +0 -0
  91. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/__init__.py +0 -0
  92. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/ascii_art.py +0 -0
  93. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/cli.py +0 -0
  94. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/comms_v4.py +0 -0
  95. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/compat.py +0 -0
  96. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/error_hints.py +0 -0
  97. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/exceptions.py +0 -0
  98. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/invites.py +0 -0
  99. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/launcher.py +0 -0
  100. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/launcher_install.py +0 -0
  101. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__init__.py +0 -0
  102. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__main__.py +0 -0
  103. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/backend.py +0 -0
  104. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/realtime.py +0 -0
  105. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/server.py +0 -0
  106. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_backend.py +0 -0
  107. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_realtime.py +0 -0
  108. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  109. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/preferences.py +0 -0
  110. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/protocol_v2.py +0 -0
  111. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/quickstart.py +0 -0
  112. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/run_agent.py +0 -0
  113. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/secrets.py +0 -0
  114. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/self_update.py +0 -0
  115. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/setup_clients.py +0 -0
  116. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/supervisor.py +0 -0
  117. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/build/lib/meshcode/upload.py +0 -0
  118. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/comms_v4.py +0 -0
  119. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/__init__.py +0 -0
  120. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/ascii_art.py +0 -0
  121. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/cli.py +0 -0
  122. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/comms_v4.py +0 -0
  123. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/compat.py +0 -0
  124. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/error_hints.py +0 -0
  125. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/exceptions.py +0 -0
  126. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/invites.py +0 -0
  127. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/launcher.py +0 -0
  128. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/launcher_install.py +0 -0
  129. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/meshcode_mcp/__init__.py +0 -0
  130. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/meshcode_mcp/__main__.py +0 -0
  131. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/meshcode_mcp/backend.py +0 -0
  132. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/meshcode_mcp/realtime.py +0 -0
  133. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/meshcode_mcp/server.py +0 -0
  134. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
  135. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
  136. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  137. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/preferences.py +0 -0
  138. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/protocol_v2.py +0 -0
  139. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/quickstart.py +0 -0
  140. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/run_agent.py +0 -0
  141. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/secrets.py +0 -0
  142. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/self_update.py +0 -0
  143. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/setup_clients.py +0 -0
  144. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/supervisor.py +0 -0
  145. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/meshcode/upload.py +0 -0
  146. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/scripts/sentinel.py +0 -0
  147. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_core.py +0 -0
  148. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_cross_agent_messaging.py +0 -0
  149. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_esc_deaf_state.py +0 -0
  150. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_exceptions.py +0 -0
  151. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_mark_read_batch.py +0 -0
  152. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_migration_integrity.py +0 -0
  153. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_realtime_event_freshness.py +0 -0
  154. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_rls_cross_tenant.py +0 -0
  155. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_rpc_migrations.py +0 -0
  156. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_security_regressions.py +0 -0
  157. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_sentinel.py +0 -0
  158. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-noun-wt/tests/test_status_enum_coverage.py +0 -0
  159. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/comms_v4.py +0 -0
  160. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/__init__.py +0 -0
  161. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/ascii_art.py +0 -0
  162. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/cli.py +0 -0
  163. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/comms_v4.py +0 -0
  164. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/compat.py +0 -0
  165. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/error_hints.py +0 -0
  166. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/exceptions.py +0 -0
  167. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/invites.py +0 -0
  168. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/launcher.py +0 -0
  169. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/launcher_install.py +0 -0
  170. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/meshcode_mcp/__init__.py +0 -0
  171. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/meshcode_mcp/__main__.py +0 -0
  172. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/meshcode_mcp/backend.py +0 -0
  173. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/meshcode_mcp/realtime.py +0 -0
  174. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/meshcode_mcp/server.py +0 -0
  175. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
  176. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
  177. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
  178. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/preferences.py +0 -0
  179. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/protocol_v2.py +0 -0
  180. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/quickstart.py +0 -0
  181. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/run_agent.py +0 -0
  182. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/secrets.py +0 -0
  183. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/self_update.py +0 -0
  184. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/setup_clients.py +0 -0
  185. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/supervisor.py +0 -0
  186. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/meshcode/upload.py +0 -0
  187. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/scripts/sentinel.py +0 -0
  188. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_core.py +0 -0
  189. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_cross_agent_messaging.py +0 -0
  190. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_esc_deaf_state.py +0 -0
  191. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_exceptions.py +0 -0
  192. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_mark_read_batch.py +0 -0
  193. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_migration_integrity.py +0 -0
  194. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_realtime_event_freshness.py +0 -0
  195. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_rls_cross_tenant.py +0 -0
  196. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_rpc_migrations.py +0 -0
  197. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_security_regressions.py +0 -0
  198. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_sentinel.py +0 -0
  199. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode-tasks-wt/tests/test_status_enum_coverage.py +0 -0
  200. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/PKG-INFO 2 +0 -0
  201. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/SOURCES 2.txt +0 -0
  202. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/SOURCES.txt +0 -0
  203. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/dependency_links 2.txt +0 -0
  204. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/dependency_links.txt +0 -0
  205. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/entry_points 2.txt +0 -0
  206. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/entry_points.txt +0 -0
  207. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/requires 2.txt +0 -0
  208. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/requires.txt +0 -0
  209. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/top_level 2.txt +0 -0
  210. {meshcode-2.11.73 → meshcode-2.11.75}/meshcode.egg-info/top_level.txt +0 -0
  211. {meshcode-2.11.73 → meshcode-2.11.75}/setup.cfg +0 -0
  212. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_auto_update_hardening.py +0 -0
  213. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_closegap_1.py +0 -0
  214. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_closegap_2.py +0 -0
  215. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_closegap_3.py +0 -0
  216. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 10.py +0 -0
  217. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 11.py +0 -0
  218. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 12.py +0 -0
  219. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 13.py +0 -0
  220. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 14.py +0 -0
  221. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 15.py +0 -0
  222. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 16.py +0 -0
  223. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 17.py +0 -0
  224. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 18.py +0 -0
  225. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 19.py +0 -0
  226. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 2.py +0 -0
  227. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 20.py +0 -0
  228. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 21.py +0 -0
  229. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 22.py +0 -0
  230. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 3.py +0 -0
  231. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 4.py +0 -0
  232. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 5.py +0 -0
  233. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 6.py +0 -0
  234. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 7.py +0 -0
  235. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 8.py +0 -0
  236. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject 9.py +0 -0
  237. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_autonomous_prompt_inject.py +0 -0
  238. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_boot_bug_regression.py +0 -0
  239. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_color_truecolor.py +0 -0
  240. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_core.py +0 -0
  241. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_cross_agent_messaging.py +0 -0
  242. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_date_parse.py +0 -0
  243. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_doctor.py +0 -0
  244. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_epistemic_v1_python_sdk.py +0 -0
  245. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_epistemic_v1_stop_conditions.py +0 -0
  246. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_esc_deaf_state.py +0 -0
  247. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_exceptions.py +0 -0
  248. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_file_upload.py +0 -0
  249. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_init_device_code.py +0 -0
  250. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_install_guard.py +0 -0
  251. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_lease_sigterm_release.py +0 -0
  252. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_mark_read_batch.py +0 -0
  253. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_marketplace_ratings.py +0 -0
  254. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_migration_integrity.py +0 -0
  255. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_realtime_event_freshness.py +0 -0
  256. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_rls_cross_tenant.py +0 -0
  257. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_rpc_grants.py +0 -0
  258. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_rpc_migrations.py +0 -0
  259. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_run_agent_dry_run.py +0 -0
  260. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_run_agent_no_server_import.py +0 -0
  261. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_security_regressions.py +0 -0
  262. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_self_update_user_site.py +0 -0
  263. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_sentinel.py +0 -0
  264. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_setup_path.py +0 -0
  265. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_sleep_signals.py +0 -0
  266. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_status_enum_coverage.py +0 -0
  267. {meshcode-2.11.73 → meshcode-2.11.75}/tests/test_stay_on_loop_hook.py +0 -0
  268. {meshcode-2.11.73 → meshcode-2.11.75}/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.73
3
+ Version: 2.11.75
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.73"
2
+ __version__ = "2.11.75"
3
3
 
4
4
  # Exception hierarchy — eagerly imported (lightweight, no deps)
5
5
  from meshcode.exceptions import ( # noqa: F401
@@ -60,9 +60,14 @@ def _is_claude_session() -> bool:
60
60
 
61
61
 
62
62
  def _update_disabled() -> bool:
63
+ # task 399d7b51 FIX A (unify): honor MESHCODE_NO_AUTO_UPDATE too. hostd launcher / run_agent /
64
+ # schtasks set that var to disable ALL launch-time auto-update; previously only the meshcode-pip
65
+ # path checked MESHCODE_NO_UPDATE, so the claude-CLI blocking update still fired (extra hang).
63
66
  if os.environ.get("MESHCODE_NO_UPDATE") == "1":
64
67
  return True
65
- if "--no-update" in sys.argv:
68
+ if os.environ.get("MESHCODE_NO_AUTO_UPDATE") == "1":
69
+ return True
70
+ if "--no-update" in sys.argv or "--no-auto-update" in sys.argv:
66
71
  return True
67
72
  return False
68
73
 
@@ -2388,6 +2388,16 @@ def login(api_key):
2388
2388
  backend = secrets_mod.keyring_status().get("backend", "?")
2389
2389
  print(f"[meshcode] Authenticated as {result['display_name']} ({result['email']})")
2390
2390
  print(f"[meshcode] API key stored in OS keychain ({backend})")
2391
+
2392
+ # ZERO-SETUP (task f12b9d36): auto-bootstrap hostd so Launch works with no manual
2393
+ # `meshcode hostd install`. Idempotent + cross-platform + best-effort (never breaks login).
2394
+ try:
2395
+ import importlib as _il
2396
+ _hd = _il.import_module("meshcode.hostd")
2397
+ _hd._hostd_bootstrap(verbose=True)
2398
+ except Exception:
2399
+ pass
2400
+
2391
2401
  return True
2392
2402
 
2393
2403
 
@@ -35,6 +35,7 @@ from __future__ import annotations
35
35
  import json
36
36
  import os
37
37
  import shlex
38
+ import shutil
38
39
  import subprocess
39
40
  import sys
40
41
  import time
@@ -47,8 +48,18 @@ STATE_DIR = Path.home() / ".meshcode"
47
48
  HOST_ID_PATH = STATE_DIR / "host_id"
48
49
  LOG_PATH = STATE_DIR / "hostd.log"
49
50
 
50
- POLL_INTERVAL_SEC = 45
51
- STALE_SECONDS = 150 # heartbeat liveness cutoff (QA #3)
51
+ def _env_poll_interval() -> int:
52
+ # task 399d7b51 SPEED: poll faster so click->desired_state->spawn latency drops (was 45s).
53
+ # Env-configurable (survives upgrade); floor 3s so we never hammer the DB.
54
+ try:
55
+ v = int(os.environ.get("MESHCODE_HOSTD_POLL_SEC", "10"))
56
+ except Exception:
57
+ v = 10
58
+ return max(3, v)
59
+
60
+
61
+ POLL_INTERVAL_SEC = _env_poll_interval() # default 10s (was 45); env MESHCODE_HOSTD_POLL_SEC, floor 3
62
+ STALE_SECONDS = 150 # heartbeat liveness cutoff (QA #3) — do NOT lower (false respawns / boot-storm)
52
63
  RESPAWN_TIMEOUT_SEC = 30
53
64
  # statuses that mean "actively working" → never recycle mid-task
54
65
  BUSY_STATUSES = {"working", "online", "busy"}
@@ -204,6 +215,7 @@ def _spawn_agent(project: str, agent: str, headless: bool = False) -> bool:
204
215
  env = {k: v for k, v in os.environ.items()
205
216
  if k not in ("CLAUDECODE", "CLAUDE_CODE_SESSION")}
206
217
  env["MESHCODE_NO_AUTO_UPDATE"] = "1"
218
+ env["MESHCODE_NO_UPDATE"] = "1" # belt-and-suspenders: var honored pre-2.11.74 (no launch-hang)
207
219
  log_dir = STATE_DIR / "logs"
208
220
  try:
209
221
  log_dir.mkdir(parents=True, exist_ok=True)
@@ -257,10 +269,11 @@ def _spawn_agent(project: str, agent: str, headless: bool = False) -> bool:
257
269
  # on ';' -> file-not-found. Layered ON TOP of the 2.11.72 headless-flags fix (visible branch only).
258
270
  if sys.platform == "win32":
259
271
  cmd = (f'set "CLAUDECODE=" & set "CLAUDE_CODE_SESSION=" & '
260
- f'set "MESHCODE_NO_AUTO_UPDATE=1" & "{bin_}" run "{target}"')
272
+ f'set "MESHCODE_NO_AUTO_UPDATE=1" & set "MESHCODE_NO_UPDATE=1" & '
273
+ f'"{bin_}" run "{target}"')
261
274
  else:
262
275
  cmd = (f"unset CLAUDECODE CLAUDE_CODE_SESSION; export MESHCODE_NO_AUTO_UPDATE=1; "
263
- f"exec {shlex.quote(bin_)} run {shlex.quote(target)}")
276
+ f"export MESHCODE_NO_UPDATE=1; exec {shlex.quote(bin_)} run {shlex.quote(target)}")
264
277
  try:
265
278
  from meshcode import protocol_handler as _ph
266
279
  ok, info = _ph._spawn_terminal(cmd)
@@ -447,7 +460,9 @@ def _hostd_install_windows() -> int:
447
460
  launch_cmd = STATE_DIR / "hostd-launch.cmd"
448
461
  launch_cmd.write_text(
449
462
  "@echo off\r\n"
450
- 'set "MESHCODE_NO_AUTO_UPDATE=1"\r\n'
463
+ 'set "MESHCODE_NO_UPDATE=1"\r\n' # var honored pre-2.11.74 (belt-and-suspenders)
464
+ 'set "MESHCODE_NO_AUTO_UPDATE=1"\r\n' # unified var (honored 2.11.74+)
465
+ 'set "MESHCODE_HOSTD_POLL_SEC=10"\r\n' # faster click->spawn (default 10s, floor 3)
451
466
  f'"{mc}" hostd run\r\n',
452
467
  encoding="utf-8",
453
468
  )
@@ -471,12 +486,64 @@ def _hostd_install_windows() -> int:
471
486
  return 0
472
487
 
473
488
 
489
+ _HOSTD_SYSTEMD_UNIT = "meshcode-hostd.service"
490
+
491
+
492
+ def _hostd_run_argv() -> list:
493
+ """Argv that runs `meshcode hostd run`, resolving the installed console script or
494
+ falling back to `python -m meshcode`."""
495
+ mc = shutil.which("meshcode")
496
+ if mc:
497
+ return [mc, "hostd", "run"]
498
+ return [sys.executable, "-m", "meshcode", "hostd", "run"]
499
+
500
+
501
+ def _hostd_install_linux() -> int:
502
+ """Linux (task f12b9d36): systemd --user unit (durable, auto-restart, survives logout-login)
503
+ with nohup fallback when systemd --user isn't usable (no session bus / container)."""
504
+ (STATE_DIR / "logs").mkdir(parents=True, exist_ok=True)
505
+ argv = _hostd_run_argv()
506
+ execstart = " ".join(shlex.quote(a) for a in argv)
507
+ if shutil.which("systemctl"):
508
+ unit_dir = Path.home() / ".config" / "systemd" / "user"
509
+ unit_dir.mkdir(parents=True, exist_ok=True)
510
+ (unit_dir / _HOSTD_SYSTEMD_UNIT).write_text(
511
+ "[Unit]\nDescription=MeshCode hostd\nAfter=default.target\n\n"
512
+ "[Service]\nType=simple\n"
513
+ "Environment=MESHCODE_NO_UPDATE=1\nEnvironment=MESHCODE_NO_AUTO_UPDATE=1\n"
514
+ "Environment=MESHCODE_HOSTD_POLL_SEC=10\n"
515
+ f"ExecStart={execstart}\nRestart=on-failure\nRestartSec=10\n\n"
516
+ "[Install]\nWantedBy=default.target\n",
517
+ encoding="utf-8",
518
+ )
519
+ subprocess.run(["systemctl", "--user", "daemon-reload"], capture_output=True, text=True)
520
+ r = subprocess.run(["systemctl", "--user", "enable", "--now", _HOSTD_SYSTEMD_UNIT],
521
+ capture_output=True, text=True)
522
+ if r.returncode == 0:
523
+ print(f"[hostd] installed systemd --user unit '{_HOSTD_SYSTEMD_UNIT}' (enabled + started)")
524
+ return 0
525
+ _log(f"systemd --user enable failed ({r.stderr.strip()}); falling back to nohup")
526
+ # nohup fallback: starts now (host registers); not reboot-persistent.
527
+ env = {**os.environ, "MESHCODE_NO_UPDATE": "1", "MESHCODE_NO_AUTO_UPDATE": "1",
528
+ "MESHCODE_HOSTD_POLL_SEC": "10"}
529
+ try:
530
+ logf = open(STATE_DIR / "logs" / "hostd.stdout.log", "ab")
531
+ except Exception:
532
+ logf = subprocess.DEVNULL
533
+ subprocess.Popen(argv, stdout=logf, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL,
534
+ start_new_session=True, env=env)
535
+ print("[hostd] started via nohup (no systemd --user available; not reboot-persistent)")
536
+ return 0
537
+
538
+
474
539
  def _hostd_install() -> int:
475
540
  import platform
476
541
  if platform.system() == "Windows":
477
542
  return _hostd_install_windows()
543
+ if platform.system() == "Linux":
544
+ return _hostd_install_linux()
478
545
  if platform.system() != "Darwin":
479
- print("[hostd] launchd install is macOS only (Linux: use systemd --user; or run `meshcode hostd run` under your own supervisor).", file=sys.stderr)
546
+ print("[hostd] unsupported platform; run `meshcode hostd run` under your own supervisor.", file=sys.stderr)
480
547
  return 2
481
548
  plist = _hostd_plist_path()
482
549
  plist.parent.mkdir(parents=True, exist_ok=True)
@@ -510,6 +577,48 @@ def _hostd_uninstall() -> int:
510
577
  return 0
511
578
 
512
579
 
580
+ def _hostd_bootstrap(verbose: bool = False) -> bool:
581
+ """Idempotent auto-install + start of hostd (task f12b9d36) — called from `meshcode login`
582
+ so onboarding is just `pip install meshcode` + `meshcode login` (no manual `hostd install`).
583
+ If the OS job already exists, just ensure it's running (don't bounce a live daemon); else
584
+ install + start. Best-effort: NEVER raises — login must not fail on a bootstrap hiccup."""
585
+ import platform
586
+ try:
587
+ sysname = platform.system()
588
+ if sysname == "Darwin":
589
+ if not _hostd_plist_path().exists():
590
+ _hostd_install() # writes plist + launchctl load
591
+ try:
592
+ uid = str(os.getuid())
593
+ subprocess.run(["launchctl", "kickstart", f"gui/{uid}/{_HOSTD_PLIST_LABEL}"],
594
+ capture_output=True, text=True) # start if not already running
595
+ except Exception:
596
+ pass
597
+ elif sysname == "Windows":
598
+ q = subprocess.run(["schtasks", "/Query", "/TN", _HOSTD_TASK_NAME],
599
+ capture_output=True, text=True)
600
+ if q.returncode != 0:
601
+ _hostd_install_windows()
602
+ subprocess.run(["schtasks", "/Run", "/TN", _HOSTD_TASK_NAME],
603
+ capture_output=True, text=True) # harmless if already running
604
+ else: # Linux + others
605
+ if shutil.which("systemctl"):
606
+ act = subprocess.run(["systemctl", "--user", "is-active", _HOSTD_SYSTEMD_UNIT],
607
+ capture_output=True, text=True)
608
+ if act.stdout.strip() == "active":
609
+ return True # already running — no-op
610
+ _hostd_install_linux() # systemd enable --now, or nohup fallback
611
+ if verbose:
612
+ print("[meshcode] hostd bootstrapped — Launch is ready (no manual setup needed).")
613
+ return True
614
+ except Exception as e:
615
+ try:
616
+ _log(f"hostd bootstrap skipped: {e}")
617
+ except Exception:
618
+ pass
619
+ return False
620
+
621
+
513
622
  def cmd_hostd(args: list) -> int:
514
623
  """Entry point for `meshcode hostd ...`."""
515
624
  if not args or args[0] in ("-h", "--help"):
@@ -96,14 +96,59 @@ def is_pipx_install() -> bool:
96
96
 
97
97
 
98
98
  def update_disabled() -> bool:
99
- """User explicitly opted out for this run / globally."""
99
+ """User explicitly opted out for this run / globally.
100
+
101
+ task 399d7b51 FIX A: honor BOTH var names. The hostd launcher, run_agent, and the 2.11.73
102
+ Windows schtasks installer all historically set MESHCODE_NO_AUTO_UPDATE (NOT MESHCODE_NO_UPDATE),
103
+ so the "disable" everyone believed they were applying was a silent NO-OP — every launch still
104
+ ran the blocking pip update (and hung on Windows WinError 32). Accept both names + flags.
105
+ """
100
106
  if os.environ.get("MESHCODE_NO_UPDATE") == "1":
101
107
  return True
102
- if "--no-update" in sys.argv:
108
+ if os.environ.get("MESHCODE_NO_AUTO_UPDATE") == "1":
109
+ return True
110
+ if "--no-update" in sys.argv or "--no-auto-update" in sys.argv:
103
111
  return True
104
112
  return False
105
113
 
106
114
 
115
+ def _selfheal_pip_turds() -> int:
116
+ """FIX C (399d7b51): remove ~eshcode / ~~shcode leftovers that pip drops in site-packages when a
117
+ Windows overwrite of meshcode.exe fails (WinError 32). Best-effort; returns count removed."""
118
+ import glob
119
+ removed = 0
120
+ dirs = set()
121
+ try:
122
+ import site
123
+ for p in (site.getsitepackages() if hasattr(site, "getsitepackages") else []):
124
+ dirs.add(p)
125
+ try:
126
+ dirs.add(site.getusersitepackages())
127
+ except Exception:
128
+ pass
129
+ except Exception:
130
+ pass
131
+ try:
132
+ dirs.add(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
133
+ except Exception:
134
+ pass
135
+ for d in dirs:
136
+ if not d or not os.path.isdir(d):
137
+ continue
138
+ for pat in ("~eshcode*", "~~shcode*", "~~eshcode*"):
139
+ for t in glob.glob(os.path.join(d, pat)):
140
+ try:
141
+ if os.path.isdir(t):
142
+ import shutil as _sh
143
+ _sh.rmtree(t, ignore_errors=True)
144
+ else:
145
+ os.remove(t)
146
+ removed += 1
147
+ except Exception:
148
+ pass
149
+ return removed
150
+
151
+
107
152
  def _version_tuple(v: str) -> Tuple[int, ...]:
108
153
  parts = []
109
154
  for p in v.split("."):
@@ -401,6 +446,22 @@ def check_and_maybe_update_blocking(verbose: bool = True, timeout_sec: int = 60)
401
446
  # Dev mode — never touch the working tree from underneath the user.
402
447
  return None
403
448
 
449
+ # FIX B+C (399d7b51): on Windows an inline `pip install -U meshcode` CANNOT overwrite
450
+ # meshcode.exe while a meshcode process is running (WinError 32) — it has hung ~10s and
451
+ # FAILED on every Windows launch since April, leaving ~eshcode/~~shcode turds. Do NOT block:
452
+ # self-heal the turds, then delegate to the NON-blocking staged updater (applies on a future
453
+ # clean start) and return immediately so the launch goes straight to the editor.
454
+ if sys.platform == "win32":
455
+ try:
456
+ _selfheal_pip_turds()
457
+ except Exception:
458
+ pass
459
+ try:
460
+ check_and_maybe_update(verbose=verbose) # non-blocking; never overwrites a live .exe inline
461
+ except Exception:
462
+ pass
463
+ return None
464
+
404
465
  cur = _current_version()
405
466
  latest = fetch_latest_version()
406
467
  _mark_checked(latest)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcode
3
- Version: 2.11.73
3
+ Version: 2.11.75
4
4
  Summary: Real-time communication between AI agents — Supabase-backed CLI
5
5
  Author-email: MeshCode <hello@meshcode.io>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "meshcode"
7
- version = "2.11.73"
7
+ version = "2.11.75"
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
File without changes