relay-companion 0.1.95 → 0.1.97

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.
@@ -682,8 +682,6 @@
682
682
  /* Conversation messages read like a group chat: each person's own messages
683
683
  sit on one side, and every party's name keeps a stable color so a busy
684
684
  thread is scannable by who-said-what (the WhatsApp convention). */
685
- .th-detail-title { padding:2px 16px 10px; font-family:var(--serif); font-size:15px; line-height:1.3; color:var(--ink); font-weight:600; overflow-wrap:anywhere; }
686
- .th-detail-title:empty { display:none; }
687
685
  .th-msg { position:relative; display:block; width:100%; text-align:left; appearance:none; border:0; cursor:pointer; background:transparent; padding:11px 16px; border-bottom:1px solid var(--hair); font-family:var(--sans); }
688
686
  .th-msg:hover { background:rgba(31,26,23,.035); }
689
687
  .th-msg.expanded { background:rgba(31,26,23,.045); }
@@ -695,16 +693,16 @@
695
693
  overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow-wrap:anywhere; }
696
694
  .th-msg.unread .th-msg-title { color:var(--ink); font-weight:500; }
697
695
  /* Your own messages hang to the right, like your side of a group chat. */
698
- .th-msg.mine { text-align:right; background:rgba(31,26,23,.022); }
696
+ .th-msg.mine { text-align:right; }
699
697
  .th-msg.mine .th-msg-top { flex-direction:row-reverse; }
700
698
  .th-msg.mine .th-party { text-align:right; }
701
699
  .th-msg.mine .th-msg-title { text-align:right; }
702
700
  /* Per-party name colors. Assigned by a stable hash of the party name, so a
703
701
  person keeps the same color across every conversation and every restart. */
