fix(apps): read the settled sandbox URL from a ref at client construction
The previous round's `await` did not do what it claimed. `setupClientForServer` is synchronous and memoized, so a caller that awaited the config resumed with the `sandboxUrl` captured by the render it STARTED in — undefined, on exactly the load the wait was added for. The deep-link one-shot guard then prevented a retry, so that connection silently lost the capability despite having a sandbox. The OAuth-callback path did not wait at all. Construction now reads a ref written every render, so it sees the current value whichever entry point reached it, and the OAuth path waits like the connect path does. The wait still matters — it is what makes an absent value mean 'confirmed absent' rather than 'not known yet' — but the ref is what makes the value read be the settled one. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
ce263366b6
commit
356e8eaa8a
1 changed files with 11 additions and 2 deletions
|
|
@ -818,6 +818,13 @@ function App() {
|
|||
// entry would otherwise be rendered by a factory bound to the replacement
|
||||
// client, i.e. read and answered through a different server.
|
||||
const appElicitationSessionRef = useRef<AppElicitationSession>(null);
|
||||
// `setupClientForServer` is synchronous and memoized, so a caller that
|
||||
// awaited the config would still resume with the `sandboxUrl` captured by the
|
||||
// render it STARTED in — undefined, on the very load this matters for. The
|
||||
// ref is written every render, so client construction reads the current value
|
||||
// whichever entry point (connect, deep link, OAuth callback) reached it.
|
||||
const sandboxUrlRef = useRef<string | undefined>(undefined);
|
||||
sandboxUrlRef.current = sandboxUrl;
|
||||
// Whether the sandbox exists is only known once `/api/config` resolves, and
|
||||
// the answer is baked into the client at construction (it decides whether the
|
||||
// nested MCP Apps `elicitation` capability is advertised). So a connect waits
|
||||
|
|
@ -2518,7 +2525,7 @@ function App() {
|
|||
// here means "confirmed absent" rather than "not known yet" — a
|
||||
// connection that reaches this with no sandbox behaves like the
|
||||
// CLI/TUI: native elicitation queue, no claim made to the server.
|
||||
...(sandboxUrl && {
|
||||
...(sandboxUrlRef.current && {
|
||||
appElicitation: newAppElicitationSession().render,
|
||||
}),
|
||||
// Always advertise the roots capability (even with no configured
|
||||
|
|
@ -2623,7 +2630,6 @@ function App() {
|
|||
onBeforeOAuthRedirect,
|
||||
clientConfig,
|
||||
newAppElicitationSession,
|
||||
sandboxUrl,
|
||||
],
|
||||
);
|
||||
|
||||
|
|
@ -2743,6 +2749,9 @@ function App() {
|
|||
}
|
||||
|
||||
void (async () => {
|
||||
// Same reason as the connect path: whether this client may advertise
|
||||
// app-rendered elicitation is fixed at construction.
|
||||
await initialConfigSettledRef.current?.promise;
|
||||
try {
|
||||
await webOAuthStorage.load();
|
||||
} catch (err) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue