diff --git a/lib/__tests__/plugin-host-features.test.ts b/lib/__tests__/plugin-host-features.test.ts index bea136c3a..9db8a0e83 100644 --- a/lib/__tests__/plugin-host-features.test.ts +++ b/lib/__tests__/plugin-host-features.test.ts @@ -172,5 +172,10 @@ describe('api.host in the sandbox runtime', () => { expect((kept as { sidePanel?: boolean }).sidePanel).toBe(true); post(hostWindow, HOST_ORIGIN, { type: 'host-change', features: { externalSenderLabel: true, externalRecipientWarning: false, noThirdPartyTraffic: true, sidePanel: 'yes' } }); expect((kept as { sidePanel?: boolean }).sidePanel).toBe(false); + // A flag the host no longer names turns off instead of keeping its old value. + post(hostWindow, HOST_ORIGIN, { type: 'host-change', features: { externalSenderLabel: true, externalRecipientWarning: false, noThirdPartyTraffic: true, sidePanel: true } }); + expect((kept as { sidePanel?: boolean }).sidePanel).toBe(true); + post(hostWindow, HOST_ORIGIN, { type: 'host-change', features: { externalSenderLabel: true, externalRecipientWarning: false, noThirdPartyTraffic: true } }); + expect((kept as { sidePanel?: boolean }).sidePanel).toBe(false); }, 30_000); }); diff --git a/lib/plugin-sandbox/runtime.tsx b/lib/plugin-sandbox/runtime.tsx index ab741c7a9..62215aafe 100644 --- a/lib/plugin-sandbox/runtime.tsx +++ b/lib/plugin-sandbox/runtime.tsx @@ -161,10 +161,15 @@ function applyHostFeatures(next: HostFeaturesView | undefined): void { hostFeaturesState.externalRecipientWarning = next.externalRecipientWarning === true; // A host older than 1.20 doesn't send it, and never let such a plugin run in the mode. hostFeaturesState.noThirdPartyTraffic = next.noThirdPartyTraffic === true; - // The AI assistant's flags (lib/plugin-sandbox/assistant): whatever the host names, true or false. + // The AI assistant's flags (lib/plugin-sandbox/assistant): whatever the host + // names, true or false; one it no longer names turns false. const flags = hostFeaturesState as unknown as Record; + const core = new Set(['externalSenderLabel', 'externalRecipientWarning', 'noThirdPartyTraffic']); + for (const key of Object.keys(flags)) { + if (!core.has(key) && !(key in next)) flags[key] = false; + } for (const [key, value] of Object.entries(next)) { - if (key !== 'externalSenderLabel' && key !== 'externalRecipientWarning' && key !== 'noThirdPartyTraffic') flags[key] = value === true; + if (!core.has(key)) flags[key] = value === true; } for (const listener of hostFeatureListeners) { try { listener(hostFeaturesState); } catch (err) { console.error('[plugin] host feature listener failed', err); }