meshcode 2.11.83__tar.gz → 2.11.84__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.11.83 → meshcode-2.11.84}/PKG-INFO +1 -1
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/__init__.py +1 -1
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/hostd.py +155 -4
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/protocol_handler.py +6 -3
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode.egg-info/PKG-INFO +1 -1
- meshcode-2.11.84/meshcode.egg-info/SOURCES.txt +88 -0
- meshcode-2.11.84/meshcode.egg-info/top_level.txt +1 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/pyproject.toml +1 -1
- meshcode-2.11.83/meshcode/ascii_art.py +0 -638
- meshcode-2.11.83/meshcode/claude_update 2.py +0 -258
- meshcode-2.11.83/meshcode/cli.py +0 -42
- meshcode-2.11.83/meshcode/compat.py +0 -174
- meshcode-2.11.83/meshcode/error_hints.py +0 -74
- meshcode-2.11.83/meshcode/exceptions.py +0 -52
- meshcode-2.11.83/meshcode/hostd 2.py +0 -849
- meshcode-2.11.83/meshcode/invites.py +0 -406
- meshcode-2.11.83/meshcode/launcher.py +0 -353
- meshcode-2.11.83/meshcode/launcher_install.py +0 -414
- meshcode-2.11.83/meshcode/meshcode_mcp/__init__.py +0 -22
- meshcode-2.11.83/meshcode/meshcode_mcp/__main__.py +0 -62
- meshcode-2.11.83/meshcode/meshcode_mcp/test_backend.py +0 -86
- meshcode-2.11.83/meshcode/meshcode_mcp/test_realtime.py +0 -95
- meshcode-2.11.83/meshcode/meshcode_mcp/test_server_wrapper.py +0 -117
- meshcode-2.11.83/meshcode/preferences.py +0 -260
- meshcode-2.11.83/meshcode/protocol_v2.py +0 -129
- meshcode-2.11.83/meshcode/secrets.py +0 -365
- meshcode-2.11.83/meshcode/supervisor.py +0 -186
- meshcode-2.11.83/meshcode/up 2.py +0 -257
- meshcode-2.11.83/meshcode/upload.py +0 -125
- meshcode-2.11.83/meshcode-backend-wt/comms_v4.py +0 -1941
- meshcode-2.11.83/meshcode-backend-wt/meshcode/__init__.py +0 -82
- meshcode-2.11.83/meshcode-backend-wt/meshcode/comms_v4.py +0 -3563
- meshcode-2.11.83/meshcode-backend-wt/meshcode/meshcode_mcp/backend.py +0 -1261
- meshcode-2.11.83/meshcode-backend-wt/meshcode/meshcode_mcp/realtime.py +0 -460
- meshcode-2.11.83/meshcode-backend-wt/meshcode/meshcode_mcp/server.py +0 -4117
- meshcode-2.11.83/meshcode-backend-wt/meshcode/quickstart.py +0 -148
- meshcode-2.11.83/meshcode-backend-wt/meshcode/run_agent.py +0 -958
- meshcode-2.11.83/meshcode-backend-wt/meshcode/self_update.py +0 -345
- meshcode-2.11.83/meshcode-backend-wt/meshcode/setup_clients.py +0 -926
- meshcode-2.11.83/meshcode-backend-wt/scripts/sentinel.py +0 -257
- meshcode-2.11.83/meshcode-backend-wt/tests/test_rpc_migrations.py +0 -387
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/__init__.py +0 -82
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/ascii_art.py +0 -638
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/cli.py +0 -42
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/comms_v4.py +0 -3563
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/compat.py +0 -174
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/error_hints.py +0 -74
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/exceptions.py +0 -52
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/invites.py +0 -406
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/launcher.py +0 -353
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/launcher_install.py +0 -414
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__init__.py +0 -22
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__main__.py +0 -62
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/backend.py +0 -1261
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/realtime.py +0 -460
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/server.py +0 -4117
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_backend.py +0 -86
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_realtime.py +0 -95
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_server_wrapper.py +0 -117
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/preferences.py +0 -260
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/protocol_v2.py +0 -129
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/quickstart.py +0 -148
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/run_agent.py +0 -958
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/secrets.py +0 -365
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/self_update.py +0 -345
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/setup_clients.py +0 -926
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/supervisor.py +0 -186
- meshcode-2.11.83/meshcode-noun-wt/build/lib/meshcode/upload.py +0 -125
- meshcode-2.11.83/meshcode-noun-wt/comms_v4.py +0 -1941
- meshcode-2.11.83/meshcode-noun-wt/meshcode/__init__.py +0 -82
- meshcode-2.11.83/meshcode-noun-wt/meshcode/ascii_art.py +0 -638
- meshcode-2.11.83/meshcode-noun-wt/meshcode/cli.py +0 -42
- meshcode-2.11.83/meshcode-noun-wt/meshcode/comms_v4.py +0 -3563
- meshcode-2.11.83/meshcode-noun-wt/meshcode/compat.py +0 -174
- meshcode-2.11.83/meshcode-noun-wt/meshcode/error_hints.py +0 -74
- meshcode-2.11.83/meshcode-noun-wt/meshcode/exceptions.py +0 -52
- meshcode-2.11.83/meshcode-noun-wt/meshcode/invites.py +0 -406
- meshcode-2.11.83/meshcode-noun-wt/meshcode/launcher.py +0 -353
- meshcode-2.11.83/meshcode-noun-wt/meshcode/launcher_install.py +0 -414
- meshcode-2.11.83/meshcode-noun-wt/meshcode/meshcode_mcp/__init__.py +0 -22
- meshcode-2.11.83/meshcode-noun-wt/meshcode/meshcode_mcp/__main__.py +0 -62
- meshcode-2.11.83/meshcode-noun-wt/meshcode/meshcode_mcp/backend.py +0 -1261
- meshcode-2.11.83/meshcode-noun-wt/meshcode/meshcode_mcp/realtime.py +0 -460
- meshcode-2.11.83/meshcode-noun-wt/meshcode/meshcode_mcp/server.py +0 -4117
- meshcode-2.11.83/meshcode-noun-wt/meshcode/meshcode_mcp/test_backend.py +0 -86
- meshcode-2.11.83/meshcode-noun-wt/meshcode/meshcode_mcp/test_realtime.py +0 -95
- meshcode-2.11.83/meshcode-noun-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -117
- meshcode-2.11.83/meshcode-noun-wt/meshcode/preferences.py +0 -260
- meshcode-2.11.83/meshcode-noun-wt/meshcode/protocol_v2.py +0 -129
- meshcode-2.11.83/meshcode-noun-wt/meshcode/quickstart.py +0 -148
- meshcode-2.11.83/meshcode-noun-wt/meshcode/run_agent.py +0 -958
- meshcode-2.11.83/meshcode-noun-wt/meshcode/secrets.py +0 -365
- meshcode-2.11.83/meshcode-noun-wt/meshcode/self_update.py +0 -345
- meshcode-2.11.83/meshcode-noun-wt/meshcode/setup_clients.py +0 -926
- meshcode-2.11.83/meshcode-noun-wt/meshcode/supervisor.py +0 -186
- meshcode-2.11.83/meshcode-noun-wt/meshcode/upload.py +0 -125
- meshcode-2.11.83/meshcode-noun-wt/scripts/sentinel.py +0 -257
- meshcode-2.11.83/meshcode-noun-wt/tests/test_core.py +0 -216
- meshcode-2.11.83/meshcode-noun-wt/tests/test_cross_agent_messaging.py +0 -366
- meshcode-2.11.83/meshcode-noun-wt/tests/test_esc_deaf_state.py +0 -361
- meshcode-2.11.83/meshcode-noun-wt/tests/test_exceptions.py +0 -107
- meshcode-2.11.83/meshcode-noun-wt/tests/test_mark_read_batch.py +0 -200
- meshcode-2.11.83/meshcode-noun-wt/tests/test_migration_integrity.py +0 -176
- meshcode-2.11.83/meshcode-noun-wt/tests/test_realtime_event_freshness.py +0 -236
- meshcode-2.11.83/meshcode-noun-wt/tests/test_rls_cross_tenant.py +0 -255
- meshcode-2.11.83/meshcode-noun-wt/tests/test_rpc_migrations.py +0 -387
- meshcode-2.11.83/meshcode-noun-wt/tests/test_security_regressions.py +0 -171
- meshcode-2.11.83/meshcode-noun-wt/tests/test_sentinel.py +0 -148
- meshcode-2.11.83/meshcode-noun-wt/tests/test_status_enum_coverage.py +0 -231
- meshcode-2.11.83/meshcode-tasks-wt/comms_v4.py +0 -1941
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/__init__.py +0 -82
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/ascii_art.py +0 -638
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/cli.py +0 -42
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/comms_v4.py +0 -3563
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/compat.py +0 -174
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/error_hints.py +0 -74
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/exceptions.py +0 -52
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/invites.py +0 -406
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/launcher.py +0 -353
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/launcher_install.py +0 -414
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/meshcode_mcp/__init__.py +0 -22
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/meshcode_mcp/__main__.py +0 -62
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/meshcode_mcp/backend.py +0 -1261
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/meshcode_mcp/realtime.py +0 -460
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/meshcode_mcp/server.py +0 -4117
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/meshcode_mcp/test_backend.py +0 -86
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/meshcode_mcp/test_realtime.py +0 -95
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -117
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/preferences.py +0 -260
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/protocol_v2.py +0 -129
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/quickstart.py +0 -148
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/run_agent.py +0 -958
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/secrets.py +0 -365
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/self_update.py +0 -345
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/setup_clients.py +0 -926
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/supervisor.py +0 -186
- meshcode-2.11.83/meshcode-tasks-wt/meshcode/upload.py +0 -125
- meshcode-2.11.83/meshcode-tasks-wt/scripts/sentinel.py +0 -257
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_core.py +0 -216
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_cross_agent_messaging.py +0 -366
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_esc_deaf_state.py +0 -361
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_exceptions.py +0 -107
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_mark_read_batch.py +0 -200
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_migration_integrity.py +0 -176
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_realtime_event_freshness.py +0 -236
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_rls_cross_tenant.py +0 -255
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_rpc_migrations.py +0 -387
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_security_regressions.py +0 -171
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_sentinel.py +0 -148
- meshcode-2.11.83/meshcode-tasks-wt/tests/test_status_enum_coverage.py +0 -231
- meshcode-2.11.83/meshcode.egg-info/SOURCES.txt +0 -242
- meshcode-2.11.83/meshcode.egg-info/top_level.txt +0 -4
- meshcode-2.11.83/tests/test_autonomous_prompt_inject 2.py +0 -126
- meshcode-2.11.83/tests/test_core.py +0 -216
- meshcode-2.11.83/tests/test_cross_agent_messaging.py +0 -366
- meshcode-2.11.83/tests/test_esc_deaf_state.py +0 -361
- meshcode-2.11.83/tests/test_exceptions.py +0 -107
- meshcode-2.11.83/tests/test_mark_read_batch.py +0 -200
- meshcode-2.11.83/tests/test_migration_integrity.py +0 -176
- meshcode-2.11.83/tests/test_realtime_event_freshness.py +0 -236
- meshcode-2.11.83/tests/test_rls_cross_tenant.py +0 -255
- meshcode-2.11.83/tests/test_security_regressions.py +0 -171
- meshcode-2.11.83/tests/test_sentinel.py +0 -148
- meshcode-2.11.83/tests/test_status_enum_coverage.py +0 -231
- {meshcode-2.11.83 → meshcode-2.11.84}/README.md +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/__main__.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/_stop_hook_template.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/atomic_push.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/claude_update.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/cli.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/compat.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/daemon.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/date_parse.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/doctor.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/error_hints.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/exceptions.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/invites.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/launcher.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/preferences.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/quickstart.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/rpc_allowlist.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/run_agent.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/scripts/check_secrets.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/scripts/race_rate_harness.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/secrets.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/self_update.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/supervisor.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode/up.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/meshcode/upload.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/setup.cfg +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_auto_update_hardening.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_autonomous_closegap_1.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_autonomous_closegap_2.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_autonomous_closegap_3.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_autonomous_prompt_inject.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_boot_bug_regression.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_color_truecolor.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_core.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_date_parse.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_doctor.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_epistemic_v1_python_sdk.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_epistemic_v1_stop_conditions.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_exceptions.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_file_upload.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_init_device_code.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_install_guard.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_lease_sigterm_release.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_marketplace_ratings.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_rpc_grants.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_run_agent_dry_run.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_run_agent_no_server_import.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_self_update_user_site.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_sentinel.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_setup_path.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_sleep_signals.py +0 -0
- {meshcode-2.11.83/meshcode-backend-wt → meshcode-2.11.84}/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_stay_on_loop_hook.py +0 -0
- {meshcode-2.11.83 → meshcode-2.11.84}/tests/test_wait_open_tasks_contradiction.py +0 -0
|
@@ -36,6 +36,7 @@ import json
|
|
|
36
36
|
import os
|
|
37
37
|
import shlex
|
|
38
38
|
import shutil
|
|
39
|
+
import signal as _signal
|
|
39
40
|
import subprocess
|
|
40
41
|
import sys
|
|
41
42
|
import time
|
|
@@ -260,8 +261,12 @@ def _spawn_agent(project: str, agent: str, headless: bool = False) -> bool:
|
|
|
260
261
|
try:
|
|
261
262
|
# `python -m meshcode` (NOT the meshcode.exe shim) so the .exe isn't held open by the
|
|
262
263
|
# agent -> a background `pip install -U` can replace it on Windows (task 14782bb4 #4).
|
|
263
|
-
subprocess.Popen([sys.executable, "-m", "meshcode", "run", target], **kwargs)
|
|
264
|
-
|
|
264
|
+
proc = subprocess.Popen([sys.executable, "-m", "meshcode", "run", target], **kwargs)
|
|
265
|
+
# LAUNCH-NO-WINDOW (task 35bee961): record the headless PID so the Stop sweep
|
|
266
|
+
# (_do_stops) can hard-kill it — a headless agent has NO window for Samuel to
|
|
267
|
+
# close, so desired_state='stopped' must be enforced by killing the process.
|
|
268
|
+
_record_headless_pid(target, proc.pid)
|
|
269
|
+
_log(f"spawned {target} HEADLESS (no window, {sys.platform}; pid={proc.pid}; log={log_path})")
|
|
265
270
|
return True
|
|
266
271
|
except Exception as e:
|
|
267
272
|
_log(f"WARN: headless spawn {target} failed: {e}")
|
|
@@ -369,6 +374,151 @@ def _save_state(st: dict) -> None:
|
|
|
369
374
|
pass
|
|
370
375
|
|
|
371
376
|
|
|
377
|
+
# ------------------------------------------------------------------
|
|
378
|
+
# Stop — hard-kill a HEADLESS agent (task 35bee961). A headless agent has no
|
|
379
|
+
# window Samuel can close, so a Stop (desired_state='stopped') that the agent
|
|
380
|
+
# doesn't honor cooperatively (must_exit) would otherwise run forever. We record
|
|
381
|
+
# each headless spawn's PID (persisted across hostd restarts) and kill it when the
|
|
382
|
+
# cloud says it should be stopped but it's still heartbeating.
|
|
383
|
+
# ------------------------------------------------------------------
|
|
384
|
+
|
|
385
|
+
def _record_headless_pid(target: str, pid: int) -> None:
|
|
386
|
+
try:
|
|
387
|
+
st = _load_state()
|
|
388
|
+
pids = st.get("headless_pids") or {}
|
|
389
|
+
pids[target] = pid
|
|
390
|
+
st["headless_pids"] = pids
|
|
391
|
+
_save_state(st)
|
|
392
|
+
except Exception:
|
|
393
|
+
pass
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def _pid_cmdline(pid: int) -> str:
|
|
397
|
+
"""Best-effort command line for a pid (to avoid killing a reused PID). '' on failure."""
|
|
398
|
+
try:
|
|
399
|
+
if sys.platform == "win32":
|
|
400
|
+
out = subprocess.run(
|
|
401
|
+
["wmic", "process", "where", f"ProcessId={pid}", "get", "CommandLine"],
|
|
402
|
+
capture_output=True, text=True, timeout=5).stdout
|
|
403
|
+
else:
|
|
404
|
+
out = subprocess.run(
|
|
405
|
+
["ps", "-o", "args=", "-p", str(pid)],
|
|
406
|
+
capture_output=True, text=True, timeout=5).stdout
|
|
407
|
+
return out or ""
|
|
408
|
+
except Exception:
|
|
409
|
+
return ""
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def _discover_agent_pids(target: str) -> list:
|
|
413
|
+
"""Fallback PID discovery by command line, for agents spawned before this hostd
|
|
414
|
+
(no recorded PID) or after a state-file loss. Matches `meshcode run <target>`.
|
|
415
|
+
Best-effort; returns [] on any failure."""
|
|
416
|
+
pids = []
|
|
417
|
+
try:
|
|
418
|
+
if sys.platform == "win32":
|
|
419
|
+
out = subprocess.run(
|
|
420
|
+
["wmic", "process", "where", "name='python.exe'", "get", "ProcessId,CommandLine", "/FORMAT:LIST"],
|
|
421
|
+
capture_output=True, text=True, timeout=8).stdout
|
|
422
|
+
block_pid = None
|
|
423
|
+
for line in out.splitlines():
|
|
424
|
+
line = line.strip()
|
|
425
|
+
if line.startswith("CommandLine="):
|
|
426
|
+
block_pid = ("meshcode" in line and f"run {target}" in line)
|
|
427
|
+
elif line.startswith("ProcessId=") and block_pid:
|
|
428
|
+
try:
|
|
429
|
+
pids.append(int(line.split("=", 1)[1]))
|
|
430
|
+
except Exception:
|
|
431
|
+
pass
|
|
432
|
+
block_pid = None
|
|
433
|
+
else:
|
|
434
|
+
out = subprocess.run(
|
|
435
|
+
["pgrep", "-f", f"meshcode run {target}"],
|
|
436
|
+
capture_output=True, text=True, timeout=8).stdout
|
|
437
|
+
for ln in out.split():
|
|
438
|
+
try:
|
|
439
|
+
pids.append(int(ln))
|
|
440
|
+
except Exception:
|
|
441
|
+
pass
|
|
442
|
+
except Exception:
|
|
443
|
+
pass
|
|
444
|
+
return pids
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def _kill_headless_pid(target: str, pid: int) -> bool:
|
|
448
|
+
"""Hard-kill a recorded headless PID + its child tree. Guards against PID reuse by
|
|
449
|
+
confirming the cmdline still looks like this meshcode agent. Returns True if killed."""
|
|
450
|
+
if not pid:
|
|
451
|
+
return False
|
|
452
|
+
cl = _pid_cmdline(pid).lower()
|
|
453
|
+
# Reuse guard: a headless agent's process is either `python -m meshcode run ...`
|
|
454
|
+
# (Windows: parent stays alive) or `claude ...` (POSIX: execvp'd to the editor). If
|
|
455
|
+
# we got a cmdline and it's NEITHER, the PID was reused by something unrelated — skip.
|
|
456
|
+
if cl and ("meshcode" not in cl and "claude" not in cl):
|
|
457
|
+
_log(f"STOP {target}: pid {pid} cmdline no longer matches (reused) — skip kill")
|
|
458
|
+
return False
|
|
459
|
+
try:
|
|
460
|
+
if sys.platform == "win32":
|
|
461
|
+
# /T kills the whole tree (python parent + cmd.exe + claude child), /F forces.
|
|
462
|
+
subprocess.run(["taskkill", "/PID", str(pid), "/T", "/F"],
|
|
463
|
+
capture_output=True, timeout=10)
|
|
464
|
+
else:
|
|
465
|
+
try:
|
|
466
|
+
os.killpg(os.getpgid(pid), _signal.SIGTERM) # start_new_session => own group
|
|
467
|
+
except Exception:
|
|
468
|
+
os.kill(pid, _signal.SIGTERM)
|
|
469
|
+
time.sleep(1.5)
|
|
470
|
+
try:
|
|
471
|
+
os.kill(pid, 0) # still alive?
|
|
472
|
+
os.killpg(os.getpgid(pid), _signal.SIGKILL)
|
|
473
|
+
except ProcessLookupError:
|
|
474
|
+
pass
|
|
475
|
+
except Exception:
|
|
476
|
+
try:
|
|
477
|
+
os.kill(pid, _signal.SIGKILL)
|
|
478
|
+
except Exception:
|
|
479
|
+
pass
|
|
480
|
+
_log(f"STOP {target}: hard-killed headless pid {pid}")
|
|
481
|
+
return True
|
|
482
|
+
except Exception as e:
|
|
483
|
+
_log(f"WARN: STOP {target} kill pid {pid} failed: {e}")
|
|
484
|
+
return False
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def _do_stops(api_key: str, host_id: str) -> int:
|
|
488
|
+
"""One stop sweep: hard-kill headless agents the cloud marked stopped but that are
|
|
489
|
+
still alive (cooperative must_exit didn't land). Returns number killed."""
|
|
490
|
+
res = _rpc("mc_agents_to_stop", {"p_api_key": api_key, "p_host_id": host_id})
|
|
491
|
+
if not res or not res.get("ok"):
|
|
492
|
+
return 0
|
|
493
|
+
agents = res.get("agents") or []
|
|
494
|
+
if not agents:
|
|
495
|
+
return 0
|
|
496
|
+
st = _load_state()
|
|
497
|
+
pids = st.get("headless_pids") or {}
|
|
498
|
+
n = 0
|
|
499
|
+
for a in agents:
|
|
500
|
+
proj, agent = a.get("project_name"), a.get("agent")
|
|
501
|
+
if not proj or not agent:
|
|
502
|
+
continue
|
|
503
|
+
target = f"{proj}/{agent}"
|
|
504
|
+
pid = pids.get(target)
|
|
505
|
+
killed = bool(pid) and _kill_headless_pid(target, pid)
|
|
506
|
+
if pid and killed:
|
|
507
|
+
pids.pop(target, None)
|
|
508
|
+
if not killed:
|
|
509
|
+
# No recorded PID (spawned by an older hostd / state lost) OR the recorded
|
|
510
|
+
# PID was stale — discover by command line and kill.
|
|
511
|
+
for dpid in _discover_agent_pids(target):
|
|
512
|
+
if _kill_headless_pid(target, dpid):
|
|
513
|
+
killed = True
|
|
514
|
+
pids.pop(target, None)
|
|
515
|
+
if killed:
|
|
516
|
+
n += 1
|
|
517
|
+
st["headless_pids"] = pids
|
|
518
|
+
_save_state(st)
|
|
519
|
+
return n
|
|
520
|
+
|
|
521
|
+
|
|
372
522
|
def _do_recycles(api_key: str, host_id: str) -> int:
|
|
373
523
|
"""Uptime-based recycle at task boundary. Returns number recycled."""
|
|
374
524
|
cfg = _rpc("mc_host_config_get", {"p_api_key": api_key, "p_host_id": host_id})
|
|
@@ -833,9 +983,10 @@ def cmd_hostd(args: list) -> int:
|
|
|
833
983
|
relaunched = _do_respawns(api_key, host_id)
|
|
834
984
|
recycled = _do_recycles(api_key, host_id)
|
|
835
985
|
ver_recycled = _do_version_recycles(api_key, host_id)
|
|
986
|
+
stopped = _do_stops(api_key, host_id)
|
|
836
987
|
_up = int(time.monotonic() - _spawn_mono)
|
|
837
|
-
if relaunched or recycled or ver_recycled:
|
|
838
|
-
_log(f"sweep done (uptime={_up}s) — {relaunched} respawned, {recycled} recycled, {ver_recycled} version-recycled")
|
|
988
|
+
if relaunched or recycled or ver_recycled or stopped:
|
|
989
|
+
_log(f"sweep done (uptime={_up}s) — {relaunched} respawned, {recycled} recycled, {ver_recycled} version-recycled, {stopped} stopped")
|
|
839
990
|
elif time.monotonic() - _last_alive_log >= 60:
|
|
840
991
|
_log(f"alive — uptime={_up}s")
|
|
841
992
|
_last_alive_log = time.monotonic()
|
|
@@ -117,9 +117,12 @@ def _spawn_terminal_windows(cmd: str) -> tuple[bool, str]:
|
|
|
117
117
|
wt = str(cand)
|
|
118
118
|
if wt:
|
|
119
119
|
try:
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
|
|
120
|
+
# LAUNCH-NO-WINDOW (task 35bee961, commander-corrected): `-w new` forces a
|
|
121
|
+
# BRAND-NEW Windows Terminal window (freshly created => FOREGROUND/focused), which
|
|
122
|
+
# is what Samuel wants ("ventana nueva ENFOCADA"). The old `-w 0 nt` opened a tab in
|
|
123
|
+
# the most-recently-used window — frequently minimized/background, so the launch
|
|
124
|
+
# looked like "nada pasó".
|
|
125
|
+
subprocess.Popen([wt, "-w", "new", "nt", "cmd", "/k", cmd])
|
|
123
126
|
return True, "wt"
|
|
124
127
|
except Exception as e:
|
|
125
128
|
return False, f"wt.exe: {e}"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
meshcode/__init__.py
|
|
4
|
+
meshcode/__main__.py
|
|
5
|
+
meshcode/_stop_hook_template.py
|
|
6
|
+
meshcode/ascii_art.py
|
|
7
|
+
meshcode/atomic_push.py
|
|
8
|
+
meshcode/claude_update.py
|
|
9
|
+
meshcode/cli.py
|
|
10
|
+
meshcode/comms_v4.py
|
|
11
|
+
meshcode/compat.py
|
|
12
|
+
meshcode/daemon.py
|
|
13
|
+
meshcode/date_parse.py
|
|
14
|
+
meshcode/doctor.py
|
|
15
|
+
meshcode/error_hints.py
|
|
16
|
+
meshcode/exceptions.py
|
|
17
|
+
meshcode/hostd.py
|
|
18
|
+
meshcode/invites.py
|
|
19
|
+
meshcode/launcher.py
|
|
20
|
+
meshcode/launcher_install.py
|
|
21
|
+
meshcode/preferences.py
|
|
22
|
+
meshcode/protocol_handler.py
|
|
23
|
+
meshcode/protocol_v2.py
|
|
24
|
+
meshcode/quickstart.py
|
|
25
|
+
meshcode/rpc_allowlist.py
|
|
26
|
+
meshcode/run_agent.py
|
|
27
|
+
meshcode/secrets.py
|
|
28
|
+
meshcode/self_update.py
|
|
29
|
+
meshcode/setup_clients.py
|
|
30
|
+
meshcode/supervisor.py
|
|
31
|
+
meshcode/up.py
|
|
32
|
+
meshcode/upload.py
|
|
33
|
+
meshcode.egg-info/PKG-INFO
|
|
34
|
+
meshcode.egg-info/SOURCES.txt
|
|
35
|
+
meshcode.egg-info/dependency_links.txt
|
|
36
|
+
meshcode.egg-info/entry_points.txt
|
|
37
|
+
meshcode.egg-info/requires.txt
|
|
38
|
+
meshcode.egg-info/top_level.txt
|
|
39
|
+
meshcode/meshcode_mcp/__init__.py
|
|
40
|
+
meshcode/meshcode_mcp/__main__.py
|
|
41
|
+
meshcode/meshcode_mcp/backend.py
|
|
42
|
+
meshcode/meshcode_mcp/realtime.py
|
|
43
|
+
meshcode/meshcode_mcp/server.py
|
|
44
|
+
meshcode/meshcode_mcp/sleep_signals.py
|
|
45
|
+
meshcode/meshcode_mcp/test_backend.py
|
|
46
|
+
meshcode/meshcode_mcp/test_boot_timing.py
|
|
47
|
+
meshcode/meshcode_mcp/test_install_guard.py
|
|
48
|
+
meshcode/meshcode_mcp/test_prefs_claude_version.py
|
|
49
|
+
meshcode/meshcode_mcp/test_realtime.py
|
|
50
|
+
meshcode/meshcode_mcp/test_server_wrapper.py
|
|
51
|
+
meshcode/scripts/check_secrets.py
|
|
52
|
+
meshcode/scripts/race_rate_harness.py
|
|
53
|
+
tests/test_auto_update_hardening.py
|
|
54
|
+
tests/test_autonomous_closegap_1.py
|
|
55
|
+
tests/test_autonomous_closegap_2.py
|
|
56
|
+
tests/test_autonomous_closegap_3.py
|
|
57
|
+
tests/test_autonomous_prompt_inject.py
|
|
58
|
+
tests/test_boot_bug_regression.py
|
|
59
|
+
tests/test_color_truecolor.py
|
|
60
|
+
tests/test_core.py
|
|
61
|
+
tests/test_cross_agent_messaging.py
|
|
62
|
+
tests/test_date_parse.py
|
|
63
|
+
tests/test_doctor.py
|
|
64
|
+
tests/test_epistemic_v1_python_sdk.py
|
|
65
|
+
tests/test_epistemic_v1_stop_conditions.py
|
|
66
|
+
tests/test_esc_deaf_state.py
|
|
67
|
+
tests/test_exceptions.py
|
|
68
|
+
tests/test_file_upload.py
|
|
69
|
+
tests/test_init_device_code.py
|
|
70
|
+
tests/test_install_guard.py
|
|
71
|
+
tests/test_lease_sigterm_release.py
|
|
72
|
+
tests/test_mark_read_batch.py
|
|
73
|
+
tests/test_marketplace_ratings.py
|
|
74
|
+
tests/test_migration_integrity.py
|
|
75
|
+
tests/test_realtime_event_freshness.py
|
|
76
|
+
tests/test_rls_cross_tenant.py
|
|
77
|
+
tests/test_rpc_grants.py
|
|
78
|
+
tests/test_rpc_migrations.py
|
|
79
|
+
tests/test_run_agent_dry_run.py
|
|
80
|
+
tests/test_run_agent_no_server_import.py
|
|
81
|
+
tests/test_security_regressions.py
|
|
82
|
+
tests/test_self_update_user_site.py
|
|
83
|
+
tests/test_sentinel.py
|
|
84
|
+
tests/test_setup_path.py
|
|
85
|
+
tests/test_sleep_signals.py
|
|
86
|
+
tests/test_status_enum_coverage.py
|
|
87
|
+
tests/test_stay_on_loop_hook.py
|
|
88
|
+
tests/test_wait_open_tasks_contradiction.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
meshcode
|