From b5eec3eea9233602c2260400b531bb2aec3721f2 Mon Sep 17 00:00:00 2001
From: DIodide
Date: Sat, 22 Aug 2026 15:58:53 -0400
Subject: [PATCH] Reconcile connections per message; surface OAuth callback
errors; style CTA
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Open chats deduped setup() by settings hash, so a Google Calendar
consent finished on My apps never reached them — the model kept saying
no calendar tool existed. Every send now forces a reconcile (no-op for
already-connected apps, picks up newly tokened ones).
A failed OAuth callback redirected to /apps?error=... which nothing
displayed; My apps now shows the error on a sticky note with recovery
guidance. The "Connect with Google" link becomes a proper button
instead of a bare blue underline.
Claude-Session: https://claude.ai/code/session_01MKLJUWk6biNAKXupHTTWn5
---
app/src/client/pages/AppsPage.tsx | 17 +++++++++++++++--
app/src/client/pages/ChatPage.tsx | 8 +++++---
app/src/client/styles.css | 17 +++++++++++++++++
3 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/app/src/client/pages/AppsPage.tsx b/app/src/client/pages/AppsPage.tsx
index 4892b7f..e7e7ff5 100644
--- a/app/src/client/pages/AppsPage.tsx
+++ b/app/src/client/pages/AppsPage.tsx
@@ -18,6 +18,11 @@ export function AppsPage({
}) {
const desk = useDesk(settings);
const [saving, setSaving] = useState(false);
+ const [callbackError] = useState(() => {
+ const err = new URLSearchParams(location.search).get("error");
+ if (err) history.replaceState(null, "", "/apps");
+ return err;
+ });
// Reconcile connections on arrival so statuses and any pending Google
// consent link are current, not left over from the last visit.
@@ -76,6 +81,14 @@ export function AppsPage({
read and act on — flip them anytime.
+ {callbackError && (
+
+ that didn't finish —
+ connecting Google Calendar failed: {callbackError}. Toggle it off
+ and on to get a fresh link, then try again.
+
+ )}
+