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.
@@ -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
- if (!win.isVisible()) win.showInactive();
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
- if (!win.isVisible()) win.showInactive();
707
+ showOverlayWindow();
696
708
  } else if (win.isVisible()) {
697
709
  win.hide();
698
710
  }
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relay-companion",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Relay companion: connects local coding agents to Relay tasks, approvals, and connector tools.",
5
5
  "type": "module",
6
6
  "bin": {
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
- return { content: [{ type: "text", text: `Relay error: ${err.message}` }], isError: true };
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
 
@@ -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
  }