From 581f2cecbd09c1891ff0656028f304f30f0b6a04 Mon Sep 17 00:00:00 2001 From: Evie Gauthier Date: Tue, 31 Mar 2026 10:46:35 -0400 Subject: [PATCH 1/7] feat(dev-tools): add rotate-sessions developer tool --- .../settings/developer-tools/DevelopTools.tsx | 82 ++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/src/app/features/settings/developer-tools/DevelopTools.tsx b/src/app/features/settings/developer-tools/DevelopTools.tsx index c8ffeb12d..6478d9582 100644 --- a/src/app/features/settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/settings/developer-tools/DevelopTools.tsx @@ -1,5 +1,6 @@ import { useCallback, useState } from 'react'; -import { Box, Text, Scroll, Switch, Button } from 'folds'; +import { Box, Text, Scroll, Switch, Button, Spinner, color } from 'folds'; +import { KnownMembership } from 'matrix-js-sdk/lib/types'; import { PageContent } from '$components/page'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; @@ -10,6 +11,7 @@ import { AccountDataEditor, AccountDataSubmitCallback } from '$components/Accoun import { copyToClipboard } from '$utils/dom'; import { SequenceCardStyle } from '$features/settings/styles.css'; import { SettingsSectionPage } from '../SettingsSectionPage'; +import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; import { AccountData } from './AccountData'; import { SyncDiagnostics } from './SyncDiagnostics'; import { DebugLogViewer } from './DebugLogViewer'; @@ -25,6 +27,33 @@ export function DeveloperTools({ requestBack, requestClose }: DeveloperToolsProp const [expand, setExpend] = useState(false); const [accountDataType, setAccountDataType] = useState(); + const [rotateState, rotateAllSessions] = useAsyncCallback< + { rotated: number; total: number }, + Error, + [] + >( + useCallback(async () => { + const crypto = mx.getCrypto(); + if (!crypto) throw new Error('Crypto module not available'); + + const encryptedRooms = mx + .getRooms() + .filter( + (room) => + room.getMyMembership() === KnownMembership.Join && mx.isRoomEncrypted(room.roomId) + ); + + await Promise.all(encryptedRooms.map((room) => crypto.forceDiscardSession(room.roomId))); + const rotated = encryptedRooms.length; + + // Proactively start session creation + key sharing with all devices + // (including bridge bots). fire-and-forget per room. + encryptedRooms.forEach((room) => crypto.prepareToEncrypt(room)); + + return { rotated, total: encryptedRooms.length }; + }, [mx]) + ); + const submitAccountData: AccountDataSubmitCallback = useCallback( async (type, content) => { // TODO: remove cast once account data typing is unified. @@ -109,6 +138,57 @@ export function DeveloperTools({ requestBack, requestClose }: DeveloperToolsProp )} {developerTools && } + {developerTools && ( + + Encryption + + + ) + } + > + + {rotateState.status === AsyncStatus.Loading ? 'Rotating…' : 'Rotate'} + + + } + > + {rotateState.status === AsyncStatus.Success && ( + + Sessions discarded for {rotateState.data.rotated} of{' '} + {rotateState.data.total} encrypted rooms. Key sharing is starting in the + background — send a message in an affected room to confirm delivery to + bridges. + + )} + {rotateState.status === AsyncStatus.Error && ( + + {rotateState.error.message} + + )} + + + + )} {developerTools && ( Date: Tue, 31 Mar 2026 12:06:31 -0400 Subject: [PATCH 2/7] chore: add changeset for devtool-rotate-sessions --- .changeset/devtool-rotate-sessions.md | 5 +++++ src/app/features/settings/developer-tools/DevelopTools.tsx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/devtool-rotate-sessions.md diff --git a/.changeset/devtool-rotate-sessions.md b/.changeset/devtool-rotate-sessions.md new file mode 100644 index 000000000..2730ad8e6 --- /dev/null +++ b/.changeset/devtool-rotate-sessions.md @@ -0,0 +1,5 @@ +--- +default: patch +--- + +Add rotate-sessions developer tool to force session rotation for testing diff --git a/src/app/features/settings/developer-tools/DevelopTools.tsx b/src/app/features/settings/developer-tools/DevelopTools.tsx index 6478d9582..c9d934aec 100644 --- a/src/app/features/settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/settings/developer-tools/DevelopTools.tsx @@ -10,8 +10,8 @@ import { useMatrixClient } from '$hooks/useMatrixClient'; import { AccountDataEditor, AccountDataSubmitCallback } from '$components/AccountDataEditor'; import { copyToClipboard } from '$utils/dom'; import { SequenceCardStyle } from '$features/settings/styles.css'; -import { SettingsSectionPage } from '../SettingsSectionPage'; import { AsyncStatus, useAsyncCallback } from '$hooks/useAsyncCallback'; +import { SettingsSectionPage } from '../SettingsSectionPage'; import { AccountData } from './AccountData'; import { SyncDiagnostics } from './SyncDiagnostics'; import { DebugLogViewer } from './DebugLogViewer'; From cd5192bdd6a8aa7725f2b8094a3733ce9dcc170d Mon Sep 17 00:00:00 2001 From: Evie Gauthier Date: Tue, 14 Apr 2026 22:55:00 -0400 Subject: [PATCH 3/7] fix(dev-tools): address review feedback for rotate-sessions - Import KnownMembership from $types/matrix-sdk instead of matrix-js-sdk/lib/types - Use Promise.allSettled to handle partial failures and report accurate count - Add window.confirm confirmation before discarding sessions - Clarify changeset: 'encryption sessions' not 'sessions' --- .changeset/devtool-rotate-sessions.md | 2 +- build.log | 114 ++++++++++++++++++ full_output.txt | 0 lint_output.txt | 62 ++++++++++ .../settings/developer-tools/DevelopTools.tsx | 16 ++- test_file.txt | 1 + 6 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 build.log create mode 100644 full_output.txt create mode 100644 lint_output.txt create mode 100644 test_file.txt diff --git a/.changeset/devtool-rotate-sessions.md b/.changeset/devtool-rotate-sessions.md index 2730ad8e6..cae1bda0c 100644 --- a/.changeset/devtool-rotate-sessions.md +++ b/.changeset/devtool-rotate-sessions.md @@ -2,4 +2,4 @@ default: patch --- -Add rotate-sessions developer tool to force session rotation for testing +Add rotate-encryption-sessions developer tool to force Megolm session rotation for testing diff --git a/build.log b/build.log new file mode 100644 index 000000000..1f5016d8d --- /dev/null +++ b/build.log @@ -0,0 +1,114 @@ + +> sable@1.14.0 build /Users/evie/git/Sable +> vite build + +vite v7.3.1 building client environment for production... +transforming... +✓ 8032 modules transformed. +rendering chunks... +computing gzip size... +[vite-plugin-static-copy] Copied 10 items. +dist/.assetsignore 0.02 kB +dist/assets/index-Ds5yF1gS.js.br 0.07 kB +dist/assets/index-Ds5yF1gS.js.map.br 0.41 kB +dist/wrangler.json.br 0.42 kB +dist/assets/cinny-logo-maskable-36x36-CT1Bq-jJ.png 0.79 kB +dist/index.html.br 0.88 kB +dist/assets/cinny-logo-maskable-DXG8PKa6.svg.br 0.96 kB +dist/wrangler.json 1.00 kB │ gzip: 0.54 kB +dist/assets/cinny-logo-maskable-48x48-DfxQ4FEO.png 1.08 kB +dist/assets/cinny-logo-maskable-57x57-B_a6RKlt.png 1.28 kB +dist/assets/cinny-logo-maskable-60x60-uAvO2kwU.png 1.35 kB +dist/assets/cinny-logo-maskable-72x72-ChMts4zW.png 1.59 kB +dist/assets/cinny-logo-maskable-96x96-DeladQJ2.png 2.08 kB +dist/assets/cinny-logo-maskable-114x114-BRz0LILn.png 2.45 kB +dist/assets/cinny-logo-maskable-DXG8PKa6.svg 2.56 kB │ gzip: 1.12 kB +dist/assets/cinny-logo-maskable-120x120-BBcwUWQZ.png 2.59 kB +dist/assets/cinny-logo-maskable-144x144-CitAVeb0.png 3.08 kB +dist/assets/cinny-logo-maskable-152x152-Di3nKfIW.png 3.26 kB +dist/assets/cinny-logo-maskable-167x167-Dk9KG9Yi.png 3.59 kB +dist/assets/cinny-logo-maskable-180x180-RAgvvHf4.png 3.79 kB +dist/assets/cinny-logo-maskable-192x192-BHxZuLYc.png 4.06 kB +dist/assets/favicon-CemZgig7.png 4.15 kB +dist/index.html 4.28 kB │ gzip: 1.17 kB +dist/assets/arborium-4uGfF3G6.js.br 4.54 kB +dist/assets/arborium-4uGfF3G6.js.map.br 4.98 kB +dist/assets/space-mono-vietnamese-700-italic-BwPKnf-l.woff 5.24 kB +dist/assets/space-mono-vietnamese-400-normal-B0PMp_xB.woff 5.41 kB +dist/assets/space-mono-vietnamese-700-normal-D-KrLuLr.woff 5.45 kB +dist/assets/cinny-logo-maskable-256x256-B_icl17M.png 5.58 kB +dist/assets/space-mono-vietnamese-400-italic-DvlTUS1j.woff 5.88 kB +dist/assets/space-mono-vietnamese-400-normal-BNOj0Qhp.woff2 7.27 kB +dist/assets/space-mono-vietnamese-700-normal-DWQgDHuA.woff2 7.33 kB +dist/assets/space-mono-vietnamese-700-italic-i2bR4MHS.woff2 7.39 kB +dist/assets/cinny-logo-maskable-384x384-DA-2uwBp.png 8.52 kB +dist/assets/space-mono-vietnamese-400-italic-CyQIvI4V.woff2 9.69 kB +dist/assets/notification-EtLMRd0T.ogg 11.30 kB +dist/assets/cinny-logo-maskable-512x512-dB91iLyU.png 11.87 kB +dist/assets/space-mono-latin-400-normal-_3DlpgIW.woff 12.31 kB +dist/assets/space-mono-latin-700-normal-D7A851RN.woff 12.42 kB +dist/assets/space-mono-latin-ext-700-normal-B_E7P90g.woff 12.48 kB +dist/assets/space-mono-latin-ext-400-normal-D4cJI_B-.woff 12.61 kB +dist/assets/space-mono-latin-ext-400-italic-DYA_DB_l.woff 12.89 kB +dist/assets/nunito-vietnamese-wght-normal-U01xdrZh.woff2 13.10 kB +dist/assets/space-mono-latin-ext-700-italic-CbHMtIk0.woff 13.14 kB +dist/assets/space-mono-latin-700-italic-B8C1HgwN.woff 13.65 kB +dist/assets/space-mono-latin-400-italic-zmx7Qf09.woff 13.82 kB +dist/assets/nunito-vietnamese-wght-italic-5K55R7rt.woff2 14.77 kB +dist/assets/space-mono-latin-ext-700-normal-B2s3bDs2.woff2 15.81 kB +dist/assets/space-mono-latin-ext-400-normal-DTLbW2xa.woff2 15.83 kB +dist/assets/space-mono-latin-400-normal-Rg4St2Dn.woff2 16.52 kB +dist/assets/space-mono-latin-700-normal-mWgeinG7.woff2 16.72 kB +dist/assets/space-mono-latin-ext-400-italic-x3PrlAeq.woff2 17.20 kB +dist/assets/space-mono-latin-ext-700-italic-CkCrmjWu.woff2 17.74 kB +dist/assets/space-mono-latin-400-italic-YylcN9Ay.woff2 18.30 kB +dist/assets/space-mono-latin-700-italic-vNvENeTh.woff2 18.64 kB +dist/assets/index-C5lozGWL.css.br 20.47 kB +dist/assets/nunito-cyrillic-wght-normal-CY6AOgYE.woff2 20.78 kB +dist/assets/nunito-cyrillic-wght-italic-AGUkry7S.woff2 22.90 kB +dist/assets/nunito-cyrillic-ext-wght-normal-D4X5GqEv.woff2 28.93 kB +dist/assets/nunito-cyrillic-ext-wght-italic-C7FdRbwB.woff2 31.51 kB +dist/assets/invite-DROg5x7-.ogg 32.67 kB +dist/assets/nunito-latin-ext-wght-normal-CXYtwYOx.woff2 35.59 kB +dist/assets/nunito-latin-ext-wght-italic-CmZo11nB.woff2 39.07 kB +dist/assets/nunito-latin-wght-normal-BzFMHfZw.woff2 39.13 kB +dist/assets/index-ByL9e3j1.js.br 39.36 kB +dist/assets/nunito-latin-wght-italic-ZB3Aladm.woff2 41.76 kB +dist/assets/pdf-DEJ3BJS6.js.br 130.24 kB +dist/assets/ringtone-4rwYiCEg.webm 139.95 kB +dist/assets/index-ByL9e3j1.js.map.br 140.69 kB +dist/assets/pdf-DEJ3BJS6.js.map.br 290.20 kB +dist/assets/index-BTNFNN8W.js.map.br 302.21 kB +dist/assets/Twemoji.Mozilla.v15.1.0-CM1RS90w.woff2 491.74 kB +dist/assets/index-BTNFNN8W.js.br 951.42 kB +dist/assets/matrix_sdk_crypto_wasm_bg-dMeGppz-.wasm.br 1,333.88 kB +dist/assets/Twemoji.Mozilla.v15.1.0-DHQZm25T.ttf 1,451.58 kB +dist/assets/matrix_sdk_crypto_wasm_bg-dMeGppz-.wasm 5,513.88 kB │ gzip: 1,831.16 kB +dist/assets/index-C5lozGWL.css 156.09 kB │ gzip: 25.73 kB +dist/assets/index-Ds5yF1gS.js 0.08 kB │ gzip: 0.09 kB │ map: 0.96 kB +dist/assets/arborium-4uGfF3G6.js 20.65 kB │ gzip: 5.16 kB │ map: 21.44 kB +dist/assets/index-ByL9e3j1.js 272.42 kB │ gzip: 47.99 kB │ map: 950.66 kB +dist/assets/pdf-DEJ3BJS6.js 755.04 kB │ gzip: 165.12 kB │ map: 1,505.59 kB +dist/assets/index-BTNFNN8W.js 6,603.34 kB │ gzip: 1,316.26 kB │ map: 1,618.30 kB + +(!) Some chunks are larger than 500 kB after minification. Consider: +- Using dynamic import() to code-split the application +- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks +- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit. + +PWA v1.2.0 +Building src/sw.ts service worker ("es" format)... +vite v7.3.1 building client environment for production... +transforming... +✓ 61 modules transformed. +rendering chunks... +computing gzip size... +dist/sw.mjs 37.52 kB │ gzip: 11.63 kB │ map: 232.66 kB + +PWA v1.2.0 +mode injectManifest +format: es +precache 9 entries (14223.46 KiB) +files generated + dist/sw.js + dist/sw.js.map diff --git a/full_output.txt b/full_output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/lint_output.txt b/lint_output.txt new file mode 100644 index 000000000..d0e6288a3 --- /dev/null +++ b/lint_output.txt @@ -0,0 +1,62 @@ + +> sable@1.14.0 lint /Users/evie/git/Sable +> eslint . + + +/Users/evie/git/Sable/src/app/components/url-preview/UrlPreviewCard.tsx + 36:5 warning Unexpected console statement no-console + 97:9 warning Unexpected console statement no-console + 104:11 warning Unexpected console statement no-console + +/Users/evie/git/Sable/src/app/features/room/RoomInput.tsx + 1678:19 warning Unexpected console statement no-console + +/Users/evie/git/Sable/src/app/features/settings/Persona/PerMessageProfileEditor.tsx + 47:3 warning Unexpected console statement no-console + +/Users/evie/git/Sable/src/app/pages/client/ClientNonUIFeatures.tsx + 833:9 warning Unexpected console statement no-console + +/Users/evie/git/Sable/src/app/plugins/call/CallEmbed.ts + 317:7 warning Unexpected console statement no-console + 423:11 warning Unexpected console statement no-console + +/Users/evie/git/Sable/src/app/utils/debugLogger.ts + 87:9 warning Unexpected console statement no-console + +/Users/evie/git/Sable/src/index.tsx + 54:9 warning Unexpected confirm no-alert + +/Users/evie/git/Sable/src/sw.ts + 110:9 warning Unexpected console statement no-console + 117:9 warning Unexpected console statement no-console + 182:5 warning Unexpected console statement no-console + 189:5 warning Unexpected console statement no-console + 222:5 warning Unexpected console statement no-console + 230:7 warning Unexpected console statement no-console + 276:7 warning Unexpected console statement no-console + 281:5 warning Unexpected console statement no-console + 412:11 warning Unexpected console statement no-console + 421:9 warning Unexpected console statement no-console + 448:5 warning Unexpected console statement no-console + 458:5 warning Unexpected console statement no-console + 872:7 warning Unexpected console statement no-console + 914:3 warning Unexpected console statement no-console + 920:3 warning Unexpected console statement no-console + 922:5 warning Unexpected console statement no-console + 927:3 warning Unexpected console statement no-console + 954:5 warning Unexpected console statement no-console + 979:3 warning Unexpected console statement no-console + 980:3 warning Unexpected console statement no-console + 1015:3 warning Unexpected console statement no-console + 1024:7 warning Unexpected console statement no-console + 1031:9 warning Unexpected console statement no-console + 1049:11 warning Unexpected console statement no-console + 1055:7 warning Unexpected console statement no-console + +/Users/evie/git/Sable/src/sw/pushNotification.ts + 48:5 warning Unexpected console statement no-console + 169:7 warning Unexpected console statement no-console + +✖ 37 problems (0 errors, 37 warnings) + diff --git a/src/app/features/settings/developer-tools/DevelopTools.tsx b/src/app/features/settings/developer-tools/DevelopTools.tsx index c9d934aec..e9ef1ee89 100644 --- a/src/app/features/settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/settings/developer-tools/DevelopTools.tsx @@ -1,6 +1,6 @@ import { useCallback, useState } from 'react'; import { Box, Text, Scroll, Switch, Button, Spinner, color } from 'folds'; -import { KnownMembership } from 'matrix-js-sdk/lib/types'; +import { KnownMembership } from '$types/matrix-sdk'; import { PageContent } from '$components/page'; import { SequenceCard } from '$components/sequence-card'; import { SettingTile } from '$components/setting-tile'; @@ -33,6 +33,14 @@ export function DeveloperTools({ requestBack, requestClose }: DeveloperToolsProp [] >( useCallback(async () => { + if ( + !window.confirm( + 'This will discard all current Megolm encryption sessions and start new ones. Continue?' + ) + ) { + throw new Error('Cancelled'); + } + const crypto = mx.getCrypto(); if (!crypto) throw new Error('Crypto module not available'); @@ -43,8 +51,10 @@ export function DeveloperTools({ requestBack, requestClose }: DeveloperToolsProp room.getMyMembership() === KnownMembership.Join && mx.isRoomEncrypted(room.roomId) ); - await Promise.all(encryptedRooms.map((room) => crypto.forceDiscardSession(room.roomId))); - const rotated = encryptedRooms.length; + const results = await Promise.allSettled( + encryptedRooms.map((room) => crypto.forceDiscardSession(room.roomId)) + ); + const rotated = results.filter((r) => r.status === 'fulfilled').length; // Proactively start session creation + key sharing with all devices // (including bridge bots). fire-and-forget per room. diff --git a/test_file.txt b/test_file.txt new file mode 100644 index 000000000..9daeafb98 --- /dev/null +++ b/test_file.txt @@ -0,0 +1 @@ +test From 8cdf36a0bf8e0da1958bd7655795526f821d60be Mon Sep 17 00:00:00 2001 From: Evie Gauthier Date: Tue, 14 Apr 2026 22:55:09 -0400 Subject: [PATCH 4/7] chore: remove accidentally committed scratch files --- build.log | 114 ------------------------------------------------ full_output.txt | 0 lint_output.txt | 62 -------------------------- test_file.txt | 1 - 4 files changed, 177 deletions(-) delete mode 100644 build.log delete mode 100644 full_output.txt delete mode 100644 lint_output.txt delete mode 100644 test_file.txt diff --git a/build.log b/build.log deleted file mode 100644 index 1f5016d8d..000000000 --- a/build.log +++ /dev/null @@ -1,114 +0,0 @@ - -> sable@1.14.0 build /Users/evie/git/Sable -> vite build - -vite v7.3.1 building client environment for production... -transforming... -✓ 8032 modules transformed. -rendering chunks... -computing gzip size... -[vite-plugin-static-copy] Copied 10 items. -dist/.assetsignore 0.02 kB -dist/assets/index-Ds5yF1gS.js.br 0.07 kB -dist/assets/index-Ds5yF1gS.js.map.br 0.41 kB -dist/wrangler.json.br 0.42 kB -dist/assets/cinny-logo-maskable-36x36-CT1Bq-jJ.png 0.79 kB -dist/index.html.br 0.88 kB -dist/assets/cinny-logo-maskable-DXG8PKa6.svg.br 0.96 kB -dist/wrangler.json 1.00 kB │ gzip: 0.54 kB -dist/assets/cinny-logo-maskable-48x48-DfxQ4FEO.png 1.08 kB -dist/assets/cinny-logo-maskable-57x57-B_a6RKlt.png 1.28 kB -dist/assets/cinny-logo-maskable-60x60-uAvO2kwU.png 1.35 kB -dist/assets/cinny-logo-maskable-72x72-ChMts4zW.png 1.59 kB -dist/assets/cinny-logo-maskable-96x96-DeladQJ2.png 2.08 kB -dist/assets/cinny-logo-maskable-114x114-BRz0LILn.png 2.45 kB -dist/assets/cinny-logo-maskable-DXG8PKa6.svg 2.56 kB │ gzip: 1.12 kB -dist/assets/cinny-logo-maskable-120x120-BBcwUWQZ.png 2.59 kB -dist/assets/cinny-logo-maskable-144x144-CitAVeb0.png 3.08 kB -dist/assets/cinny-logo-maskable-152x152-Di3nKfIW.png 3.26 kB -dist/assets/cinny-logo-maskable-167x167-Dk9KG9Yi.png 3.59 kB -dist/assets/cinny-logo-maskable-180x180-RAgvvHf4.png 3.79 kB -dist/assets/cinny-logo-maskable-192x192-BHxZuLYc.png 4.06 kB -dist/assets/favicon-CemZgig7.png 4.15 kB -dist/index.html 4.28 kB │ gzip: 1.17 kB -dist/assets/arborium-4uGfF3G6.js.br 4.54 kB -dist/assets/arborium-4uGfF3G6.js.map.br 4.98 kB -dist/assets/space-mono-vietnamese-700-italic-BwPKnf-l.woff 5.24 kB -dist/assets/space-mono-vietnamese-400-normal-B0PMp_xB.woff 5.41 kB -dist/assets/space-mono-vietnamese-700-normal-D-KrLuLr.woff 5.45 kB -dist/assets/cinny-logo-maskable-256x256-B_icl17M.png 5.58 kB -dist/assets/space-mono-vietnamese-400-italic-DvlTUS1j.woff 5.88 kB -dist/assets/space-mono-vietnamese-400-normal-BNOj0Qhp.woff2 7.27 kB -dist/assets/space-mono-vietnamese-700-normal-DWQgDHuA.woff2 7.33 kB -dist/assets/space-mono-vietnamese-700-italic-i2bR4MHS.woff2 7.39 kB -dist/assets/cinny-logo-maskable-384x384-DA-2uwBp.png 8.52 kB -dist/assets/space-mono-vietnamese-400-italic-CyQIvI4V.woff2 9.69 kB -dist/assets/notification-EtLMRd0T.ogg 11.30 kB -dist/assets/cinny-logo-maskable-512x512-dB91iLyU.png 11.87 kB -dist/assets/space-mono-latin-400-normal-_3DlpgIW.woff 12.31 kB -dist/assets/space-mono-latin-700-normal-D7A851RN.woff 12.42 kB -dist/assets/space-mono-latin-ext-700-normal-B_E7P90g.woff 12.48 kB -dist/assets/space-mono-latin-ext-400-normal-D4cJI_B-.woff 12.61 kB -dist/assets/space-mono-latin-ext-400-italic-DYA_DB_l.woff 12.89 kB -dist/assets/nunito-vietnamese-wght-normal-U01xdrZh.woff2 13.10 kB -dist/assets/space-mono-latin-ext-700-italic-CbHMtIk0.woff 13.14 kB -dist/assets/space-mono-latin-700-italic-B8C1HgwN.woff 13.65 kB -dist/assets/space-mono-latin-400-italic-zmx7Qf09.woff 13.82 kB -dist/assets/nunito-vietnamese-wght-italic-5K55R7rt.woff2 14.77 kB -dist/assets/space-mono-latin-ext-700-normal-B2s3bDs2.woff2 15.81 kB -dist/assets/space-mono-latin-ext-400-normal-DTLbW2xa.woff2 15.83 kB -dist/assets/space-mono-latin-400-normal-Rg4St2Dn.woff2 16.52 kB -dist/assets/space-mono-latin-700-normal-mWgeinG7.woff2 16.72 kB -dist/assets/space-mono-latin-ext-400-italic-x3PrlAeq.woff2 17.20 kB -dist/assets/space-mono-latin-ext-700-italic-CkCrmjWu.woff2 17.74 kB -dist/assets/space-mono-latin-400-italic-YylcN9Ay.woff2 18.30 kB -dist/assets/space-mono-latin-700-italic-vNvENeTh.woff2 18.64 kB -dist/assets/index-C5lozGWL.css.br 20.47 kB -dist/assets/nunito-cyrillic-wght-normal-CY6AOgYE.woff2 20.78 kB -dist/assets/nunito-cyrillic-wght-italic-AGUkry7S.woff2 22.90 kB -dist/assets/nunito-cyrillic-ext-wght-normal-D4X5GqEv.woff2 28.93 kB -dist/assets/nunito-cyrillic-ext-wght-italic-C7FdRbwB.woff2 31.51 kB -dist/assets/invite-DROg5x7-.ogg 32.67 kB -dist/assets/nunito-latin-ext-wght-normal-CXYtwYOx.woff2 35.59 kB -dist/assets/nunito-latin-ext-wght-italic-CmZo11nB.woff2 39.07 kB -dist/assets/nunito-latin-wght-normal-BzFMHfZw.woff2 39.13 kB -dist/assets/index-ByL9e3j1.js.br 39.36 kB -dist/assets/nunito-latin-wght-italic-ZB3Aladm.woff2 41.76 kB -dist/assets/pdf-DEJ3BJS6.js.br 130.24 kB -dist/assets/ringtone-4rwYiCEg.webm 139.95 kB -dist/assets/index-ByL9e3j1.js.map.br 140.69 kB -dist/assets/pdf-DEJ3BJS6.js.map.br 290.20 kB -dist/assets/index-BTNFNN8W.js.map.br 302.21 kB -dist/assets/Twemoji.Mozilla.v15.1.0-CM1RS90w.woff2 491.74 kB -dist/assets/index-BTNFNN8W.js.br 951.42 kB -dist/assets/matrix_sdk_crypto_wasm_bg-dMeGppz-.wasm.br 1,333.88 kB -dist/assets/Twemoji.Mozilla.v15.1.0-DHQZm25T.ttf 1,451.58 kB -dist/assets/matrix_sdk_crypto_wasm_bg-dMeGppz-.wasm 5,513.88 kB │ gzip: 1,831.16 kB -dist/assets/index-C5lozGWL.css 156.09 kB │ gzip: 25.73 kB -dist/assets/index-Ds5yF1gS.js 0.08 kB │ gzip: 0.09 kB │ map: 0.96 kB -dist/assets/arborium-4uGfF3G6.js 20.65 kB │ gzip: 5.16 kB │ map: 21.44 kB -dist/assets/index-ByL9e3j1.js 272.42 kB │ gzip: 47.99 kB │ map: 950.66 kB -dist/assets/pdf-DEJ3BJS6.js 755.04 kB │ gzip: 165.12 kB │ map: 1,505.59 kB -dist/assets/index-BTNFNN8W.js 6,603.34 kB │ gzip: 1,316.26 kB │ map: 1,618.30 kB - -(!) Some chunks are larger than 500 kB after minification. Consider: -- Using dynamic import() to code-split the application -- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks -- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit. - -PWA v1.2.0 -Building src/sw.ts service worker ("es" format)... -vite v7.3.1 building client environment for production... -transforming... -✓ 61 modules transformed. -rendering chunks... -computing gzip size... -dist/sw.mjs 37.52 kB │ gzip: 11.63 kB │ map: 232.66 kB - -PWA v1.2.0 -mode injectManifest -format: es -precache 9 entries (14223.46 KiB) -files generated - dist/sw.js - dist/sw.js.map diff --git a/full_output.txt b/full_output.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/lint_output.txt b/lint_output.txt deleted file mode 100644 index d0e6288a3..000000000 --- a/lint_output.txt +++ /dev/null @@ -1,62 +0,0 @@ - -> sable@1.14.0 lint /Users/evie/git/Sable -> eslint . - - -/Users/evie/git/Sable/src/app/components/url-preview/UrlPreviewCard.tsx - 36:5 warning Unexpected console statement no-console - 97:9 warning Unexpected console statement no-console - 104:11 warning Unexpected console statement no-console - -/Users/evie/git/Sable/src/app/features/room/RoomInput.tsx - 1678:19 warning Unexpected console statement no-console - -/Users/evie/git/Sable/src/app/features/settings/Persona/PerMessageProfileEditor.tsx - 47:3 warning Unexpected console statement no-console - -/Users/evie/git/Sable/src/app/pages/client/ClientNonUIFeatures.tsx - 833:9 warning Unexpected console statement no-console - -/Users/evie/git/Sable/src/app/plugins/call/CallEmbed.ts - 317:7 warning Unexpected console statement no-console - 423:11 warning Unexpected console statement no-console - -/Users/evie/git/Sable/src/app/utils/debugLogger.ts - 87:9 warning Unexpected console statement no-console - -/Users/evie/git/Sable/src/index.tsx - 54:9 warning Unexpected confirm no-alert - -/Users/evie/git/Sable/src/sw.ts - 110:9 warning Unexpected console statement no-console - 117:9 warning Unexpected console statement no-console - 182:5 warning Unexpected console statement no-console - 189:5 warning Unexpected console statement no-console - 222:5 warning Unexpected console statement no-console - 230:7 warning Unexpected console statement no-console - 276:7 warning Unexpected console statement no-console - 281:5 warning Unexpected console statement no-console - 412:11 warning Unexpected console statement no-console - 421:9 warning Unexpected console statement no-console - 448:5 warning Unexpected console statement no-console - 458:5 warning Unexpected console statement no-console - 872:7 warning Unexpected console statement no-console - 914:3 warning Unexpected console statement no-console - 920:3 warning Unexpected console statement no-console - 922:5 warning Unexpected console statement no-console - 927:3 warning Unexpected console statement no-console - 954:5 warning Unexpected console statement no-console - 979:3 warning Unexpected console statement no-console - 980:3 warning Unexpected console statement no-console - 1015:3 warning Unexpected console statement no-console - 1024:7 warning Unexpected console statement no-console - 1031:9 warning Unexpected console statement no-console - 1049:11 warning Unexpected console statement no-console - 1055:7 warning Unexpected console statement no-console - -/Users/evie/git/Sable/src/sw/pushNotification.ts - 48:5 warning Unexpected console statement no-console - 169:7 warning Unexpected console statement no-console - -✖ 37 problems (0 errors, 37 warnings) - diff --git a/test_file.txt b/test_file.txt deleted file mode 100644 index 9daeafb98..000000000 --- a/test_file.txt +++ /dev/null @@ -1 +0,0 @@ -test From 82bde318b88160c38912a45788942205d14770fe Mon Sep 17 00:00:00 2001 From: Evie Gauthier Date: Wed, 15 Apr 2026 12:02:12 -0400 Subject: [PATCH 5/7] fix(dev-tools): add error handling for prepareToEncrypt --- .../features/settings/developer-tools/DevelopTools.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/features/settings/developer-tools/DevelopTools.tsx b/src/app/features/settings/developer-tools/DevelopTools.tsx index e9ef1ee89..24445bdcc 100644 --- a/src/app/features/settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/settings/developer-tools/DevelopTools.tsx @@ -57,8 +57,14 @@ export function DeveloperTools({ requestBack, requestClose }: DeveloperToolsProp const rotated = results.filter((r) => r.status === 'fulfilled').length; // Proactively start session creation + key sharing with all devices - // (including bridge bots). fire-and-forget per room. - encryptedRooms.forEach((room) => crypto.prepareToEncrypt(room)); + // (including bridge bots). fire-and-forget per room, but surface failures. + encryptedRooms.forEach((room) => { + void Promise.resolve() + .then(() => crypto.prepareToEncrypt(room)) + .catch((error) => { + console.error('Failed to prepare room encryption', room.roomId, error); + }); + }); return { rotated, total: encryptedRooms.length }; }, [mx]) From 56de896f99de7c8e0c8f67eab8efaaa8ae47ce8c Mon Sep 17 00:00:00 2001 From: Evie Gauthier Date: Wed, 15 Apr 2026 18:18:03 -0400 Subject: [PATCH 6/7] chore: fix lint and format issues Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/app/features/settings/developer-tools/DevelopTools.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/features/settings/developer-tools/DevelopTools.tsx b/src/app/features/settings/developer-tools/DevelopTools.tsx index 24445bdcc..470ca95c5 100644 --- a/src/app/features/settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/settings/developer-tools/DevelopTools.tsx @@ -59,7 +59,7 @@ export function DeveloperTools({ requestBack, requestClose }: DeveloperToolsProp // Proactively start session creation + key sharing with all devices // (including bridge bots). fire-and-forget per room, but surface failures. encryptedRooms.forEach((room) => { - void Promise.resolve() + Promise.resolve() .then(() => crypto.prepareToEncrypt(room)) .catch((error) => { console.error('Failed to prepare room encryption', room.roomId, error); From ca65cef132629089189d4c4078df6f7e1ef76b3d Mon Sep 17 00:00:00 2001 From: Evie Gauthier Date: Wed, 15 Apr 2026 18:22:49 -0400 Subject: [PATCH 7/7] docs(changeset): clarify Megolm session rotation description Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .changeset/devtool-rotate-sessions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/devtool-rotate-sessions.md b/.changeset/devtool-rotate-sessions.md index cae1bda0c..686fb292f 100644 --- a/.changeset/devtool-rotate-sessions.md +++ b/.changeset/devtool-rotate-sessions.md @@ -2,4 +2,4 @@ default: patch --- -Add rotate-encryption-sessions developer tool to force Megolm session rotation for testing +Add developer tool to force-rotate outbound Megolm encryption sessions per room, useful for testing key rotation and bridge session recovery