relay-companion 0.1.8 → 0.1.9
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.
- package/overlay/inbox.html +3 -0
- package/overlay/main.cjs +14 -2
- package/overlay/preload.cjs +1 -0
- package/package.json +1 -1
- package/src/mcp.js +15 -1
- package/src/notifications.js +5 -0
package/overlay/inbox.html
CHANGED
|
@@ -1550,6 +1550,9 @@
|
|
|
1550
1550
|
else notifyArrival(row);
|
|
1551
1551
|
});
|
|
1552
1552
|
if (window.relay.onOpenFull) window.relay.onOpenFull(() => trayOpen());
|
|
1553
|
+
// The OS window was just re-shown and main re-asserted click-through; reset the
|
|
1554
|
+
// local flag so the next mousemove re-runs the interactivity handshake cleanly.
|
|
1555
|
+
if (window.relay.onShown) window.relay.onShown(() => { interactive = false; });
|
|
1553
1556
|
if (window.relay.onOpenDone) window.relay.onOpenDone((id) => stopOpening(id));
|
|
1554
1557
|
window.relay.refresh().then((p) => {
|
|
1555
1558
|
onPayload(p);
|
package/overlay/main.cjs
CHANGED
|
@@ -324,7 +324,7 @@ async function pushInbox(force) {
|
|
|
324
324
|
if (dismissed) {
|
|
325
325
|
if (hostRunning) {
|
|
326
326
|
ghostActive = true;
|
|
327
|
-
|
|
327
|
+
showOverlayWindow();
|
|
328
328
|
win.webContents.send("newRelay", fresh[0], { ghost: true });
|
|
329
329
|
}
|
|
330
330
|
} else {
|
|
@@ -686,13 +686,25 @@ function anchorTopRight() {
|
|
|
686
686
|
return { x: wa.x + wa.width - WIN.width - MARGIN, y: wa.y + MARGIN, width: WIN.width, height: WIN.height };
|
|
687
687
|
}
|
|
688
688
|
|
|
689
|
+
// Show the overlay window. Electron's forwarded-mousemove stream (the thing that
|
|
690
|
+
// lets the renderer detect hover on a click-through window) can stall across a
|
|
691
|
+
// hide()/show() cycle, leaving the window permanently click-through. Re-assert
|
|
692
|
+
// setIgnoreMouseEvents on every hidden->shown transition and tell the renderer to
|
|
693
|
+
// reset its interactivity handshake.
|
|
694
|
+
function showOverlayWindow() {
|
|
695
|
+
if (!win || win.isDestroyed() || win.isVisible()) return;
|
|
696
|
+
win.showInactive();
|
|
697
|
+
win.setIgnoreMouseEvents(true, { forward: true });
|
|
698
|
+
win.webContents.send("shown");
|
|
699
|
+
}
|
|
700
|
+
|
|
689
701
|
function maybeShow() {
|
|
690
702
|
if (!win || win.isDestroyed()) return;
|
|
691
703
|
// Dismissed keeps the window hidden except while a ghost notification is up.
|
|
692
704
|
// trayForcedVisible honors an explicit menu-bar click even when no host runs.
|
|
693
705
|
const wanted = (hostRunning || trayForcedVisible) && (!dismissed || ghostActive);
|
|
694
706
|
if (wanted) {
|
|
695
|
-
|
|
707
|
+
showOverlayWindow();
|
|
696
708
|
} else if (win.isVisible()) {
|
|
697
709
|
win.hide();
|
|
698
710
|
}
|
package/overlay/preload.cjs
CHANGED
|
@@ -6,6 +6,7 @@ contextBridge.exposeInMainWorld("relay", {
|
|
|
6
6
|
onNewRelay: (cb) => ipcRenderer.on("newRelay", (_e, relay, opts) => cb(relay, opts || {})),
|
|
7
7
|
onOpenDone: (cb) => ipcRenderer.on("openDone", (_e, id) => cb(id)),
|
|
8
8
|
onOpenFull: (cb) => ipcRenderer.on("openFull", () => cb()), // menu-bar icon clicked
|
|
9
|
+
onShown: (cb) => ipcRenderer.on("shown", () => cb()), // window re-shown; reset hover handshake
|
|
9
10
|
|
|
10
11
|
// pull the full payload on demand
|
|
11
12
|
refresh: () => ipcRenderer.invoke("relay:get"),
|
package/package.json
CHANGED
package/src/mcp.js
CHANGED
|
@@ -543,7 +543,21 @@ export async function runMcpServer() {
|
|
|
543
543
|
try {
|
|
544
544
|
return await handleCall(client, req.params.name, req.params.arguments || {});
|
|
545
545
|
} catch (err) {
|
|
546
|
-
|
|
546
|
+
// Surface the API's validation detail so the calling agent can self-correct
|
|
547
|
+
// instead of guessing what "invalid_request" meant.
|
|
548
|
+
let detail = "";
|
|
549
|
+
const issues = err && err.body && Array.isArray(err.body.issues) ? err.body.issues : null;
|
|
550
|
+
if (issues && issues.length) {
|
|
551
|
+
detail =
|
|
552
|
+
"\n" +
|
|
553
|
+
issues
|
|
554
|
+
.slice(0, 8)
|
|
555
|
+
.map((i) => `- ${Array.isArray(i.path) && i.path.length ? i.path.join(".") : "(request)"}: ${i.message}`)
|
|
556
|
+
.join("\n");
|
|
557
|
+
} else if (err && err.body && typeof err.body.instruction === "string") {
|
|
558
|
+
detail = `\n${err.body.instruction}`;
|
|
559
|
+
}
|
|
560
|
+
return { content: [{ type: "text", text: `Relay error: ${err.message}${detail}` }], isError: true };
|
|
547
561
|
}
|
|
548
562
|
});
|
|
549
563
|
|
package/src/notifications.js
CHANGED
|
@@ -287,6 +287,11 @@ function senderForNotification(notification) {
|
|
|
287
287
|
// anyway via RELAY_HIDDEN_KINDS, but the staged senderName must still be coherent.)
|
|
288
288
|
if (notification.kind === "task_request") return "Your agent";
|
|
289
289
|
if (notification.kind === "share_approval") return "Your agent";
|
|
290
|
+
// Task lifecycle notices (completed/cancelled/failed) are the agent run reporting
|
|
291
|
+
// back, not a person — label them as the automation, never "Someone".
|
|
292
|
+
if (notification.kind === "task_completed") return "Your agent";
|
|
293
|
+
if (notification.kind === "task_cancelled") return "Your agent";
|
|
294
|
+
if (notification.kind === "task_failed") return "Your agent";
|
|
290
295
|
if (notification.kind === "connector_reauth") return "Relay connectors";
|
|
291
296
|
return "Someone";
|
|
292
297
|
}
|