diff --git a/.lane/memory/apps/app/src/composer.tsx/01M4YQG7BVWEFZPD56A2BA0VE9-mode-ace-mode-channels-id-an.md b/.lane/memory/apps/app/src/composer.tsx/01M4YQG7BVWEFZPD56A2BA0VE9-mode-ace-mode-channels-id-an.md index ad94eac4..5e7486db 100644 --- a/.lane/memory/apps/app/src/composer.tsx/01M4YQG7BVWEFZPD56A2BA0VE9-mode-ace-mode-channels-id-an.md +++ b/.lane/memory/apps/app/src/composer.tsx/01M4YQG7BVWEFZPD56A2BA0VE9-mode-ace-mode-channels-id-an.md @@ -4,9 +4,9 @@ anchor: function Composer created: 2026-10-15T02:50:44Z norm: '1' sig: 6e0e6c5c8afbd01a -body_hash: f1ce2fae59a8c894 -raw_hash: 0815737299df6f4a -vouched: 2026-10-22T15:28:03Z +body_hash: 5d41556386df9599 +raw_hash: da6fdc606e9e685b +vouched: 2026-10-22T15:31:22Z lines: 99-282 --- diff --git a/.lane/memory/apps/app/src/composer.tsx/01M4ZSEZBJJ3AMEBTR7SH36FW4-models-are-read-only-while-t.md b/.lane/memory/apps/app/src/composer.tsx/01M4ZSEZBJJ3AMEBTR7SH36FW4-models-are-read-only-while-t.md index 5869134e..57745d3c 100644 --- a/.lane/memory/apps/app/src/composer.tsx/01M4ZSEZBJJ3AMEBTR7SH36FW4-models-are-read-only-while-t.md +++ b/.lane/memory/apps/app/src/composer.tsx/01M4ZSEZBJJ3AMEBTR7SH36FW4-models-are-read-only-while-t.md @@ -4,9 +4,9 @@ anchor: function Composer created: 2026-10-15T12:44:15Z norm: '1' sig: 6e0e6c5c8afbd01a -body_hash: f1ce2fae59a8c894 -raw_hash: 0815737299df6f4a -vouched: 2026-10-22T15:28:03Z +body_hash: 5d41556386df9599 +raw_hash: da6fdc606e9e685b +vouched: 2026-10-22T15:31:22Z lines: 101-290 --- diff --git a/.lane/memory/apps/app/src/composer.tsx/01M4ZYQVGB6C87WBEV12WPQ8PF-a-withdrawn-message-returns.md b/.lane/memory/apps/app/src/composer.tsx/01M4ZYQVGB6C87WBEV12WPQ8PF-a-withdrawn-message-returns.md index 8b8e293e..96402efd 100644 --- a/.lane/memory/apps/app/src/composer.tsx/01M4ZYQVGB6C87WBEV12WPQ8PF-a-withdrawn-message-returns.md +++ b/.lane/memory/apps/app/src/composer.tsx/01M4ZYQVGB6C87WBEV12WPQ8PF-a-withdrawn-message-returns.md @@ -4,9 +4,9 @@ anchor: function Composer created: 2026-10-15T14:16:28Z norm: '1' sig: 6e0e6c5c8afbd01a -body_hash: f1ce2fae59a8c894 -raw_hash: 0815737299df6f4a -vouched: 2026-10-22T15:28:03Z +body_hash: 5d41556386df9599 +raw_hash: da6fdc606e9e685b +vouched: 2026-10-22T15:31:22Z lines: 104-326 --- diff --git a/.lane/memory/apps/app/src/panels/terminal.tsx/01M4YSG7VPSWA76RMR94GF5184-the-terminal-s-cmd-k-clear-m.md b/.lane/memory/apps/app/src/panels/terminal.tsx/01M4YSG7VPSWA76RMR94GF5184-the-terminal-s-cmd-k-clear-m.md index fc8fd344..dc249326 100644 --- a/.lane/memory/apps/app/src/panels/terminal.tsx/01M4YSG7VPSWA76RMR94GF5184-the-terminal-s-cmd-k-clear-m.md +++ b/.lane/memory/apps/app/src/panels/terminal.tsx/01M4YSG7VPSWA76RMR94GF5184-the-terminal-s-cmd-k-clear-m.md @@ -4,9 +4,9 @@ anchor: function Terminal created: 2026-10-15T03:25:42Z norm: '1' sig: 9ad6b07a24fa0261 -body_hash: 911da63f1fbfb712 -raw_hash: 90f1050382e16903 -vouched: 2026-10-22T15:24:30Z +body_hash: 89146e5bb0652ae2 +raw_hash: 14dc8c2e9a8e17aa +vouched: 2026-10-22T15:30:11Z lines: 124-294 --- diff --git a/.lane/memory/packages/ui/src/components/composer/chat-composer.tsx/01M53E0S8M7RPD1RK65J9NG78E-dictation-writes-only-betwee.md b/.lane/memory/packages/ui/src/components/composer/chat-composer.tsx/01M53E0S8M7RPD1RK65J9NG78E-dictation-writes-only-betwee.md index 8b298260..a73fca06 100644 --- a/.lane/memory/packages/ui/src/components/composer/chat-composer.tsx/01M53E0S8M7RPD1RK65J9NG78E-dictation-writes-only-betwee.md +++ b/.lane/memory/packages/ui/src/components/composer/chat-composer.tsx/01M53E0S8M7RPD1RK65J9NG78E-dictation-writes-only-betwee.md @@ -4,9 +4,9 @@ anchor: function useComposer created: 2026-10-16T22:41:13Z norm: '1' sig: 381929b0cbaf2245 -body_hash: 17515b9210059870 -raw_hash: 30786624d9379566 -vouched: 2026-10-22T15:02:44Z +body_hash: f4f3cc3dac113b90 +raw_hash: 1066200fbc3f634c +vouched: 2026-10-22T15:29:58Z lines: 597-1226 --- diff --git a/.lane/memory/packages/ui/src/hooks/use-dictation.ts/01M53CZ2RRXDYDPZWZ8AKNMFH0-deactivating-aborts-and-deta.md b/.lane/memory/packages/ui/src/hooks/use-dictation.ts/01M53CZ2RRXDYDPZWZ8AKNMFH0-deactivating-aborts-and-deta.md index ffa07226..05e055d8 100644 --- a/.lane/memory/packages/ui/src/hooks/use-dictation.ts/01M53CZ2RRXDYDPZWZ8AKNMFH0-deactivating-aborts-and-deta.md +++ b/.lane/memory/packages/ui/src/hooks/use-dictation.ts/01M53CZ2RRXDYDPZWZ8AKNMFH0-deactivating-aborts-and-deta.md @@ -3,9 +3,10 @@ id: 01M53CZ2RRXDYDPZWZ8AKNMFH0 anchor: function useDictation created: 2026-10-16T22:22:49Z norm: '1' -sig: de94e6fe0d9626d6 -body_hash: 78e3734a05619b3c -raw_hash: 85cbb253122dfd32 +sig: 85f78e4a517cc347 +body_hash: 95229acf42918e4c +raw_hash: 809dc7b3b022a7fc +vouched: 2026-10-22T15:29:59Z lines: 28-51 --- diff --git a/apps/app/src/app.tsx b/apps/app/src/app.tsx index 54260b4b..330bba53 100644 --- a/apps/app/src/app.tsx +++ b/apps/app/src/app.tsx @@ -34,7 +34,7 @@ import { projectId, } from "@ace/host/protocol"; -import { chosen, deployed, remember } from "./address"; +import { chosen, deployed, gateway, remember } from "./address"; import { type Attention, glow, useAttention } from "./attention"; import { Channel, ChannelDetails, type ChannelDraft } from "./channel"; import { useCompute } from "./compute"; @@ -107,12 +107,38 @@ function ChannelsSidebar(props: SessionSidebarProps) { ); } +/** + * Whether the deployed app's host answers HTTP at all. A browser hides why a WebSocket failed, but + * an opaque no-cors response still proves the host is reachable, so its gateway refused this app. + */ +function useAnswers(): boolean | undefined { + const [answers, setAnswers] = useState(); + useEffect(() => { + if (!deployed || !gateway) return; + const url = new URL(gateway.replace(/^ws/, "http")); + url.pathname = "/"; + fetch(url, { mode: "no-cors", cache: "no-store" }).then( + () => setAnswers(true), + () => setAnswers(false), + ); + }, []); + return answers; +} + function Disconnected() { + const answers = useAnswers(); if (desktop) return <>Disconnected from Ace Helper. Open Settings → This Mac to start it.; if (!deployed) return <>Disconnected from your host. Reconnecting…; return ( <> - Can't reach {chosen}. Check that Tailscale is on.{" "} + {answers + ? ( + <> + {chosen} refused this web app. On that host, run{" "} + ace web {location.origin}, then reload. + + ) + : <>Can't reach {chosen}. Check that Tailscale is on.}{" "} )} - {!editing && ( + {/* A saved key would go unused while the environment overrides it. */} + {!editing && !provider.override && (