meshcode 1.9.0__tar.gz → 2.0.0__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-1.9.0 → meshcode-2.0.0}/PKG-INFO +1 -1
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/__init__.py +1 -1
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/comms_v4.py +23 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/meshcode_mcp/server.py +155 -1
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode.egg-info/PKG-INFO +1 -1
- {meshcode-1.9.0 → meshcode-2.0.0}/pyproject.toml +1 -1
- {meshcode-1.9.0 → meshcode-2.0.0}/README.md +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/cli.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/invites.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/launcher.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/launcher_install.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/meshcode_mcp/__init__.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/meshcode_mcp/__main__.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/meshcode_mcp/backend.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/meshcode_mcp/realtime.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/meshcode_mcp/test_backend.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/meshcode_mcp/test_realtime.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/preferences.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/protocol_v2.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/run_agent.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/secrets.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/self_update.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode/setup_clients.py +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode.egg-info/SOURCES.txt +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode.egg-info/dependency_links.txt +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode.egg-info/entry_points.txt +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode.egg-info/requires.txt +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/meshcode.egg-info/top_level.txt +0 -0
- {meshcode-1.9.0 → meshcode-2.0.0}/setup.cfg +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""MeshCode — Real-time communication between AI agents."""
|
|
2
|
-
__version__ = "
|
|
2
|
+
__version__ = "2.0.0"
|
|
@@ -171,6 +171,7 @@ def sb_rpc(fn_name, params):
|
|
|
171
171
|
raw = resp.read().decode()
|
|
172
172
|
return json.loads(raw) if raw.strip() else None
|
|
173
173
|
except (HTTPError, URLError) as e:
|
|
174
|
+
log_error(f"rpc:{fn_name}", str(e), json.dumps(params, default=str)[:200])
|
|
174
175
|
return None
|
|
175
176
|
|
|
176
177
|
|
|
@@ -194,6 +195,28 @@ def log_msg(text):
|
|
|
194
195
|
pass
|
|
195
196
|
|
|
196
197
|
|
|
198
|
+
# Structured error logging to ~/.meshcode/error.log (rotating, max 1MB)
|
|
199
|
+
_ERROR_LOG = Path.home() / ".meshcode" / "error.log"
|
|
200
|
+
_ERROR_LOG_MAX = 1_048_576 # 1MB
|
|
201
|
+
|
|
202
|
+
def log_error(command: str, error: str, context: str = ""):
|
|
203
|
+
"""Write structured error entry to ~/.meshcode/error.log with rotation."""
|
|
204
|
+
try:
|
|
205
|
+
_ERROR_LOG.parent.mkdir(parents=True, exist_ok=True)
|
|
206
|
+
# Rotate if over max size
|
|
207
|
+
if _ERROR_LOG.exists() and _ERROR_LOG.stat().st_size > _ERROR_LOG_MAX:
|
|
208
|
+
rotated = _ERROR_LOG.with_suffix(".log.old")
|
|
209
|
+
_ERROR_LOG.rename(rotated)
|
|
210
|
+
entry = json.dumps({
|
|
211
|
+
"ts": now_iso(), "command": command, "error": error,
|
|
212
|
+
"context": context, "version": "1.9.0"
|
|
213
|
+
}, default=str)
|
|
214
|
+
with open(_ERROR_LOG, "a") as f:
|
|
215
|
+
f.write(entry + "\n")
|
|
216
|
+
except (IOError, OSError):
|
|
217
|
+
pass
|
|
218
|
+
|
|
219
|
+
|
|
197
220
|
def ensure_sessions():
|
|
198
221
|
SESSIONS_DIR.mkdir(parents=True, exist_ok=True)
|
|
199
222
|
|
|
@@ -446,7 +446,16 @@ meshcode_expand_link(). No sensitive msgs cross-mesh.
|
|
|
446
446
|
|
|
447
447
|
MEMORY: meshcode_remember(key, value) persists across sessions.
|
|
448
448
|
meshcode_recall(key?) retrieves. meshcode_forget(key) deletes.
|
|
449
|
-
Auto-remember: mistakes, feedback, patterns, preferences
|
|
449
|
+
Auto-remember after each task: mistakes, feedback, patterns, preferences.
|
|
450
|
+
Save reusable code patterns as template_* keys for instant recall.
|
|
451
|
+
|
|
452
|
+
SCRATCHPAD: meshcode_scratchpad_set/get for shared meshwork-level context
|
|
453
|
+
(decisions, conventions, architecture notes). All agents can read/write.
|
|
454
|
+
|
|
455
|
+
ACCOUNT MANAGEMENT: you can create meshworks (meshcode_create_meshwork),
|
|
456
|
+
add agents (meshcode_add_agent), edit roles/prompts (meshcode_edit_agent),
|
|
457
|
+
and edit other agents' memory (meshcode_edit_memory). Always tell the user
|
|
458
|
+
what CLI command to run next (e.g. "meshcode run backend in a new terminal").
|
|
450
459
|
|
|
451
460
|
Setup help → README.md or https://meshcode.io/docs
|
|
452
461
|
"""
|
|
@@ -920,6 +929,42 @@ def meshcode_task_complete(task_id: str, summary: str = "") -> Dict[str, Any]:
|
|
|
920
929
|
return be.task_complete(api_key, _PROJECT_ID, task_id, AGENT_NAME, summary=summary)
|
|
921
930
|
|
|
922
931
|
|
|
932
|
+
@mcp.tool()
|
|
933
|
+
@with_working_status
|
|
934
|
+
def meshcode_task_approve(task_id: str) -> Dict[str, Any]:
|
|
935
|
+
"""Approve a task in review. Only the reviewer can approve.
|
|
936
|
+
|
|
937
|
+
Args:
|
|
938
|
+
task_id: Task UUID to approve.
|
|
939
|
+
"""
|
|
940
|
+
api_key = _get_api_key()
|
|
941
|
+
return be.sb_rpc("mc_task_approve", {
|
|
942
|
+
"p_api_key": api_key,
|
|
943
|
+
"p_project_id": _PROJECT_ID,
|
|
944
|
+
"p_task_id": task_id,
|
|
945
|
+
"p_approving_agent": AGENT_NAME,
|
|
946
|
+
})
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
@mcp.tool()
|
|
950
|
+
@with_working_status
|
|
951
|
+
def meshcode_task_reject(task_id: str, feedback: str = "") -> Dict[str, Any]:
|
|
952
|
+
"""Reject a task in review — sends it back to in_progress with feedback.
|
|
953
|
+
|
|
954
|
+
Args:
|
|
955
|
+
task_id: Task UUID to reject.
|
|
956
|
+
feedback: Why it was rejected.
|
|
957
|
+
"""
|
|
958
|
+
api_key = _get_api_key()
|
|
959
|
+
return be.sb_rpc("mc_task_reject", {
|
|
960
|
+
"p_api_key": api_key,
|
|
961
|
+
"p_project_id": _PROJECT_ID,
|
|
962
|
+
"p_task_id": task_id,
|
|
963
|
+
"p_rejecting_agent": AGENT_NAME,
|
|
964
|
+
"p_feedback": feedback,
|
|
965
|
+
})
|
|
966
|
+
|
|
967
|
+
|
|
923
968
|
# ----------------- MESH LINK TOOLS -----------------
|
|
924
969
|
|
|
925
970
|
@mcp.tool()
|
|
@@ -990,6 +1035,115 @@ def meshcode_expand_link(link_id: str, agents: str) -> Dict[str, Any]:
|
|
|
990
1035
|
})
|
|
991
1036
|
|
|
992
1037
|
|
|
1038
|
+
# ----------------- ACCOUNT MANAGEMENT TOOLS -----------------
|
|
1039
|
+
|
|
1040
|
+
@mcp.tool()
|
|
1041
|
+
@with_working_status
|
|
1042
|
+
def meshcode_create_meshwork(name: str) -> Dict[str, Any]:
|
|
1043
|
+
"""Create a new meshwork for the current user. Tell them to run 'meshcode setup <name> <agent>' next.
|
|
1044
|
+
|
|
1045
|
+
Args:
|
|
1046
|
+
name: Meshwork name (lowercase, hyphens ok).
|
|
1047
|
+
"""
|
|
1048
|
+
api_key = _get_api_key()
|
|
1049
|
+
result = be.sb_rpc("mc_create_meshwork_by_api_key", {
|
|
1050
|
+
"p_api_key": api_key, "p_name": name,
|
|
1051
|
+
})
|
|
1052
|
+
if isinstance(result, dict) and result.get("ok"):
|
|
1053
|
+
return {**result, "next_step": f"Run: meshcode setup {name} <agent-name>"}
|
|
1054
|
+
return result or {"error": "failed to create meshwork"}
|
|
1055
|
+
|
|
1056
|
+
|
|
1057
|
+
@mcp.tool()
|
|
1058
|
+
@with_working_status
|
|
1059
|
+
def meshcode_add_agent(name: str, role: str = "") -> Dict[str, Any]:
|
|
1060
|
+
"""Add an agent to the current meshwork. Tell user to run 'meshcode setup <project> <name>' then 'meshcode run <name>'.
|
|
1061
|
+
|
|
1062
|
+
Args:
|
|
1063
|
+
name: Agent name.
|
|
1064
|
+
role: Agent role description.
|
|
1065
|
+
"""
|
|
1066
|
+
result = be.register_agent(PROJECT_NAME, name, role or "MCP-connected agent")
|
|
1067
|
+
if isinstance(result, dict) and not result.get("error"):
|
|
1068
|
+
return {"ok": True, "agent": name, "next_step": f"Run: meshcode setup {PROJECT_NAME} {name} && meshcode run {name}"}
|
|
1069
|
+
return result or {"error": "failed to add agent"}
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
@mcp.tool()
|
|
1073
|
+
@with_working_status
|
|
1074
|
+
def meshcode_edit_agent(name: str, role: Optional[str] = None, launch_prompt: Optional[str] = None) -> Dict[str, Any]:
|
|
1075
|
+
"""Update an agent's role or launch prompt.
|
|
1076
|
+
|
|
1077
|
+
Args:
|
|
1078
|
+
name: Agent name to edit.
|
|
1079
|
+
role: New role description.
|
|
1080
|
+
launch_prompt: New launch prompt (injected into agent's system context).
|
|
1081
|
+
"""
|
|
1082
|
+
return be.sb_rpc("mc_agent_update_profile", {
|
|
1083
|
+
"p_project_id": _PROJECT_ID,
|
|
1084
|
+
"p_agent_name": name,
|
|
1085
|
+
"p_color": None,
|
|
1086
|
+
"p_display_name": None,
|
|
1087
|
+
"p_role_description": role,
|
|
1088
|
+
"p_launch_prompt": launch_prompt,
|
|
1089
|
+
}) or {"error": "failed to update agent"}
|
|
1090
|
+
|
|
1091
|
+
|
|
1092
|
+
@mcp.tool()
|
|
1093
|
+
@with_working_status
|
|
1094
|
+
def meshcode_edit_memory(agent_name: str, key: str, value: Any) -> Dict[str, Any]:
|
|
1095
|
+
"""Edit another agent's memory (for commanders coordinating the team).
|
|
1096
|
+
|
|
1097
|
+
Args:
|
|
1098
|
+
agent_name: Target agent whose memory to edit.
|
|
1099
|
+
key: Memory key.
|
|
1100
|
+
value: New value.
|
|
1101
|
+
"""
|
|
1102
|
+
api_key = _get_api_key()
|
|
1103
|
+
json_value = value if isinstance(value, (dict, list)) else {"_raw": value}
|
|
1104
|
+
return be.sb_rpc("mc_memory_set", {
|
|
1105
|
+
"p_api_key": api_key,
|
|
1106
|
+
"p_agent_name": agent_name,
|
|
1107
|
+
"p_key": key,
|
|
1108
|
+
"p_value": json_value,
|
|
1109
|
+
}) or {"error": "failed to edit memory"}
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
# ----------------- SCRATCHPAD TOOLS -----------------
|
|
1113
|
+
|
|
1114
|
+
@mcp.tool()
|
|
1115
|
+
@with_working_status
|
|
1116
|
+
def meshcode_scratchpad_set(key: str, value: Any) -> Dict[str, Any]:
|
|
1117
|
+
"""Write to shared scratchpad (all agents in this meshwork can read/write).
|
|
1118
|
+
|
|
1119
|
+
Args:
|
|
1120
|
+
key: Key name (e.g. "architecture_decisions", "conventions").
|
|
1121
|
+
value: Any JSON-serializable value.
|
|
1122
|
+
"""
|
|
1123
|
+
api_key = _get_api_key()
|
|
1124
|
+
json_value = value if isinstance(value, (dict, list)) else {"_raw": value}
|
|
1125
|
+
return be.sb_rpc("mc_scratchpad_set", {
|
|
1126
|
+
"p_api_key": api_key,
|
|
1127
|
+
"p_key": key,
|
|
1128
|
+
"p_value": json_value,
|
|
1129
|
+
})
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
@mcp.tool()
|
|
1133
|
+
@with_working_status
|
|
1134
|
+
def meshcode_scratchpad_get(key: Optional[str] = None) -> Dict[str, Any]:
|
|
1135
|
+
"""Read from shared scratchpad. Omit key to list all entries.
|
|
1136
|
+
|
|
1137
|
+
Args:
|
|
1138
|
+
key: Specific key, or omit for all entries.
|
|
1139
|
+
"""
|
|
1140
|
+
api_key = _get_api_key()
|
|
1141
|
+
if key:
|
|
1142
|
+
return be.sb_rpc("mc_scratchpad_get", {"p_api_key": api_key, "p_key": key})
|
|
1143
|
+
else:
|
|
1144
|
+
return be.sb_rpc("mc_scratchpad_list", {"p_api_key": api_key})
|
|
1145
|
+
|
|
1146
|
+
|
|
993
1147
|
# ----------------- OBSIDIAN SYNC HELPER -----------------
|
|
994
1148
|
|
|
995
1149
|
def _sync_to_obsidian(key: str, value: Any) -> None:
|
|
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
|