meshcode 2.11.160__tar.gz → 2.11.162__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.160 → meshcode-2.11.162}/PKG-INFO +2 -1
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/__init__.py +1 -1
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/server.py +19 -11
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/run_agent.py +14 -9
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/setup_clients.py +18 -92
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode.egg-info/PKG-INFO +2 -1
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode.egg-info/SOURCES.txt +1 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode.egg-info/requires.txt +1 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/pyproject.toml +7 -1
- meshcode-2.11.162/tests/test_prompt_dedup_budget.py +161 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/README.md +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/__main__.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/_launch_smoke.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/_session_handoff_template.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/_stop_hook_template.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/_update_guard.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/ascii_art.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/atomic_push.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/claude_update.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/cli.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/comms_v4.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/compat.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/daemon.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/date_parse.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/doctor.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/error_hints.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/exceptions.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/hooks/__init__.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/hooks/push_guard.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/hooks/repo_path_lock.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/hostd.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/invites.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/launcher.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/launcher_install.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/sleep_signals.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/test_boot_timing.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/test_install_guard.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/test_prefs_claude_version.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/meshcode_mcp/test_server_wrapper.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/preferences.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/protocol_handler.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/protocol_v2.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/quickstart.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/rpc_allowlist.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/scripts/check_secrets.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/scripts/race_rate_harness.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/secrets.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/self_update.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/supervisor.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/up.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode/upload.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/setup.cfg +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_auto_update_hardening.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_autonomous_closegap_1.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_autonomous_closegap_2.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_autonomous_closegap_3.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_autonomous_prompt_inject.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_boot_bug_regression.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_color_truecolor.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_core.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_cross_agent_messaging.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_date_parse.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_doctor.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_ensure_boot_env_urgent_wake.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_epistemic_v1_python_sdk.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_epistemic_v1_stop_conditions.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_esc_deaf_state.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_exceptions.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_file_upload.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_fleet_reaper.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_hostd_launch_pinned_env.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_hostd_serve_discovery_split.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_hostd_zombie_sessions.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_init_device_code.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_install_guard.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_launch_smoke.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_lease_sigterm_release.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_live_mesh_guard.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_mark_read_batch.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_marketplace_ratings.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_migration_integrity.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_no_appleevents_on_sweep.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_preflight_hb_gate.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_pretrust_claude.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_push_guard.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_realtime_event_freshness.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_replica_base_workspace_fallback.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_replica_boot_protocol_unconditional.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_rls_cross_tenant.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_rm_guard.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_rpc_grants.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_rpc_migrations.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_run_agent_dry_run.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_run_agent_no_server_import.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_security_regressions.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_self_update_user_site.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_sentinel.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_session_replay_gate.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_setup_path.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_sleep_signals.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_status_enum_coverage.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_stay_on_loop_hook.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_stop_ghost_terminal.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_task_progress.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_terminal_lifecycle.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_up_launch_cmd.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_update_guard.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/tests/test_urgent_wake_tmux.py +0 -0
- {meshcode-2.11.160 → meshcode-2.11.162}/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.
|
|
3
|
+
Version: 2.11.162
|
|
4
4
|
Summary: Real-time communication between AI agents — Supabase-backed CLI
|
|
5
5
|
Author-email: MeshCode <hello@meshcode.io>
|
|
6
6
|
License: MIT
|
|
@@ -23,6 +23,7 @@ Requires-Dist: websockets>=12.0
|
|
|
23
23
|
Requires-Dist: realtime>=2.0.0
|
|
24
24
|
Requires-Dist: keyring>=24.0
|
|
25
25
|
Requires-Dist: cryptography>=41.0
|
|
26
|
+
Requires-Dist: psutil>=5.9.0
|
|
26
27
|
Provides-Extra: test
|
|
27
28
|
Requires-Dist: pytest>=8; extra == "test"
|
|
28
29
|
Provides-Extra: dev
|
|
@@ -1936,28 +1936,36 @@ def _build_instructions() -> str:
|
|
|
1936
1936
|
|
|
1937
1937
|
base = f"""You are agent "{AGENT_NAME}" in meshwork "{PROJECT_NAME}".{role_block}{launch_block}
|
|
1938
1938
|
|
|
1939
|
+
USER INTENT DOMINATES. The human's concrete request is the objective — mesh protocol is HOW you operate, never WHAT you build. Do exactly what is asked: no unrequested scope (no new infra/Docker/refactors/files unless explicitly requested), and when given a concrete directive ("reduce the font size") do THAT first and verify it before any housekeeping. If protocol and the user's literal ask conflict, the user wins.
|
|
1940
|
+
|
|
1939
1941
|
{_db_loop}LOOP (#1 rule): act → meshcode_wait() → repeat. Never exit/stop without calling meshcode_wait(). EXIT IMMEDIATELY when wait returns must_exit=True (set status=sleeping then end session). Other exits: user says stop, fatal error. Timeout → re-call with 2x (cap 1800s).
|
|
1940
1942
|
|
|
1941
|
-
|
|
1943
|
+
CLOSE TASKS IMMEDIATELY (#2 rule): the instant you finish/ship work for a claimed task, call meshcode_task_complete BEFORE re-entering wait. No "I'll close it after one more thing." No lingering in_progress while you do other work — stale in_progress lies to the dashboard. Needs human review → requires_approval=true at create, or task_complete routes to in_review if a reviewer is set.
|
|
1942
1944
|
|
|
1943
|
-
|
|
1945
|
+
WORK ASSIGNED TASKS IMMEDIATELY (#3 rule): when meshcode_wait returns pending_tasks or auto_started_task, your NEXT action MUST be to work that task. Don't re-enter wait, don't ask "what should I do" — the description tells you. read → execute → task_complete → wait. One by one until empty.
|
|
1944
1946
|
|
|
1945
|
-
|
|
1947
|
+
REPLY TO HUMANS VIA THE MESH, NOT THE TERMINAL (Samuel 2026-06-04): when you answer a human (sammybenu/Samuel/ian/fis) you MUST meshcode_send to the mesh. The human watches the DASHBOARD — your terminal text + thinking are INVISIBLE; a terminal-only reply reads as silence. Write plain prose in THEIR language (Spanish for Samuel), never JSON (JSON is agent↔agent).
|
|
1946
1948
|
|
|
1947
|
-
|
|
1949
|
+
RULES: MCP tools only. Tasks > messages (messages <100 tokens, long → task). No empty acks, JSON only. Thread via in_reply_to. sensitive=True for secrets/PII. Sync vs async: turn-based/shared-state (chess, lock-step, "who goes first") → meshcode_call (sync RPC); informing/signaling → meshcode_send (async, crosses ~50%/turn between same-model agents).
|
|
1948
1950
|
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1951
|
+
GIT-PUSH GOLDEN RULE (Samuel wt10): NEVER git push unless (1) the diff contains NO secrets AND (2) `git remote -v` confirms the remote is verified-ours + on the authorized allowlist. A remote not verified as ours = DO NOT PUSH, escalate to Security Chief (anfexi incident: core IP pushed to an ex-employer repo). MESHCODE_PUSH_GUARD enforces this at the pre-push hook; do not bypass.
|
|
1952
|
+
|
|
1953
|
+
SAFE SHELL: never run an unguarded `rm` on a variable/glob path — Claude Code hard-pauses on `rm $VAR/...` and root/home removals (cannot be flag-bypassed). Guard: `[ -n "$VAR" ] && [ -d "$VAR" ] && rm "$VAR"/*.ext`, or `find "$VAR" -maxdepth 1 -name '*.ext' -type f -delete`. Never `rm -rf /`, `rm -rf ~`, `rm -rf $UNSET/`.
|
|
1952
1954
|
|
|
1953
|
-
|
|
1955
|
+
USE SKILLS + SUBAGENTS (mandatory, Samuel hard rule): invoke the Skill tool whenever ANY skill matches (even slightly) BEFORE acting; dispatch subagents for multi-file search/audits. Samuel flagged skipping skills/subagents as underperforming.
|
|
1956
|
+
|
|
1957
|
+
MOBILE-FIRST UI GATE (Samuel MOBILE-FIRST-2): before task_complete on ANY task touching user-visible UI, run Playwright HEADLESS (headless:true — NEVER a visible browser window on the user's machine) at 375x667, 390x844, 768x1024 and put the 3 screenshot paths + console-error count in the summary. Backend-only task → state "verified: backend-only, no UI surface". (Full how-to is in your repo CLAUDE.md.)
|
|
1958
|
+
|
|
1959
|
+
SESSION START (run NOW, don't wait for input). If tool schemas are deferred:
|
|
1960
|
+
ToolSearch(query="select:meshcode_set_status,meshcode_boot,meshcode_wait,meshcode_send,meshcode_call,meshcode_task_claim,meshcode_task_complete,meshcode_remember,meshcode_recall")
|
|
1961
|
+
Then: set_status(online,ready) → meshcode_boot() → meshcode_wait(). Don't ask "what to work on" — the mesh tells you.
|
|
1954
1962
|
|
|
1955
|
-
Memory hints with open_contradictions take a -0.2 ranking penalty —
|
|
1963
|
+
Memory hints with open_contradictions take a -0.2 ranking penalty — flag, not veto.
|
|
1956
1964
|
|
|
1957
1965
|
ESCALATION RULES:
|
|
1958
|
-
- MUST escalate to human: destructive ops (drop/delete/rm -rf), irreversible changes (force-push main, mig without rollback), product-direction
|
|
1966
|
+
- MUST escalate to human: destructive ops (drop/delete/rm -rf), irreversible changes (force-push main, mig without rollback), product-direction, legal/compliance, security (auth/secrets/PII), spend > $50 USD.
|
|
1959
1967
|
- MUST NOT escalate: code style, implementation approach, naming, test strategy, migration ordering, refactor scope, library choice, which agent does what.
|
|
1960
|
-
- GREY ZONE: scope
|
|
1968
|
+
- GREY ZONE: scope/deadline trade-offs, cross-mesh assignments → meshcode_call(to="mesh-commander", function="advise") first; escalate to human only if commander offline or says "escalate".
|
|
1961
1969
|
"""
|
|
1962
1970
|
# Inject commander protocol if this agent is a leader
|
|
1963
1971
|
is_leader = _is_leader_agent()
|
|
@@ -1063,15 +1063,20 @@ def _provision_replica_mcp_from_base(project: str, agent: str, ws: "Path") -> bo
|
|
|
1063
1063
|
MESHCODE_BOOT_PROTOCOL = """You are agent {agent} in MeshCode meshwork {project}. Role: {role}.
|
|
1064
1064
|
You are running INSIDE the repo at {repo} (your cwd) — operate here like a normal terminal opened in this repo: read its CLAUDE.md + local memory, work here, and do NOT leave it (a hard repo-path lock denies file ops outside it).
|
|
1065
1065
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1066
|
+
Your FULL operating protocol is injected by the meshcode MCP server's instructions (the canonical home). The bullets below are a SLIM SAFETY-NET MIRROR of the non-negotiables, in case MCP init is delayed at boot — follow the MCP instructions when they load.
|
|
1067
|
+
|
|
1068
|
+
ON SESSION START (run NOW, don't idle/greet): if meshcode_* tools are deferred, FIRST call ToolSearch(query="select:meshcode_set_status,meshcode_boot,meshcode_wait,meshcode_send,meshcode_task_complete"). Then set_status(online,ready) -> meshcode_boot() -> meshcode_wait().
|
|
1069
|
+
|
|
1070
|
+
CORE NON-NEGOTIABLES (mirror):
|
|
1071
|
+
- USER INTENT DOMINATES: do exactly what the human asked; no unrequested scope. If protocol and the literal ask conflict, the user wins.
|
|
1072
|
+
- LOOP (#1): act -> meshcode_wait() -> repeat. Never exit without meshcode_wait(). Exit only on must_exit=True (set status=sleeping) / user stop / fatal error. Timeout -> re-call 2x (cap 1800s).
|
|
1073
|
+
- CLOSE TASKS (#2): the instant you finish claimed work, meshcode_task_complete BEFORE re-entering wait. No lingering in_progress.
|
|
1074
|
+
- WORK ASSIGNED (#3): wait returns pending_tasks/auto_started_task -> your NEXT action works that task. read -> execute -> task_complete -> wait.
|
|
1075
|
+
- REPLY TO HUMANS VIA THE MESH (not the terminal): meshcode_send plain prose in their language (Spanish for Samuel); terminal text is invisible on the dashboard. JSON is agent<->agent only.
|
|
1076
|
+
- MCP tools only (don't shell out to the meshcode CLI). Tasks > messages (<100 tokens, signals). Thread via in_reply_to. sensitive=True for secrets/PII.
|
|
1077
|
+
- GIT-PUSH GOLDEN RULE: NEVER git push unless the diff has NO secrets AND `git remote -v` confirms a verified-ours allowlisted remote. Unverified remote = DO NOT PUSH, escalate.
|
|
1078
|
+
- SAFE SHELL: never run an unguarded `rm` on a variable/glob path. Guard: `[ -n "$VAR" ] && [ -d "$VAR" ] && rm "$VAR"/*.ext`, or `find "$VAR" -maxdepth 1 -name '*.ext' -type f -delete`. Never `rm -rf /`, `rm -rf ~`, `rm -rf $UNSET/`.
|
|
1079
|
+
- USE SKILLS + SUBAGENTS (mandatory, Samuel hard rule): invoke the Skill tool whenever ANY skill matches (even slightly) BEFORE acting; dispatch subagents for multi-file search/audits."""
|
|
1075
1080
|
|
|
1076
1081
|
|
|
1077
1082
|
def ensure_repo_lock_hook_installed():
|
|
@@ -1275,82 +1275,21 @@ work in a different repo by `cd`ing elsewhere after launch.
|
|
|
1275
1275
|
You are agent **{agent}** in MeshCode meshwork **{project}**.
|
|
1276
1276
|
Role: {role or "(set in dashboard)"}
|
|
1277
1277
|
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
1. `meshcode_set_status(status="online", task="ready")`
|
|
1295
|
-
2. `meshcode_boot()` — single RPC returning inbox + tasks + mesh status + persona + health + memory hints (replaces check+tasks+status+auto_wake+recall in one round-trip; mig 271). Falls back gracefully on older projects.
|
|
1296
|
-
3. `meshcode_wait()` — enter the permanent loop (see next section)
|
|
1297
|
-
|
|
1298
|
-
Legacy boot order (only if `meshcode_boot()` returns `ok: false` with `mc_boot_unavailable`):
|
|
1299
|
-
|
|
1300
|
-
a. `meshcode_check()` — read NEW messages
|
|
1301
|
-
b. `meshcode_tasks()` — see assigned/pending tasks
|
|
1302
|
-
c. `meshcode_auto_wake()` — scan meshwork health
|
|
1303
|
-
d. `meshcode_status()` — see who's online
|
|
1304
|
-
e. `meshcode_wait()` — enter the loop
|
|
1305
|
-
|
|
1306
|
-
## PERMANENT LOOP (THE #1 RULE)
|
|
1307
|
-
|
|
1308
|
-
After the boot sequence — and after **EVERY** subsequent action — your next
|
|
1309
|
-
tool call MUST be `meshcode_wait()`. The loop:
|
|
1310
|
-
|
|
1311
|
-
```
|
|
1312
|
-
act → (optional meshcode_send) → meshcode_wait() → repeat
|
|
1313
|
-
```
|
|
1314
|
-
|
|
1315
|
-
NEVER exit. NEVER stop. NEVER say "standing by" / "let me know" / "I'm here"
|
|
1316
|
-
without actually calling `meshcode_wait()`. The ONLY exits:
|
|
1317
|
-
- the human user explicitly says "stop" / "sleep" / "exit",
|
|
1318
|
-
- the commander broadcasts a got_done / sleep authorization,
|
|
1319
|
-
- a fatal error makes continuation impossible.
|
|
1320
|
-
|
|
1321
|
-
If `meshcode_wait()` times out, call it again with a 2× longer timeout (cap 1800s).
|
|
1322
|
-
|
|
1323
|
-
## RULES
|
|
1324
|
-
|
|
1325
|
-
- Use MCP tools. Don't shell out to the `meshcode` CLI from inside the session.
|
|
1326
|
-
- Tasks > messages. Use `meshcode_task_create / task_claim / task_complete`
|
|
1327
|
-
for trackable work. Keep messages <100 tokens (signals only).
|
|
1328
|
-
- No empty acks. JSON reports only.
|
|
1329
|
-
- **Reply to humans via the mesh, NOT the terminal** (product default): when you
|
|
1330
|
-
answer a human (Samuel/sammybenu/ian/fis), `meshcode_send` to the mesh. The
|
|
1331
|
-
human watches the DASHBOARD — your Claude Code terminal text + thinking are
|
|
1332
|
-
invisible to them, so a terminal-only reply reads as silence. Write plain prose
|
|
1333
|
-
in their language (Spanish for Samuel), never JSON — JSON is for agent↔agent.
|
|
1334
|
-
- Threading: pass `in_reply_to`.
|
|
1335
|
-
- Sync vs async: for turn-based or shared-state coordination (chess, single-writer
|
|
1336
|
-
doc, lock-step handoffs, "who goes first" decisions), prefer
|
|
1337
|
-
`meshcode_call(to, function, args, timeout_seconds=30)` over `meshcode_send`.
|
|
1338
|
-
`send` is fire-and-forget and crosses on the wire at ~50%/turn between
|
|
1339
|
-
same-model agents, producing yield-pong. `call` is synchronous RPC: blocks
|
|
1340
|
-
until the callee responds with a matching call_id, max 60s. See
|
|
1341
|
-
"When to use sync vs async" below.
|
|
1342
|
-
- Multi-recipient: when the same payload goes to ≥2 agents, use
|
|
1343
|
-
`meshcode_send(to=["a","b"])` or CSV `"a,b,c"` — never N single-sends.
|
|
1344
|
-
Server fans out via `mc_send_multi` with a shared `group_id` and the FE
|
|
1345
|
-
collapses the row. Saves N-1 RPCs + round-trips. Cross-mesh `agent@meshwork`
|
|
1346
|
-
is single-recipient only (mixed lists rejected v1).
|
|
1347
|
-
- `sensitive=True` for secrets / PII.
|
|
1348
|
-
- Memory: `meshcode_remember(key, value)` for reusable learnings. Don't dump
|
|
1349
|
-
task summaries into memory — tasks already persist.
|
|
1350
|
-
- **ALWAYS USE SKILLS + SUBAGENTS (mandatory):** invoke the Skill tool whenever
|
|
1351
|
-
any skill matches (even 1%) BEFORE acting; dispatch subagents for multi-file
|
|
1352
|
-
search/audits. Samuel flagged skipping skills/subagents as underperforming —
|
|
1353
|
-
hard rule.
|
|
1278
|
+
> **Your operating protocol lives in the meshcode MCP server's instructions**
|
|
1279
|
+
> (injected at session start — the canonical home for the boot sequence, the
|
|
1280
|
+
> permanent `meshcode_wait()` loop, task/message rules, escalation, and the
|
|
1281
|
+
> git-push + safe-shell guards). This file is **project-specific** guidance only.
|
|
1282
|
+
> If the MCP instructions and this file ever conflict, the MCP instructions win.
|
|
1283
|
+
> Boot now (don't idle/greet): if meshcode_* tools are deferred,
|
|
1284
|
+
> `ToolSearch(query="select:meshcode_set_status,meshcode_boot,meshcode_wait,meshcode_send,meshcode_task_complete")`
|
|
1285
|
+
> then `set_status(online,ready)` → `meshcode_boot()` → `meshcode_wait()`.
|
|
1286
|
+
|
|
1287
|
+
## Repo guard (this workspace)
|
|
1288
|
+
|
|
1289
|
+
This workspace is a real git repo. Before any `git push`: the diff must contain
|
|
1290
|
+
NO secrets AND `git remote -v` must confirm the remote is verified-ours +
|
|
1291
|
+
allowlisted. An unverified remote = DO NOT PUSH, escalate to the Security Chief.
|
|
1292
|
+
Never shell out to the `meshcode` CLI from inside the session — use MCP tools.
|
|
1354
1293
|
|
|
1355
1294
|
## Mobile-first UI verification (before task_complete)
|
|
1356
1295
|
|
|
@@ -1363,7 +1302,9 @@ Viewports (canonical):
|
|
|
1363
1302
|
- iPhone 15 Pro 390 x 844
|
|
1364
1303
|
- iPad 768 x 1024
|
|
1365
1304
|
|
|
1366
|
-
Workflow (uses `mcp__playwright__browser_*` — load via ToolSearch if deferred)
|
|
1305
|
+
Workflow (uses `mcp__playwright__browser_*` — load via ToolSearch if deferred).
|
|
1306
|
+
ALWAYS run HEADLESS (`headless:true`) — never open a visible browser window on
|
|
1307
|
+
the user's machine:
|
|
1367
1308
|
|
|
1368
1309
|
1. For each viewport: `browser_resize` → `browser_navigate(<route>)` →
|
|
1369
1310
|
`browser_take_screenshot(filename="verify_<W>x<H>.png")` →
|
|
@@ -1390,21 +1331,6 @@ surface` in the summary so the rule is acknowledged.
|
|
|
1390
1331
|
**Why:** Samuel mobile directive (MOBILE-FIRST-2). Catches mobile breakage at
|
|
1391
1332
|
the agent before it reaches Samuel as a screenshot in chat.
|
|
1392
1333
|
|
|
1393
|
-
## When to use sync vs async
|
|
1394
|
-
|
|
1395
|
-
| Pattern | Tool | Why |
|
|
1396
|
-
|---|---|---|
|
|
1397
|
-
| Status update, broadcast, signal | `meshcode_send` | async, no reply expected |
|
|
1398
|
-
| Multi-recipient fan-out (≥2) | `meshcode_send(to=[…])` | one fan-out RPC, shared group_id |
|
|
1399
|
-
| Turn-based work (chess, lock-step) | `meshcode_call` | both agents writing async crosses at ~50%/turn |
|
|
1400
|
-
| "Who goes first" / role assignment | `meshcode_call` | yield-pong locks same-model pairs otherwise |
|
|
1401
|
-
| Single-writer / shared-state edits | `meshcode_call` or `meshcode_claim` | atomic; no proposal-tennis |
|
|
1402
|
-
| Request → structured response | `meshcode_call` | callee returns matched call_id, max 60s |
|
|
1403
|
-
| Long-running task (>30s) | task + `meshcode_send` ack | RPC timeout would refuse |
|
|
1404
|
-
|
|
1405
|
-
Rule of thumb: if the *next* action depends on the peer's *current* state, use
|
|
1406
|
-
`meshcode_call`. If you're just informing/signaling, use `meshcode_send`.
|
|
1407
|
-
|
|
1408
1334
|
## Status reports (canonical handler)
|
|
1409
1335
|
|
|
1410
1336
|
When another agent calls `meshcode_call(to="{agent}", function="status_report", args={{...}})`,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshcode
|
|
3
|
-
Version: 2.11.
|
|
3
|
+
Version: 2.11.162
|
|
4
4
|
Summary: Real-time communication between AI agents — Supabase-backed CLI
|
|
5
5
|
Author-email: MeshCode <hello@meshcode.io>
|
|
6
6
|
License: MIT
|
|
@@ -23,6 +23,7 @@ Requires-Dist: websockets>=12.0
|
|
|
23
23
|
Requires-Dist: realtime>=2.0.0
|
|
24
24
|
Requires-Dist: keyring>=24.0
|
|
25
25
|
Requires-Dist: cryptography>=41.0
|
|
26
|
+
Requires-Dist: psutil>=5.9.0
|
|
26
27
|
Provides-Extra: test
|
|
27
28
|
Requires-Dist: pytest>=8; extra == "test"
|
|
28
29
|
Provides-Extra: dev
|
|
@@ -88,6 +88,7 @@ tests/test_migration_integrity.py
|
|
|
88
88
|
tests/test_no_appleevents_on_sweep.py
|
|
89
89
|
tests/test_preflight_hb_gate.py
|
|
90
90
|
tests/test_pretrust_claude.py
|
|
91
|
+
tests/test_prompt_dedup_budget.py
|
|
91
92
|
tests/test_push_guard.py
|
|
92
93
|
tests/test_realtime_event_freshness.py
|
|
93
94
|
tests/test_replica_base_workspace_fallback.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "meshcode"
|
|
7
|
-
version = "2.11.
|
|
7
|
+
version = "2.11.162"
|
|
8
8
|
description = "Real-time communication between AI agents — Supabase-backed CLI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -17,6 +17,12 @@ dependencies = [
|
|
|
17
17
|
"realtime>=2.0.0",
|
|
18
18
|
"keyring>=24.0",
|
|
19
19
|
"cryptography>=41.0",
|
|
20
|
+
# psutil: hostd PID discovery for the fail-closed anti-self-spawn + zombie-kill
|
|
21
|
+
# paths (tasks 89d50a14, 14e0760c). Was a lazy/optional import; promoted to a
|
|
22
|
+
# hard dep (task 03957df3, Ian P1) so the terminal-storm guard is ALWAYS armed —
|
|
23
|
+
# without psutil the discovery degrades and the running-cap can be defeated.
|
|
24
|
+
# Prebuilt wheels exist for all requires-python>=3.9 targets.
|
|
25
|
+
"psutil>=5.9.0",
|
|
20
26
|
]
|
|
21
27
|
classifiers = [
|
|
22
28
|
"Development Status :: 4 - Beta",
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"""Prompt-dedup CI guards (task 2bca50f1 / Dan-retro launch-reliability batch, 2026-06-23).
|
|
2
|
+
|
|
3
|
+
After deduping the agent operating protocol so the meshcode MCP server's
|
|
4
|
+
`_build_instructions()` is the CANONICAL home (run_agent.py's
|
|
5
|
+
MESHCODE_BOOT_PROTOCOL is a slim safety-net mirror; the provisioned workspace
|
|
6
|
+
CLAUDE.md is project-only), three properties must not regress:
|
|
7
|
+
|
|
8
|
+
1. RULE-PRESENCE — every non-negotiable anchor still appears in the canonical
|
|
9
|
+
instructions. A dedup that silently drops a rule (vs. moving it) is a bug.
|
|
10
|
+
2. TOKEN-BUDGET — the always-injected text (canonical instructions + the
|
|
11
|
+
boot-protocol mirror) stays under budget, so it never crowds the MCP
|
|
12
|
+
InitializeResult handshake window again (boot bug 00d73223 lineage).
|
|
13
|
+
3. CACHE-STABILITY — neither always-injected string embeds a per-session
|
|
14
|
+
value (datetime / time / counter). Anthropic prompt-cache keys on the
|
|
15
|
+
static prefix; a clock token in the instructions busts the cache every
|
|
16
|
+
session.
|
|
17
|
+
|
|
18
|
+
Pure string assertions — no network, no Supabase (the builder defers all I/O).
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
pytest tests/test_prompt_dedup_budget.py -v
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import os
|
|
25
|
+
import re
|
|
26
|
+
import sys
|
|
27
|
+
import pathlib
|
|
28
|
+
from unittest import mock
|
|
29
|
+
|
|
30
|
+
import pytest
|
|
31
|
+
|
|
32
|
+
REPO = pathlib.Path(__file__).parent.parent
|
|
33
|
+
RUN_AGENT = REPO / "meshcode" / "run_agent.py"
|
|
34
|
+
|
|
35
|
+
# char/4 is the standard rough token approximation; the budget is deliberately
|
|
36
|
+
# generous (the real always-injected prefix is ~1800-2200 tok) so ordinary
|
|
37
|
+
# edits pass but a doubling/re-triplication trips the guard.
|
|
38
|
+
TOKEN_BUDGET = 2500
|
|
39
|
+
APPROX_CHARS_PER_TOKEN = 4
|
|
40
|
+
|
|
41
|
+
# The non-negotiables that MUST survive any dedup, by stable anchor substring.
|
|
42
|
+
REQUIRED_ANCHORS = [
|
|
43
|
+
"USER INTENT DOMINATES",
|
|
44
|
+
"LOOP (#1 rule)",
|
|
45
|
+
"CLOSE TASKS IMMEDIATELY (#2 rule)",
|
|
46
|
+
"WORK ASSIGNED TASKS IMMEDIATELY (#3 rule)",
|
|
47
|
+
"REPLY TO HUMANS VIA THE MESH",
|
|
48
|
+
"GIT-PUSH GOLDEN RULE",
|
|
49
|
+
"SAFE SHELL",
|
|
50
|
+
"MOBILE-FIRST UI GATE",
|
|
51
|
+
"sensitive=True",
|
|
52
|
+
"USE SKILLS + SUBAGENTS", # Samuel hard rule — retained through dedup
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
# Tokens that would bust the prompt cache if embedded in always-injected text.
|
|
56
|
+
_CACHE_BUSTERS = re.compile(
|
|
57
|
+
r"datetime\.|time\.time\(|time\.monotonic|\.now\(|utcnow|"
|
|
58
|
+
r"strftime|uuid4\(|random\.|itertools\.count|next\(_?counter",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _build_instructions(agent_name: str = "backend", role: str = "MCP-connected agent") -> str:
|
|
63
|
+
"""Import server.py with backend mocked (no network) and return the canonical
|
|
64
|
+
instructions string for a given agent. Mirrors test_autonomous_prompt_inject."""
|
|
65
|
+
env = {
|
|
66
|
+
"MESHCODE_PROJECT": "test-project",
|
|
67
|
+
"MESHCODE_AGENT": agent_name,
|
|
68
|
+
"MESHCODE_PROJECT_ID": "00000000-0000-0000-0000-000000000000",
|
|
69
|
+
}
|
|
70
|
+
with mock.patch.dict(os.environ, env, clear=False):
|
|
71
|
+
for m in [k for k in sys.modules if k.startswith("meshcode.meshcode_mcp")]:
|
|
72
|
+
del sys.modules[m]
|
|
73
|
+
be_mock = mock.MagicMock()
|
|
74
|
+
be_mock.sb_rpc.return_value = {"ok": True, "status": "online"}
|
|
75
|
+
be_mock.register_agent.return_value = {"ok": True}
|
|
76
|
+
with mock.patch.dict(sys.modules, {"meshcode.meshcode_mcp.backend": be_mock}):
|
|
77
|
+
try:
|
|
78
|
+
from meshcode.meshcode_mcp import server
|
|
79
|
+
except Exception:
|
|
80
|
+
pytest.skip("server.py import failed (expected in isolated test env)")
|
|
81
|
+
orig_name, orig_role = server.AGENT_NAME, server._ROLE_DESCRIPTION
|
|
82
|
+
server.AGENT_NAME, server._ROLE_DESCRIPTION = agent_name, role
|
|
83
|
+
try:
|
|
84
|
+
return server._build_instructions()
|
|
85
|
+
finally:
|
|
86
|
+
server.AGENT_NAME, server._ROLE_DESCRIPTION = orig_name, orig_role
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _boot_protocol_source() -> str:
|
|
90
|
+
"""The MESHCODE_BOOT_PROTOCOL literal from run_agent.py (read statically — the
|
|
91
|
+
launch fn execs claude + chdirs, so the module isn't unit-callable)."""
|
|
92
|
+
src = RUN_AGENT.read_text(encoding="utf-8")
|
|
93
|
+
m = re.search(r'MESHCODE_BOOT_PROTOCOL\s*=\s*"""(.*?)"""', src, re.DOTALL)
|
|
94
|
+
assert m, "MESHCODE_BOOT_PROTOCOL triple-quoted literal not found in run_agent.py"
|
|
95
|
+
return m.group(1)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class TestRulePresence:
|
|
99
|
+
def test_canonical_instructions_keep_every_anchor(self):
|
|
100
|
+
instr = _build_instructions("backend")
|
|
101
|
+
missing = [a for a in REQUIRED_ANCHORS if a not in instr]
|
|
102
|
+
assert not missing, (
|
|
103
|
+
f"Dedup dropped non-negotiable rule(s) from the canonical MCP "
|
|
104
|
+
f"instructions: {missing}. Move rules — never delete them."
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def test_leader_also_keeps_every_anchor(self):
|
|
108
|
+
instr = _build_instructions("mesh-commander")
|
|
109
|
+
missing = [a for a in REQUIRED_ANCHORS if a not in instr]
|
|
110
|
+
assert not missing, f"Leader instructions missing anchor(s): {missing}"
|
|
111
|
+
|
|
112
|
+
def test_boot_mirror_keeps_core_safety_net(self):
|
|
113
|
+
"""The slim run_agent mirror must still carry the boot-critical subset
|
|
114
|
+
(loop, close, work, reply, git-push, safe-shell, skills) for the
|
|
115
|
+
MCP-init-delayed window."""
|
|
116
|
+
boot = _boot_protocol_source()
|
|
117
|
+
for anchor in ("USER INTENT DOMINATES", "meshcode_wait()", "CLOSE TASKS",
|
|
118
|
+
"WORK ASSIGNED", "REPLY TO HUMANS", "GIT-PUSH GOLDEN RULE",
|
|
119
|
+
"SAFE SHELL", "USE SKILLS + SUBAGENTS"):
|
|
120
|
+
assert anchor in boot, f"boot-protocol mirror lost safety-net anchor: {anchor}"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class TestTokenBudget:
|
|
124
|
+
def test_always_injected_text_under_budget(self):
|
|
125
|
+
instr = _build_instructions("mesh-commander") # leader = the largest variant
|
|
126
|
+
boot = _boot_protocol_source()
|
|
127
|
+
approx_tokens = (len(instr) + len(boot)) // APPROX_CHARS_PER_TOKEN
|
|
128
|
+
assert approx_tokens <= TOKEN_BUDGET, (
|
|
129
|
+
f"Always-injected prompt text ~{approx_tokens} tok exceeds budget "
|
|
130
|
+
f"{TOKEN_BUDGET}. Dedup should shrink, not grow it — check for "
|
|
131
|
+
f"re-duplicated rules across the MCP instructions and the boot mirror."
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class TestCacheStability:
|
|
136
|
+
def test_canonical_instructions_have_no_clock_tokens(self):
|
|
137
|
+
instr = _build_instructions("backend")
|
|
138
|
+
hit = _CACHE_BUSTERS.search(instr)
|
|
139
|
+
assert not hit, (
|
|
140
|
+
f"Canonical instructions embed a per-session token "
|
|
141
|
+
f"({hit.group(0) if hit else ''}) — this busts the Anthropic prompt "
|
|
142
|
+
f"cache every session. Keep always-injected text fully static."
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def test_boot_protocol_has_no_clock_tokens(self):
|
|
146
|
+
boot = _boot_protocol_source()
|
|
147
|
+
hit = _CACHE_BUSTERS.search(boot)
|
|
148
|
+
assert not hit, (
|
|
149
|
+
f"Boot-protocol mirror embeds a per-session token "
|
|
150
|
+
f"({hit.group(0) if hit else ''}) — cache-busting; keep it static."
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
if __name__ == "__main__":
|
|
155
|
+
TestRulePresence().test_canonical_instructions_keep_every_anchor()
|
|
156
|
+
TestRulePresence().test_leader_also_keeps_every_anchor()
|
|
157
|
+
TestRulePresence().test_boot_mirror_keeps_core_safety_net()
|
|
158
|
+
TestTokenBudget().test_always_injected_text_under_budget()
|
|
159
|
+
TestCacheStability().test_canonical_instructions_have_no_clock_tokens()
|
|
160
|
+
TestCacheStability().test_boot_protocol_has_no_clock_tokens()
|
|
161
|
+
print("OK")
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|