feat(desktop): mount private remote Stop controls and live receiver

Signed-off-by: Logan Johnson <loganj@squareup.com>
This commit is contained in:
Logan Johnson
2026-09-04 16:00:35 -04:00
parent 17e08d7465
commit 20436c81f2
4 changed files with 341 additions and 4 deletions

View File

@@ -310,9 +310,10 @@ with a TypeScript lookup table or an id comparison in a component.
## Remote Desktop Stop
Native IPC accepts an owner-private, explicitly selected agent+Desktop Stop,
not inferred agent location. The relay redelivers stored Stop duplicates without
repeating relay side effects.
Known Desktops exposes an owner-private, explicitly selected agent+Desktop Stop,
not inferred agent location. The app-scoped receiver subscribes live only;
reopening never replays commands. An explicit retry republishes the exact request;
the relay redelivers stored Stop duplicates without repeating relay side effects.
The receiver returns saved results or Unknown, never repeats a consumed Stop.
Native owner-delegation and community checks
precede durable admission and ordinary pair Stop. A delivery ACK is not success.

View File

@@ -0,0 +1,155 @@
import assert from "node:assert/strict";
import test from "node:test";
import React from "react";
import { JSDOM } from "jsdom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import {
DesktopStopControl,
DesktopStopReceiver,
} from "./DesktopStopControl.tsx";
import { relayClient } from "../../../shared/api/relayClient.ts";
test("mounted Stop waits for a correlated result and retries identical bytes without replay", async () => {
const dom = new JSDOM("<div id='root'></div>", {
url: "https://desktop.test",
});
Object.assign(globalThis, {
window: dom.window,
document: dom.window.document,
localStorage: dom.window.localStorage,
IS_REACT_ACT_ENVIRONMENT: true,
});
const { createRoot } = await import("react-dom/client");
const scope = { owner: "owner", community: "wss://one.example" };
const request = { id: "request", kind: 50180, tags: [["d", "desktop"]] };
const result = { id: "result", kind: 50181, tags: [["e", request.id]] };
const client = new QueryClient({
defaultOptions: { queries: { retry: false, staleTime: Infinity } },
});
client.setQueryData(
["relay-agents"],
[
{ pubkey: "agent", name: "Owned agent", ownerPubkey: "owner" },
{ pubkey: "foreign", name: "Foreign agent", ownerPubkey: "other" },
],
);
const original = {
fetch: relayClient.fetchEvents,
publish: relayClient.publishEvent,
subscribe: relayClient.subscribeLive,
};
let live, release;
let receiveCalls = 0,
prepared = 0,
closed = 0;
const sent = [];
window.__TAURI_INTERNALS__ = {
invoke: async (command, args) => {
assert.equal(args.owner, scope.owner);
assert.equal(args.community, scope.community);
if (command === "prepare_desktop_stop") {
prepared++;
assert.equal(args.desktop, "desktop");
assert.equal(args.agent, "agent");
return request;
}
if (command === "receive_desktop_stop") {
receiveCalls++;
return result;
}
assert.equal(command, "read_desktop_stop_results");
return "stopped";
},
};
relayClient.subscribeLive = async (filter, callback) => {
assert.deepEqual(filter, {
kinds: [50180],
authors: [scope.owner],
limit: 0,
});
live = callback;
return () => {
closed++;
live = undefined;
};
};
relayClient.publishEvent = async (event) => {
sent.push(event);
live?.(event);
};
relayClient.fetchEvents = async (filter) => {
assert.deepEqual(filter, {
kinds: [50181],
authors: [scope.owner],
"#e": [request.id],
limit: 16,
});
return new Promise((resolve) => {
release = () => resolve([result]);
});
};
const root = createRoot(document.getElementById("root"));
const render = (receiver) =>
React.act(async () =>
root.render(
React.createElement(
QueryClientProvider,
{ client },
React.createElement(
React.Fragment,
null,
receiver
? React.createElement(DesktopStopReceiver, { scope })
: null,
React.createElement(DesktopStopControl, {
scope,
desktop: { id: "desktop", name: "Workshop" },
}),
),
),
),
);
const click = (text) =>
React.act(async () =>
[...document.querySelectorAll("button")]
.find((b) => b.textContent === text)
.click(),
);
try {
await render(false);
assert.doesNotMatch(document.body.textContent, /Foreign agent/);
const select = document.querySelector("select");
await React.act(async () => {
select.value = "agent";
select.dispatchEvent(new dom.window.Event("change", { bubbles: true }));
});
await click("Stop on Workshop");
assert.equal(prepared, 1);
assert.match(document.body.textContent, /Waiting for this Desktop/);
assert.doesNotMatch(document.body.textContent, /Stop confirmed/);
assert.equal(receiveCalls, 0, "absent receiver has not stopped anything");
await React.act(async () => release());
assert.match(document.body.textContent, /Stop confirmed by Workshop/);
await render(true);
assert.equal(receiveCalls, 0, "mount cannot replay stored Stop");
// The mounted receiver returns a saved native result, while the sender
// explicitly retries the exact prepared request rather than signing anew.
relayClient.publishEvent = async (event) => {
sent.push(event);
if (event.kind === 50180) live?.(event);
};
await click("Retry same Stop");
await React.act(async () => release());
assert.equal(prepared, 1);
assert.equal(receiveCalls, 1);
assert.ok(sent.filter((e) => e.kind === 50180).every((e) => e === request));
} finally {
await React.act(async () => root.unmount());
assert.equal(closed, 1);
client.clear();
relayClient.fetchEvents = original.fetch;
relayClient.publishEvent = original.publish;
relayClient.subscribeLive = original.subscribe;
dom.window.close();
}
});

View File