704
- .th-party.p0 { color:#1f6f5c; } .th-party.p1 { color:#8a4b2a; } .th-party.p2 { color:#4a4aa8; }
705
- .th-party.p3 { color:#8a2f5e; } .th-party.p4 { color:#2f6f8a; } .th-party.p5 { color:#6b5a1f; }
706
- .th-party.p6 { color:#7a3030; } .th-party.p7 { color:#3f6b2a; }
707
- .th-party.me { color:var(--accent); }
702
+ .th-party.p0 { color:#4a6b5f; } .th-party.p1 { color:#7a5540; } .th-party.p2 { color:#53607d; }
703
+ .th-party.p3 { color:#75485f; } .th-party.p4 { color:#456a76; } .th-party.p5 { color:#6b6142; }
704
+ .th-party.p6 { color:#7a4f4a; } .th-party.p7 { color:#4f6748; }
705
+ .th-party.me { color:var(--muted); }
708
706
 
709
707
  /* Sent-row read receipt chip: "read" sits in a light-green enclosure, "unread" stays quiet. */
710
708
  .sent-chip {
@@ -762,6 +760,10 @@
762
760
  .sv-note { padding:10px 16px 0; font-size:11.5px; color:#1a7f37; line-height:1.4; }
763
761
  .sv-version { padding:20px 16px 12px; font-family:var(--mono); font-size:10.5px; color:var(--muted-3); }
764
762
  .sv-update { display:flex; flex-direction:column; gap:8px; align-items:flex-start; }
763
+ /* The OS default browser is often NOT where the user's session lives, so the
764
+ setup URL is shown here to open wherever they are actually signed in. */
765
+ .sv-url { padding-top:2px; }
766
+ .sv-url-text { font-family:var(--mono); font-size:10px; color:var(--muted-2); user-select:text; overflow-wrap:anywhere; }
765
767
  .sv-update-btn { width:auto; padding:7px 12px; border-radius:8px; font-family:var(--sans); font-size:12px; }
766
768
  /* signed-out call-to-action on the Relays empty state — quiet filled pill (th-count language) */
767
769
  .sv-signin-banner {
@@ -846,7 +848,6 @@
846
848
  </button>
847
849
  <span class="th-detail-name" id="thDetailName"></span>
848
850
  </div>
849
- <div class="th-detail-title" id="thDetailTitle"></div>
850
851
  <div id="thHistory"></div>
851
852
  </div>
852
853
  </section>
@@ -963,7 +964,6 @@
963
964
  const thDetailEl = document.getElementById("thDetail");
964
965
  const thBackEl = document.getElementById("thBack");
965
966
  const thDetailNameEl = document.getElementById("thDetailName");
966
- const thDetailTitleEl = document.getElementById("thDetailTitle");
967
967
  const thHistoryEl = document.getElementById("thHistory");
968
968
  const settingsViewEl = document.getElementById("settingsView");
969
969
  const signInBannerEl = document.getElementById("signInBanner");
@@ -2176,6 +2176,7 @@
2176
2176
  btn.addEventListener("click", () => {
2177
2177
  expandedSentId = null;
2178
2178
  openRelayFromUI(id, "sent", "current");
2179
+ renderSent(); // the menu must close on screen, not just in state
2179
2180
  });
2180
2181
  }
2181
2182
  for (const btn of sentListEl.querySelectorAll("[data-sent-open-fresh]")) {
@@ -2183,6 +2184,7 @@
2183
2184
  btn.addEventListener("click", () => {
2184
2185
  expandedSentId = null;
2185
2186
  openRelayFromUI(id, "sent", "fresh");
2187
+ renderSent(); // the menu must close on screen, not just in state
2186
2188
  });
2187
2189
  }
2188
2190
  }
@@ -3109,11 +3111,6 @@
3109
3111
  return;
3110
3112
  }
3111
3113
  thDetailNameEl.textContent = thread.party;
3112
- // The conversation's name sits under the party, the way a chat header shows
3113
- // the subject: an explicit thread title when one was set, else the relay
3114
- // that started the exchange. Hidden when it would only repeat the party.
3115
- const headerTitle = String(thread.title || "").trim();
3116
- thDetailTitleEl.textContent = headerTitle && headerTitle !== thread.party ? headerTitle : "";
3117
3114
  // Thread-level opens act on the newest inbound message (falling back to the
3118
3115
  // newest message overall): "current" injects with the threadId so the agent
3119
3116
  // fetches the whole exchange; "new chat" seeds the full transcript.
@@ -3270,7 +3267,8 @@
3270
3267
  maxlength="16" placeholder="Pairing code" value="${esc(svDraft)}" ${svBusy ? "disabled" : ""} />
3271
3268
  <button class="sv-connect" type="button" id="svConnect" ${svBusy ? "disabled" : ""}>${svBusy ? "Connecting…" : "Connect"}</button>
3272
3269
  </div>
3273
- <div class="sv-hint">Your browser opened the Relay setup page — paste the pairing code it shows.</div>`;
3270
+ <div class="sv-hint">Your browser opened the Relay setup page — paste the pairing code it shows.</div>
3271
+ <div class="sv-hint sv-url" data-stop="1">Wrong browser? Open this there instead:<br><span class="sv-url-text" id="svSetupUrl">${esc((settingsInfo && settingsInfo.setupUrl) || "")}</span></div>`;
3274
3272
  }
3275
3273
  function renderSettings() {
3276
3274
  if (activeView !== "settings") return;
package/overlay/main.cjs CHANGED
@@ -455,7 +455,15 @@ function accountInfo() {
455
455
  // not only in the tray menu.
456
456
  updateAvailable: availableUpdate || "",
457
457
  updating: updateInFlight,
458
- setupPath: "/app/setup",
458
+ // Route through the app's OWN sign-in, not Clerk's hosted accounts.<domain>
459
+ // subdomain. Clerk runs here in proxy mode (/__clerk), and the accounts./clerk.
460
+ // hosts present NO certificate — the handshake fails outright, so a signed-out
461
+ // user hitting /app/setup was bounced to a page no browser can load. /sign-in
462
+ // renders through the proxy and carries the user on to setup afterwards.
463
+ setupPath: "/sign-in?redirect_url=%2Fapp%2Fsetup",
464
+ // Shown in the pill so the flow is not trapped in whichever browser the OS
465
+ // considers default (the session usually lives in a different one).
466
+ setupUrl: absoluteUrl("/sign-in?redirect_url=%2Fapp%2Fsetup"),
459
467
  };
460
468
  }
461
469
 
@@ -3161,6 +3169,10 @@ function quitRelayCompletely() {
3161
3169
  let availableUpdate = null; // version string when newer than what we run
3162
3170
  let updateInFlight = false;
3163
3171
  async function checkForUpdate() {
3172
+ // A sandboxed harness must never consult the registry: whether an update
3173
+ // happens to be published mid-run would otherwise change the Settings card's
3174
+ // version line and make an assertion pass or fail on release timing.
3175
+ if (process.env.RELAY_OVERLAY_TEST === "1" || process.env.RELAY_OVERLAY_PERF === "1") return;
3164
3176
  try {
3165
3177
  const mod = await import(pathToFileURL(path.join(__dirname, "..", "src", "auto-update.js")).href);
3166
3178
  const latest = await mod.fetchLatestVersion({});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relay-companion",
3
- "version": "0.1.95",
3
+ "version": "0.1.97",
4
4
  "description": "Relay companion for ordinary messages, with dormant coordination features available only by explicit opt-in.",
5
5
  "type": "module",
6
6
  "bin": {