meshcode 2.11.10__tar.gz → 2.11.11__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.10 → meshcode-2.11.11}/PKG-INFO +1 -1
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/__init__.py +1 -1
- meshcode-2.11.11/meshcode/__main__.py +42 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/comms_v4.py +64 -1
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/server.py +25 -2
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/run_agent.py +10 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode.egg-info/SOURCES.txt +3 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/pyproject.toml +1 -1
- meshcode-2.11.11/tests/test_color_truecolor.py +83 -0
- meshcode-2.11.11/tests/test_setup_path.py +66 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/README.md +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/_stop_hook_template.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/cli.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/compat.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/daemon.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/doctor.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/error_hints.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/invites.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/launcher.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/preferences.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/protocol_handler.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/quickstart.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/scripts/check_secrets.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/scripts/race_rate_harness.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/secrets.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/self_update.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/supervisor.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode/upload.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/comms_v4.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/cli.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/compat.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/error_hints.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/invites.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/launcher.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/preferences.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/quickstart.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/run_agent.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/secrets.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/self_update.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/supervisor.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/upload.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/scripts/sentinel.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_core.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_sentinel.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/cli.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/compat.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/error_hints.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/invites.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/launcher.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/preferences.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/quickstart.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/run_agent.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/secrets.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/self_update.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/supervisor.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/upload.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/comms_v4.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/cli.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/compat.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/error_hints.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/invites.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/launcher.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/preferences.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/quickstart.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/run_agent.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/secrets.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/self_update.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/supervisor.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/meshcode/upload.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/scripts/sentinel.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_core.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_sentinel.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/comms_v4.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/cli.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/compat.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/error_hints.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/invites.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/launcher.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/meshcode_mcp/server.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/preferences.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/quickstart.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/run_agent.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/secrets.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/self_update.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/setup_clients.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/supervisor.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/meshcode/upload.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/scripts/sentinel.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_core.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_sentinel.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode-tasks-wt/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/setup.cfg +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_auto_update_hardening.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_boot_bug_regression.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_core.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_doctor.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_epistemic_v1_python_sdk.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_epistemic_v1_stop_conditions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_exceptions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_install_guard.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_lease_sigterm_release.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_sentinel.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_sleep_signals.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_stay_on_loop_hook.py +0 -0
- {meshcode-2.11.10 → meshcode-2.11.11}/tests/test_wait_open_tasks_contradiction.py +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Helpful error when user invokes `python -m meshcode` because the
|
|
2
|
+
console-script isn't on PATH yet (B5 friction).
|
|
3
|
+
|
|
4
|
+
Also dispatches `python -m meshcode setup-path` to the real CLI so the
|
|
5
|
+
user can fix PATH without needing the `meshcode` binary on PATH first.
|
|
6
|
+
"""
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def main():
|
|
12
|
+
# If the user explicitly asked to set up PATH, delegate to the real CLI.
|
|
13
|
+
if len(sys.argv) > 1 and sys.argv[1] == "setup-path":
|
|
14
|
+
from meshcode import comms_v4 as _cv # noqa: F401
|
|
15
|
+
sys.argv[0] = "meshcode"
|
|
16
|
+
# comms_v4 runs main() at module load via `if __name__ == "__main__"`.
|
|
17
|
+
# Re-exec the body by importing as __main__ would require executing
|
|
18
|
+
# the module again; simpler: invoke via runpy.
|
|
19
|
+
import runpy
|
|
20
|
+
runpy.run_module("meshcode.comms_v4", run_name="__main__", alter_sys=True)
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
# Otherwise: the user is here because `meshcode` isn't on PATH.
|
|
24
|
+
print()
|
|
25
|
+
print(" meshcode is installed but the `meshcode` command isn't on your PATH.")
|
|
26
|
+
print()
|
|
27
|
+
print(" Quick fix:")
|
|
28
|
+
print(f" {sys.executable} -m meshcode setup-path")
|
|
29
|
+
print()
|
|
30
|
+
print(" Or manually:")
|
|
31
|
+
v = sys.version_info
|
|
32
|
+
if sys.platform == "darwin":
|
|
33
|
+
print(f' export PATH="$HOME/Library/Python/{v.major}.{v.minor}/bin:$PATH"')
|
|
34
|
+
else:
|
|
35
|
+
print(' export PATH="$(python3 -m site --user-base)/bin:$PATH"')
|
|
36
|
+
print()
|
|
37
|
+
print(" Then re-run: meshcode --help")
|
|
38
|
+
sys.exit(1)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
if __name__ == "__main__":
|
|
42
|
+
main()
|
|
@@ -2868,7 +2868,7 @@ if __name__ == "__main__":
|
|
|
2868
2868
|
# doctor, help, version, login, prefs, launcher don't need auth.
|
|
2869
2869
|
_NO_AUTH_CMDS = {"doctor", "compat", "upgrade", "help", "--help", "-h", "login",
|
|
2870
2870
|
"init", "prefs", "launcher", "--version", "-V", "version",
|
|
2871
|
-
"whoami", "profiles", "scan"}
|
|
2871
|
+
"whoami", "profiles", "scan", "setup-path"}
|
|
2872
2872
|
if cmd not in _NO_AUTH_CMDS:
|
|
2873
2873
|
_cli_key = _load_api_key_for_cli()
|
|
2874
2874
|
if not _cli_key:
|
|
@@ -3479,6 +3479,69 @@ if __name__ == "__main__":
|
|
|
3479
3479
|
print(" meshcode prefs reset")
|
|
3480
3480
|
sys.exit(1)
|
|
3481
3481
|
|
|
3482
|
+
elif cmd == "setup-path":
|
|
3483
|
+
# B5: append Python user-bin to user's shell rc file (idempotent).
|
|
3484
|
+
# Friction #8 fix: after `pip install --user meshcode`, `meshcode`
|
|
3485
|
+
# isn't on PATH; this gives the user a one-command remediation.
|
|
3486
|
+
import platform as _pl
|
|
3487
|
+
import subprocess as _sp
|
|
3488
|
+
_v = sys.version_info
|
|
3489
|
+
if _pl.system() == "Darwin":
|
|
3490
|
+
user_bin = os.path.expanduser(f"~/Library/Python/{_v.major}.{_v.minor}/bin")
|
|
3491
|
+
else:
|
|
3492
|
+
try:
|
|
3493
|
+
user_bin = _sp.check_output(
|
|
3494
|
+
[sys.executable, "-m", "site", "--user-base"],
|
|
3495
|
+
text=True, timeout=5,
|
|
3496
|
+
).strip() + "/bin"
|
|
3497
|
+
except Exception:
|
|
3498
|
+
user_bin = os.path.expanduser("~/.local/bin")
|
|
3499
|
+
|
|
3500
|
+
shell = os.environ.get("SHELL", "")
|
|
3501
|
+
if "zsh" in shell:
|
|
3502
|
+
rc = os.path.expanduser("~/.zshrc")
|
|
3503
|
+
fish = False
|
|
3504
|
+
elif "fish" in shell:
|
|
3505
|
+
rc = os.path.expanduser("~/.config/fish/config.fish")
|
|
3506
|
+
fish = True
|
|
3507
|
+
else:
|
|
3508
|
+
rc = os.path.expanduser("~/.bashrc")
|
|
3509
|
+
fish = False
|
|
3510
|
+
|
|
3511
|
+
marker = "# meshcode: PATH for user-installed Python binaries"
|
|
3512
|
+
line = (f"set -gx PATH {user_bin} $PATH" if fish
|
|
3513
|
+
else f'export PATH="{user_bin}:$PATH"')
|
|
3514
|
+
|
|
3515
|
+
existing = ""
|
|
3516
|
+
try:
|
|
3517
|
+
if os.path.exists(rc):
|
|
3518
|
+
with open(rc) as f:
|
|
3519
|
+
existing = f.read()
|
|
3520
|
+
except Exception:
|
|
3521
|
+
pass
|
|
3522
|
+
|
|
3523
|
+
if user_bin in existing:
|
|
3524
|
+
print(f"[meshcode] {rc} already exports {user_bin} — nothing to do.")
|
|
3525
|
+
sys.exit(0)
|
|
3526
|
+
|
|
3527
|
+
try:
|
|
3528
|
+
os.makedirs(os.path.dirname(rc), exist_ok=True)
|
|
3529
|
+
with open(rc, "a") as f:
|
|
3530
|
+
f.write(f"\n{marker}\n{line}\n")
|
|
3531
|
+
print(f"[meshcode] Appended PATH export to {rc}")
|
|
3532
|
+
print(f"[meshcode] Open a new terminal OR run: source {rc}")
|
|
3533
|
+
print(f"[meshcode] Then: meshcode --help")
|
|
3534
|
+
sys.exit(0)
|
|
3535
|
+
except PermissionError:
|
|
3536
|
+
print(f"[meshcode] ERROR: cannot write {rc} (permission denied).")
|
|
3537
|
+
print(f"[meshcode] Manually add this line to your shell rc:")
|
|
3538
|
+
print(f" {line}")
|
|
3539
|
+
sys.exit(1)
|
|
3540
|
+
except Exception as _spe:
|
|
3541
|
+
print(f"[meshcode] ERROR: {_spe}")
|
|
3542
|
+
print(f"[meshcode] Manually add: {line}")
|
|
3543
|
+
sys.exit(1)
|
|
3544
|
+
|
|
3482
3545
|
elif cmd == "upgrade":
|
|
3483
3546
|
# meshcode upgrade — interactive foreground upgrade
|
|
3484
3547
|
import importlib
|
|
@@ -45,9 +45,21 @@ _ANSI_RGB = [
|
|
|
45
45
|
(255, 85, 85), (85, 255, 255), (255, 85, 255), (85, 255, 85), (85, 85, 255),
|
|
46
46
|
]
|
|
47
47
|
|
|
48
|
+
# BUG-AUDIO-COLOR fix (task e552412a, 2026-05-19): use 24-bit truecolor
|
|
49
|
+
# escapes when the terminal supports them so every terminal renders the
|
|
50
|
+
# same agent color (4-bit palette indices are remapped by terminal themes,
|
|
51
|
+
# producing the cross-machine mismatch Samuel saw).
|
|
52
|
+
_TRUECOLOR_OK = os.environ.get("COLORTERM", "").lower() in ("truecolor", "24bit")
|
|
53
|
+
|
|
48
54
|
|
|
49
55
|
def _hex_to_ansi(hex_color: str) -> str:
|
|
50
|
-
"""
|
|
56
|
+
"""Return ANSI escape for a hex color.
|
|
57
|
+
|
|
58
|
+
On truecolor-capable terminals returns 24-bit truecolor (\\e[38;2;R;G;Bm) so
|
|
59
|
+
the color bypasses palette remapping. Falls back to nearest 4-bit ANSI
|
|
60
|
+
palette index when COLORTERM is not truecolor.
|
|
61
|
+
Returns None if hex is malformed.
|
|
62
|
+
"""
|
|
51
63
|
hx = hex_color.strip().lstrip("#")
|
|
52
64
|
if len(hx) != 6:
|
|
53
65
|
return None
|
|
@@ -55,6 +67,9 @@ def _hex_to_ansi(hex_color: str) -> str:
|
|
|
55
67
|
r, g, b = int(hx[0:2], 16), int(hx[2:4], 16), int(hx[4:6], 16)
|
|
56
68
|
except ValueError:
|
|
57
69
|
return None
|
|
70
|
+
if _TRUECOLOR_OK:
|
|
71
|
+
return f"\033[38;2;{r};{g};{b}m"
|
|
72
|
+
# Fallback: map to nearest 4-bit ANSI palette index
|
|
58
73
|
best_i, best_d = 0, float("inf")
|
|
59
74
|
for i, (ar, ag, ab) in enumerate(_ANSI_RGB):
|
|
60
75
|
d = (r - ar) ** 2 + (g - ag) ** 2 + (b - ab) ** 2
|
|
@@ -65,10 +80,18 @@ def _hex_to_ansi(hex_color: str) -> str:
|
|
|
65
80
|
|
|
66
81
|
|
|
67
82
|
def _agent_color(name: str) -> str:
|
|
68
|
-
"""
|
|
83
|
+
"""Profile-canonical color if cached, else a deterministic per-name color.
|
|
84
|
+
Never random — same name -> same color on every machine."""
|
|
69
85
|
if _CACHED_AGENT_COLOR:
|
|
70
86
|
return _CACHED_AGENT_COLOR
|
|
71
87
|
h = int(_hashlib.md5(name.encode()).hexdigest()[:8], 16)
|
|
88
|
+
if _TRUECOLOR_OK:
|
|
89
|
+
# Pseudo-random but deterministic 24-bit color from the hash. Clamp
|
|
90
|
+
# mid-range so the color is readable on both dark and light terminals.
|
|
91
|
+
r = max(70, min(220, (h >> 16) & 0xFF))
|
|
92
|
+
g = max(70, min(220, (h >> 8) & 0xFF))
|
|
93
|
+
b = max(70, min(220, h & 0xFF))
|
|
94
|
+
return f"\033[38;2;{r};{g};{b}m"
|
|
72
95
|
return _ANSI_COLORS[h % len(_ANSI_COLORS)]
|
|
73
96
|
|
|
74
97
|
|
|
@@ -846,6 +846,16 @@ def run(agent: str, project: Optional[str] = None, editor_override: Optional[str
|
|
|
846
846
|
except Exception:
|
|
847
847
|
pass # Soft-fail — boot must proceed regardless.
|
|
848
848
|
|
|
849
|
+
# BUG-AUDIO-COLOR fix: wait briefly for profile fetch to populate
|
|
850
|
+
# _CACHED_AGENT_COLOR before rendering the banner, so the boot art
|
|
851
|
+
# doesn't flash the deterministic-hash fallback color and then "jump"
|
|
852
|
+
# to the canonical profile color. Upper-bound 350ms.
|
|
853
|
+
try:
|
|
854
|
+
from .meshcode_mcp.server import _REGISTER_PROFILE_READY
|
|
855
|
+
_REGISTER_PROFILE_READY.wait(timeout=0.35)
|
|
856
|
+
except Exception:
|
|
857
|
+
pass
|
|
858
|
+
|
|
849
859
|
# ── Welcome banner with unique ASCII art + personality ──────────
|
|
850
860
|
try:
|
|
851
861
|
from .ascii_art import generate_art, render_welcome
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
README.md
|
|
2
2
|
pyproject.toml
|
|
3
3
|
meshcode/__init__.py
|
|
4
|
+
meshcode/__main__.py
|
|
4
5
|
meshcode/_stop_hook_template.py
|
|
5
6
|
meshcode/ascii_art.py
|
|
6
7
|
meshcode/cli.py
|
|
@@ -195,6 +196,7 @@ meshcode/scripts/check_secrets.py
|
|
|
195
196
|
meshcode/scripts/race_rate_harness.py
|
|
196
197
|
tests/test_auto_update_hardening.py
|
|
197
198
|
tests/test_boot_bug_regression.py
|
|
199
|
+
tests/test_color_truecolor.py
|
|
198
200
|
tests/test_core.py
|
|
199
201
|
tests/test_cross_agent_messaging.py
|
|
200
202
|
tests/test_doctor.py
|
|
@@ -211,6 +213,7 @@ tests/test_rls_cross_tenant.py
|
|
|
211
213
|
tests/test_rpc_migrations.py
|
|
212
214
|
tests/test_security_regressions.py
|
|
213
215
|
tests/test_sentinel.py
|
|
216
|
+
tests/test_setup_path.py
|
|
214
217
|
tests/test_sleep_signals.py
|
|
215
218
|
tests/test_status_enum_coverage.py
|
|
216
219
|
tests/test_stay_on_loop_hook.py
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""Tests for BUG-AUDIO-COLOR (task e552412a) — truecolor agent colors."""
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@pytest.fixture(autouse=True)
|
|
8
|
+
def _set_required_env(monkeypatch):
|
|
9
|
+
"""server.py requires these env vars at import."""
|
|
10
|
+
monkeypatch.setenv("MESHCODE_PROJECT", "test")
|
|
11
|
+
monkeypatch.setenv("MESHCODE_AGENT", "test")
|
|
12
|
+
monkeypatch.setenv("MESHCODE_PROJECT_ID", "00000000-0000-0000-0000-000000000000")
|
|
13
|
+
yield
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_hex_to_ansi_truecolor_format(monkeypatch):
|
|
17
|
+
from meshcode.meshcode_mcp import server as srv
|
|
18
|
+
monkeypatch.setattr(srv, "_TRUECOLOR_OK", True)
|
|
19
|
+
assert srv._hex_to_ansi("#E53935") == "\033[38;2;229;57;53m"
|
|
20
|
+
assert srv._hex_to_ansi("E53935") == "\033[38;2;229;57;53m"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_hex_to_ansi_4bit_fallback(monkeypatch):
|
|
24
|
+
from meshcode.meshcode_mcp import server as srv
|
|
25
|
+
monkeypatch.setattr(srv, "_TRUECOLOR_OK", False)
|
|
26
|
+
result = srv._hex_to_ansi("#E53935")
|
|
27
|
+
# 4-bit ANSI escape, one of the palette entries
|
|
28
|
+
assert result in srv._ANSI_COLORS
|
|
29
|
+
assert result.startswith("\033[")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_hex_to_ansi_malformed_returns_none(monkeypatch):
|
|
33
|
+
from meshcode.meshcode_mcp import server as srv
|
|
34
|
+
monkeypatch.setattr(srv, "_TRUECOLOR_OK", True)
|
|
35
|
+
assert srv._hex_to_ansi("not-hex") is None
|
|
36
|
+
assert srv._hex_to_ansi("#zzzzzz") is None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_agent_color_deterministic_truecolor(monkeypatch):
|
|
40
|
+
"""Same name → same color across calls in truecolor mode."""
|
|
41
|
+
from meshcode.meshcode_mcp import server as srv
|
|
42
|
+
monkeypatch.setattr(srv, "_CACHED_AGENT_COLOR", None)
|
|
43
|
+
monkeypatch.setattr(srv, "_TRUECOLOR_OK", True)
|
|
44
|
+
a = srv._agent_color("commander")
|
|
45
|
+
b = srv._agent_color("commander")
|
|
46
|
+
assert a == b
|
|
47
|
+
assert a.startswith("\033[38;2;") # truecolor
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_agent_color_deterministic_4bit(monkeypatch):
|
|
51
|
+
from meshcode.meshcode_mcp import server as srv
|
|
52
|
+
monkeypatch.setattr(srv, "_CACHED_AGENT_COLOR", None)
|
|
53
|
+
monkeypatch.setattr(srv, "_TRUECOLOR_OK", False)
|
|
54
|
+
a = srv._agent_color("commander")
|
|
55
|
+
b = srv._agent_color("commander")
|
|
56
|
+
assert a == b
|
|
57
|
+
assert a in srv._ANSI_COLORS
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_agent_color_cached_overrides(monkeypatch):
|
|
61
|
+
"""If _CACHED_AGENT_COLOR is set (from profile fetch), use that."""
|
|
62
|
+
from meshcode.meshcode_mcp import server as srv
|
|
63
|
+
monkeypatch.setattr(srv, "_CACHED_AGENT_COLOR", "\033[38;2;100;200;50m")
|
|
64
|
+
monkeypatch.setattr(srv, "_TRUECOLOR_OK", True)
|
|
65
|
+
assert srv._agent_color("any-name") == "\033[38;2;100;200;50m"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def test_agent_color_clamped_to_mid_range(monkeypatch):
|
|
69
|
+
"""Truecolor RGB components clamped to [70, 220] for readability on
|
|
70
|
+
both dark and light terminals."""
|
|
71
|
+
from meshcode.meshcode_mcp import server as srv
|
|
72
|
+
monkeypatch.setattr(srv, "_CACHED_AGENT_COLOR", None)
|
|
73
|
+
monkeypatch.setattr(srv, "_TRUECOLOR_OK", True)
|
|
74
|
+
# Try many names to exercise the clamp
|
|
75
|
+
for name in ("a", "bbbb", "cccccc", "dddddddd", "eeeeeeeeee"):
|
|
76
|
+
c = srv._agent_color(name)
|
|
77
|
+
# Parse the \033[38;2;R;G;Bm
|
|
78
|
+
body = c.lstrip("\033[").rstrip("m")
|
|
79
|
+
parts = body.split(";")
|
|
80
|
+
r, g, b = int(parts[2]), int(parts[3]), int(parts[4])
|
|
81
|
+
assert 70 <= r <= 220, f"R={r} out of range for {name}"
|
|
82
|
+
assert 70 <= g <= 220, f"G={g} out of range for {name}"
|
|
83
|
+
assert 70 <= b <= 220, f"B={b} out of range for {name}"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Tests for B5 — `meshcode setup-path` subcommand."""
|
|
2
|
+
import os
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _run_setup_path(env_overrides: dict, expect_exit: int) -> tuple[str, str, int]:
|
|
11
|
+
"""Spawn `python -m meshcode.comms_v4 setup-path` in subprocess for
|
|
12
|
+
isolation (avoids polluting parent env / sys.argv). Returns (stdout, stderr, rc)."""
|
|
13
|
+
env = {**os.environ, **env_overrides}
|
|
14
|
+
env.setdefault("MESHCODE_PROJECT", "test")
|
|
15
|
+
env.setdefault("MESHCODE_AGENT", "test")
|
|
16
|
+
cmd = [sys.executable, "-m", "meshcode.comms_v4", "setup-path"]
|
|
17
|
+
r = subprocess.run(cmd, env=env, capture_output=True, text=True, timeout=10)
|
|
18
|
+
assert r.returncode == expect_exit, f"rc={r.returncode}, stdout={r.stdout!r}, stderr={r.stderr!r}"
|
|
19
|
+
return r.stdout, r.stderr, r.returncode
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_setup_path_writes_zsh_rc(tmp_path):
|
|
23
|
+
rc = tmp_path / ".zshrc"
|
|
24
|
+
out, err, _ = _run_setup_path(
|
|
25
|
+
{"HOME": str(tmp_path), "SHELL": "/bin/zsh"},
|
|
26
|
+
expect_exit=0,
|
|
27
|
+
)
|
|
28
|
+
assert rc.exists(), f"expected rc at {rc}"
|
|
29
|
+
body = rc.read_text()
|
|
30
|
+
assert "meshcode: PATH" in body
|
|
31
|
+
assert 'export PATH="' in body
|
|
32
|
+
assert "Appended" in out
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_setup_path_idempotent(tmp_path):
|
|
36
|
+
"""Running twice must not duplicate the export block."""
|
|
37
|
+
env = {"HOME": str(tmp_path), "SHELL": "/bin/zsh"}
|
|
38
|
+
_run_setup_path(env, expect_exit=0)
|
|
39
|
+
body1 = (tmp_path / ".zshrc").read_text()
|
|
40
|
+
out, _, _ = _run_setup_path(env, expect_exit=0)
|
|
41
|
+
body2 = (tmp_path / ".zshrc").read_text()
|
|
42
|
+
assert body1 == body2, "second run must not modify rc"
|
|
43
|
+
assert "already exports" in out
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_setup_path_writes_fish_config(tmp_path):
|
|
47
|
+
rc = tmp_path / ".config" / "fish" / "config.fish"
|
|
48
|
+
_run_setup_path(
|
|
49
|
+
{"HOME": str(tmp_path), "SHELL": "/usr/local/bin/fish"},
|
|
50
|
+
expect_exit=0,
|
|
51
|
+
)
|
|
52
|
+
assert rc.exists()
|
|
53
|
+
body = rc.read_text()
|
|
54
|
+
assert "set -gx PATH" in body
|
|
55
|
+
assert "meshcode: PATH" in body
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_setup_path_writes_bash_rc(tmp_path):
|
|
59
|
+
rc = tmp_path / ".bashrc"
|
|
60
|
+
_run_setup_path(
|
|
61
|
+
{"HOME": str(tmp_path), "SHELL": "/bin/bash"},
|
|
62
|
+
expect_exit=0,
|
|
63
|
+
)
|
|
64
|
+
assert rc.exists()
|
|
65
|
+
body = rc.read_text()
|
|
66
|
+
assert 'export PATH="' in body
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/test_backend.py
RENAMED
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/meshcode/meshcode_mcp/test_realtime.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_cross_agent_messaging.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_realtime_event_freshness.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_security_regressions.py
RENAMED
|
File without changes
|
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-backend-wt/tests/test_status_enum_coverage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/launcher_install.py
RENAMED
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__init__.py
RENAMED
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/__main__.py
RENAMED
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/backend.py
RENAMED
|
File without changes
|
{meshcode-2.11.10 → meshcode-2.11.11}/meshcode-noun-wt/build/lib/meshcode/meshcode_mcp/realtime.py
RENAMED
|
File without changes
|