@@ -0,0 +1,170 @@
import { useEffect, useRef, useState } from "react";
import { useRelayAgentsQuery } from "../hooks";
import {
prepareStop,
readStopOutcome,
receiveStops,
sendStop,
} from "../desktopStop";
import type { DesktopScope, DesktopRow } from "../desktopList";
import type { RelayEvent } from "@/shared/api/types";
import { Button } from "@/shared/ui/button";
/** App-scoped live receiver; no historical requests are loaded on mount. */
export function DesktopStopReceiver({ scope }: { scope: DesktopScope | null }) {
const [error, setError] = useState("");
const { owner, community } = scope ?? {};
useEffect(() => {
if (!owner || !community) return;
let active = true;
let close: (() => void) | undefined;
setError("");
void receiveStops({ owner, community }, () => active, setError)
.then((unsubscribe) => {
if (active) close = unsubscribe;
else unsubscribe();
})
.catch(() => {
if (active)
setError("Remote Stop receiver is unavailable on this Desktop.");
});
return () => {
active = false;
close?.();
};
}, [owner, community]);
return error ? (
<p role="status" className="text-xs text-muted-foreground">
{error}
</p>
) : null;
}
/** Deliberately selects a host, not an inferred running location or presence. */
export function DesktopStopControl({
scope,
desktop,
}: {
scope: DesktopScope;
desktop: DesktopRow;
}) {
const agents = useRelayAgentsQuery();
const owned = (agents.data ?? []).filter(
(agent) => agent.ownerPubkey === scope.owner,
);
const [agent, setAgent] = useState("");
const [request, setRequest] = useState<RelayEvent | null>(null);
const [message, setMessage] = useState("");
const [busy, setBusy] = useState(false);
const active = useRef(true);
useEffect(() => {
active.current = true;
return () => {
active.current = false;
};
}, []);
const run = async (retry: boolean) => {
setBusy(true);
let current = retry ? request : null;
try {
current ??= await prepareStop(
scope,
desktop.id,
agent,
() => active.current,
);
if (!active.current) return;
setRequest(current);
setMessage("Stop requested. Waiting for this Desktop’s result…");
try {
await sendStop(scope, current, () => active.current);
} catch {
if (active.current)
setMessage(
"Delivery unconfirmed. Checking for this Desktop’s result…",
);
}
for (let attempt = 0; attempt < 15 && active.current; attempt++) {
const outcome = await readStopOutcome(
scope,
current,
() => active.current,
);
if (!active.current) return;
if (outcome === "stopped") {
setMessage(`Stop confirmed by ${desktop.name}.`);
return;
}
if (outcome === "failed") {
setMessage(
`Stop failed on ${desktop.name}. No success was confirmed.`,
);
return;
}
await new Promise((resolve) => setTimeout(resolve, 1000));
}
if (active.current)
setMessage(
"Stop unconfirmed. This Desktop may be unavailable; its agents may still be running.",
);
} catch {
if (active.current)
setMessage("Stop unconfirmed. No successful result could be read.");
} finally {
if (active.current) setBusy(false);
}
};
return (
<div className="mt-2 space-y-2">
<label className="block text-xs">
Agent to stop on {desktop.name}
<select
aria-label={`Agent to stop on ${desktop.name}`}
className="ml-2 rounded border bg-background p-1 text-sm"
value={agent}
disabled={busy}
onChange={(event) => {
setAgent(event.target.value);
setRequest(null);
setMessage("");
}}
>
<option value="">Choose your agent</option>
{owned.map((item) => (
<option key={item.pubkey} value={item.pubkey}>
{item.name}
</option>
))}
</select>
</label>
<p className="text-xs text-muted-foreground">
Stops only this agent on this Desktop in this community. This list does
not establish where it is running.
</p>
{agents.isError && <p role="status">Your agent list is unavailable.</p>}
<Button
size="sm"
variant="outline"
disabled={!agent || busy}
onClick={() => void run(false)}
>
Stop on {desktop.name}
</Button>
{request && (
<Button
size="sm"
variant="ghost"
disabled={busy}
onClick={() => void run(true)}
>
Retry same Stop
</Button>
)}
{message && (
<p role="status" className="text-xs">
{message}
</p>
)}
</div>
);
}

View File

@@ -1,3 +1,4 @@
import { DesktopStopControl, DesktopStopReceiver } from "./DesktopStopControl";
import { useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { useIdentityQuery } from "@/shared/api/hooks";
@@ -19,6 +20,7 @@ import {
import { DesktopCapabilityDetails } from "./DesktopCapabilityDetails";
type View = {
scope?: import("../desktopList").DesktopScope;
capabilities?: DesktopCapabilities[];
capabilityWarning?: string;
list: DesktopList | null;
@@ -78,7 +80,7 @@ export function DesktopListStartup() {
unsubscribe();
};
}, [refetch, pulse, report]);
return null;
return <DesktopStopReceiver scope={useDesktopScope()} />;
}
export function KnownDesktops() {
@@ -92,6 +94,7 @@ export function KnownDesktops() {
}, []);
return (
<DesktopListView
scope={useDesktopScope() ?? undefined}
capabilities={capabilities.data?.rows}
capabilityWarning={
capabilities.isError
@@ -122,6 +125,7 @@ export function KnownDesktops() {
}
export function DesktopListView({
scope,
list,
loading,
error,
@@ -184,6 +188,13 @@ export function DesktopListView({
now,
)}
</div>
{scope && (
<DesktopStopControl
key={`${scope.owner}:${scope.community}:${row.id}`}
scope={scope}
desktop={row}
/>
)}
<DesktopCapabilityDetails
report={capabilities?.find((item) => item.id === row.id)}
now={now}