solidcraft --control PORT writes a random per-launch token to a user-only file (<data>/control/PORT.token; 0700/0600 on Unix, icacls on Windows; SOLIDCRAFT_CONTROL_TOKEN overrides) and refuses any connection whose first request lacks it. mcp --connect, the demo and packaging smoke clients send it. MCP execute/batch/open/save/export/screenshot are annotated destructive and open-world, new_design destructive. Docs: control-protocol.md, mcp.md, AGENTS.md, pending release note in releasing.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d9237d004e
commit
fe3717f2e4
19 files changed
+465
-53
No files matched your search
@@ -28,6 +28,9 @@ work=$(mktemp -d)
|
||||
export XDG_CONFIG_HOME="$work/config" XDG_DATA_HOME="$work/data" XDG_CACHE_HOME="$work/cache"
|
||||
mkdir -p "$XDG_CONFIG_HOME" "$XDG_DATA_HOME" "$XDG_CACHE_HOME"
|
||||
unset WGPU_BACKEND WGPU_BACKENDS
|
||||
# The control channel's token (docs/control-protocol.md), set here so this client knows it.
|
||||
SOLIDCRAFT_CONTROL_TOKEN=$(od -An -N32 -tx1 /dev/urandom | tr -d ' \n')
|
||||
export SOLIDCRAFT_CONTROL_TOKEN
|
||||
solidcraft --control 18837 >"$work/app.log" 2>&1 &
|
||||
app=$!
|
||||
cleanup() {
|
||||
@@ -44,7 +47,7 @@ for ((attempt=0; attempt<300; attempt++)); do
|
||||
sleep .1
|
||||
done
|
||||
test "$ready" = 1
|
||||
for request in '{"id":1,"method":"ui.inspect","params":{}}' '{"id":2,"method":"engine.execute","params":{"command":"solid.box","params":{"length":30,"width":20,"height":10}}}' '{"id":3,"method":"document.inspect","params":{"measure":true}}'; do
|
||||
for request in "{\"id\":1,\"method\":\"ui.inspect\",\"params\":{},\"token\":\"$SOLIDCRAFT_CONTROL_TOKEN\"}" '{"id":2,"method":"engine.execute","params":{"command":"solid.box","params":{"length":30,"width":20,"height":10}}}' '{"id":3,"method":"document.inspect","params":{"measure":true}}'; do
|
||||
printf '%s\n' "$request" >&3
|
||||
IFS= read -r -t 30 reply <&3
|
||||
printf '%s\n' "$reply"
|
||||
|
||||
@@ -17,6 +17,7 @@ import signal
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import secrets
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
@@ -26,8 +27,10 @@ flatpak_smoke = importlib.util.module_from_spec(_spec)
|
||||
_spec.loader.exec_module(flatpak_smoke)
|
||||
|
||||
PORTS = {"x11": 18839, "wayland": 18840}
|
||||
# The control channel's token (docs/control-protocol.md), given to the app so this client knows it.
|
||||
TOKEN = secrets.token_hex(32)
|
||||
REQUESTS = [
|
||||
{"id": 1, "method": "ui.inspect", "params": {}},
|
||||
{"id": 1, "method": "ui.inspect", "params": {}, "token": TOKEN},
|
||||
{"id": 2, "method": "engine.execute",
|
||||
"params": {"command": "solid.box", "params": {"length": 30, "width": 20, "height": 10}}},
|
||||
{"id": 3, "method": "document.inspect", "params": {"measure": True}},
|
||||
@@ -67,7 +70,7 @@ def run_backend(backend, out):
|
||||
runtime = Path(f"/run/user/{os.getuid()}")
|
||||
if not runtime.is_dir():
|
||||
raise RuntimeError(f"{runtime} is missing: snaps expect the login session's runtime directory")
|
||||
env = dict(os.environ, XDG_RUNTIME_DIR=str(runtime))
|
||||
env = dict(os.environ, XDG_RUNTIME_DIR=str(runtime), SOLIDCRAFT_CONTROL_TOKEN=TOKEN)
|
||||
for name in ("WAYLAND_DISPLAY", "WAYLAND_SOCKET", "DISPLAY", "SOLIDCRAFT_WAYLAND", "SOLVECRAFT_WAYLAND"):
|
||||
env.pop(name, None)
|
||||
# The snap can write to the (non-hidden) home folder, not to the host's /tmp.
|
||||
|
||||
Reference in new issue
Block a user