Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
5b7e53a
feat(sync): hybrid snapshot + per-device delta cloud sync over GitHub…
Jun 27, 2026
25afb80
feat(groups): group-scoped pinned tabs
Jun 27, 2026
eb7ee70
feat(popup,manage): group-pin thumbtack badge + sync-apply UI resilience
Jun 27, 2026
5644dc9
test(sync): delta-sync test suite
Jun 27, 2026
9c018a0
build: exclude dev-only test files from the packaged add-on
Jun 27, 2026
4cb05ed
fix(sync): wire delta sync into the cloud-sync trigger
Jun 28, 2026
5622e01
feat(options): split cloud sync toggle from auto-sync interval
Jun 28, 2026
e05d8fc
Merge branch 'feat/cloud-sync-autosync-toggle': split cloud sync togg…
Jun 28, 2026
7c9ef2b
refactor(sync): make cloudSync delta-only; drop USE_DELTA_SYNC (#7)
Jun 28, 2026
d0a7ee4
feat(backup): explicit Cloud backup push/restore entry points
Jun 28, 2026
597c6e3
feat(backup): configurable pre-apply backup name and location
Jun 28, 2026
81bd55b
feat(options): split cloud settings into 3 blocks
Jun 28, 2026
f9b7552
i18n: messages for the 3 cloud blocks
Jun 28, 2026
082ebe8
Merge branch 'cloud-settings-three-blocks': 3-block cloud settings (g…
Jun 28, 2026
41483e9
feat(options): group cloud settings under one section; move pre-sync …
Jun 28, 2026
2215d44
Merge branch 'cloud-settings-ui-regroup': one Cloud section; pre-sync…
Jun 28, 2026
d50c572
refactor(sync): rename sync gist files to STG-sync-*
Jun 28, 2026
4bc9a0b
refactor(sync): seed first sync from local state; drop legacy backup …
Jun 28, 2026
e4d17dd
feat(backup): separate gist file for Cloud backup
Jun 28, 2026
70792f3
Merge branch 'cloud-gist-naming': STG-sync-* file names, drop legacy …
Jun 28, 2026
b5b8bce
feat(options): gist-name in access, editable cloud-backup filename, c…
Jun 28, 2026
6855784
Merge branch 'cloud-ui-gistname': gist-name field, editable cloud-bac…
Jun 28, 2026
985c305
feat(sync): identify gist by name (description) with id cache
Jun 28, 2026
eeee812
fix(options): persist syncBackupLocation
Jun 28, 2026
dce3908
fix(sync): make autoSyncEnable local-only
Jun 28, 2026
09b174e
refactor(options): fetch gist info once on the settings page
Jun 28, 2026
b28398d
fix(options): update settings deep-link anchor to regrouped ids
Jun 28, 2026
f1b68c0
Merge branch 'cloud-consolidate': gist identity by name + id cache, r…
Jun 28, 2026
a10b2ae
fix(options): guard gist-name validation against undefined
Jun 28, 2026
cfed33c
fix(options): unify Cloud sync section under one titled box
Jun 29, 2026
20ee0a6
feat(options): add fav-icons toggle to Cloud backup
Jun 29, 2026
50dda5a
fix(options): remove empty gap under gist-name help
Jun 29, 2026
ce0d0a7
Merge branch 'cloud-ui-fixes': unify Cloud sync section, cloud-backup…
Jun 29, 2026
c2d1211
fix(sync): drop data: favicons from the delta log (RAM blowup)
Jun 29, 2026
2bb8b1a
Merge branch 'fix/delta-favicon-bloat': drop data: favicons from delt…
Jun 29, 2026
e166111
fix(backup): reserve STG-sync- namespace for the cloud-backup filename
Jun 29, 2026
03ce74e
fix(backup): restore only revisions that contain the backup file
Jun 29, 2026
71e8631
refactor(sync): drop explanatory comments from gist-identity code
Jun 29, 2026
a836755
Merge branch 'fix/cloud-review-findings': reserve STG-sync- backup na…
Jun 29, 2026
bb9cbec
perf(sync): batch bootstrap delta-log appends into one write
Jun 29, 2026
60f19ca
Merge branch 'perf/delta-log-batch-append': batch bootstrap delta-log…
Jun 29, 2026
939fa90
fix(windows): guard against undefined groupToKeep in runGrandRestore
Jun 30, 2026
74cfaea
fix(windows): include pinned tabs in startup restore dedup to prevent…
Jun 30, 2026
21819bd
fix(logger): strip data: blobs and oversized strings from retained lo…
Jun 30, 2026
b5a21ef
fix(logger): cap in-memory log buffer on append to bound memory
Jun 30, 2026
191ed49
feat(sync): add IndexedDB store for the delta log
Jun 30, 2026
78336a7
fix(sync): persist delta log in IndexedDB to stop storage.local.onCha…
Jun 30, 2026
92cc4f5
test(sync): cover delta-log IndexedDB migration
Jun 30, 2026
f55782d
Merge branch 'fix/grand-restore-null-guard': guard undefined groupToK…
Jun 30, 2026
860cd5a
Merge branch 'fix/pinned-tab-restore-dedup': include pinned tabs in s…
Jun 30, 2026
b54d1bf
Merge branch 'fix/logger-memory': strip data: blobs and cap the in-me…
Jun 30, 2026
ee41957
Merge branch 'fix/delta-log-indexeddb': persist delta log in IndexedD…
Jun 30, 2026
c4b52d0
feat(groups): warn with offending tabs and allow switching despite mi…
Jun 30, 2026
2bc5f4f
fix(groups): don't re-pin moved group-pinned tabs into a non-displaye…
Jun 30, 2026
c930320
feat(groups): offer Pin to group on tabs without a group
Jun 30, 2026
a0c817b
Merge branch 'feat/sharing-block-override': warn with offending tabs …
Jun 30, 2026
962c6b8
Merge branch 'fix/move-group-pinned-both-groups': don't re-pin moved …
Jun 30, 2026
c8c50b3
Merge branch 'feat/pin-to-group-all-tabs': offer Pin to current group…
Jun 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 107 additions & 13 deletions addon/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,14 @@
"description": "Exclude tabs with sound"
},
"notPossibleSwitchGroupBecauseSomeTabShareMicrophoneOrCamera": {
"message": "It is not possible to change the group because one of the opened tabs share microphone or camera",
"description": "It is not possible to change the group because one of the opened tabs share microphone or camera"
"message": "These tabs are sharing microphone, camera or screen and will keep doing so: \"$titles$\". Click here to switch anyway.",
"description": "Warning shown when switching a group would hide tabs that share microphone, camera or screen. Lists the tabs and lets the user switch anyway by clicking.",
"placeholders": {
"titles": {
"content": "$1",
"example": "some titles"
}
}
},
"foundHiddenUnSyncTabsDescription": {
"message": "Found hidden unsynchronized tabs. Click on tab to show it into current group/window or:",
Expand Down Expand Up @@ -759,6 +765,18 @@
"message": "Discard tab",
"description": "Discard tab"
},
"pinTabInGroupTitle": {
"message": "Pin to group",
"description": "Pin this tab within its group (pinned only while the group is active)"
},
"pinTabInCurrentGroupTitle": {
"message": "Pin to current group",
"description": "Pin a tab that is not yet in a group into the window's active group (pinned only while that group is active)"
},
"unpinTabInGroupTitle": {
"message": "Unpin from group",
"description": "Remove the group-scoped pin from this tab"
},
"folderNameTitle": {
"message": "Folder name",
"description": "Folder name title"
Expand Down Expand Up @@ -1381,21 +1399,85 @@
"message": "Start synchronization",
"description": "Start synchronization"
},
"syncStartTrustLocal": {
"message": "Start synchronization and trust local data",
"description": "Start synchronization and trust local data"
"cloudSettingsTitle": {
"message": "Cloud",
"description": "Title of the section grouping the cloud access, sync and backup settings blocks"
},
"githubGistAccessTitle": {
"message": "GitHub Gist access",
"description": "Title of the GitHub Gist access settings block (token, file, storage location)"
},
"githubGistAccessLocation": {
"message": "Store cloud settings in",
"description": "Label for the selector choosing where the roaming sync option bag is stored (Firefox Sync or local profile)"
},
"githubGistNameTitle": {
"message": "Gist name",
"description": "Label for the gist name (the gist description) used to find or create the cloud gist"
},
"githubGistNameHelp": {
"message": "Names the gist used for syncing. The same name on another device connects to the same gist.",
"description": "Help text under the gist name field in the GitHub Gist access block"
},
"githubGistNameChangeWarning": {
"message": "Changing the gist name makes __MSG_extensionName__ forget the current gist: it stays on GitHub but is no longer synced. Synchronization restarts from this device's current state.",
"description": "Warning shown when the user changes the gist name to a different value"
},
"githubGistBackupFileNameTitle": {
"message": "Backup file name",
"description": "Label for the cloud backup file name field"
},
"syncStartTrustCloud": {
"message": "Start synchronization and trust cloud data",
"description": "Start synchronization and trust cloud data"
"githubGistBackupFileNameChangeWarning": {
"message": "Changing the backup file name makes __MSG_extensionName__ forget the previous backups: they stay on GitHub but are no longer listed or restored.",
"description": "Warning shown when the user changes the cloud backup file name"
},
"syncDataInCloudCanBeDifferent": {
"message": "The data in the cloud can be very different from the current state.",
"description": "The data in the cloud can be very different from the current state."
"githubGistSyncTitle": {
"message": "Cloud sync",
"description": "Title of the cloud sync settings block"
},
"githubGistBackupTitle": {
"message": "Cloud backup",
"description": "Title of the cloud backup settings block"
},
"createBackupButton": {
"message": "Create backup",
"description": "Button that pushes the current full state to the cloud as a new gist revision"
},
"resetSyncStateButton": {
"message": "Reset sync state",
"description": "Reset this device's local sync state (recovery action)"
},
"resetSyncStateConfirm": {
"message": "This clears the local synchronization state for this device only (baseline and change log). The data in the cloud is NOT touched. The next synchronization will behave like a first sync: nothing is removed and your current tabs are re-uploaded.",
"description": "Confirmation text for the reset sync state action"
},
"syncEnableTitle": {
"message": "Enable auto backup to the cloud",
"description": "Enable auto backup to the cloud"
"message": "Enable sync to the cloud",
"description": "Enable sync to the cloud"
},
"autoSyncEnableTitle": {
"message": "Enable auto sync to the cloud",
"description": "Enable auto sync to the cloud"
},
"cloudSyncEveryTitle": {
"message": "Cloud sync every",
"description": "Cloud sync every"
},
"syncBackupBeforeApply": {
"message": "Create a backup before applying sync changes (recommended)",
"description": "Toggle: take a local STG backup before delta-sync applies any change, so a bad sync can be rolled back"
},
"syncSleepNewTabs": {
"message": "Create new synced tabs asleep (recommended)",
"description": "Toggle: tabs created by sync show title+favicon and only load when activated"
},
"syncSleepPinnedTabs": {
"message": "Sleep synced pinned tabs (Firefox loads pinned tabs by default)",
"description": "Toggle: also create synced pinned tabs asleep via create-then-discard; off by default since pinned tabs normally load"
},
"syncActivatePreviouslyActiveTabs": {
"message": "Activate tabs that were active on the other machine",
"description": "Sub-toggle: load a synced tab if it was active (loaded) on the source machine"
},
"syncSettingsLocation": {
"message": "Sync settings location",
Expand Down Expand Up @@ -1435,6 +1517,18 @@
"message": "GitHub Gist backup has incorrect data",
"description": "GitHub Gist backup has incorrect data"
},
"githubGistFileNotInRevision": {
"message": "The backup file is not present in this revision.",
"description": "The selected gist revision does not contain the cloud backup file"
},
"githubGistBackupFileNameInvalid": {
"message": "Enter a file name ending in .json that does not start with «STG-sync-» (that prefix is reserved for cloud sync).",
"description": "Cloud backup file name is empty, not .json, or uses the reserved STG-sync- prefix"
},
"githubBackupFileNameReserved": {
"message": "The cloud backup file name must not start with «STG-sync-»; that prefix is reserved for cloud sync files.",
"description": "Backup push refused because the file name collides with the reserved sync namespace"
},
"githubInvalidToken": {
"message": "Your GitHub token is invalid",
"description": "Your GitHub token is invalid"
Expand Down
88 changes: 75 additions & 13 deletions addon/src/_locales/ru/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,14 @@
"description": "Exclude tabs with sound"
},
"notPossibleSwitchGroupBecauseSomeTabShareMicrophoneOrCamera": {
"message": "Невозможно изменить группу, потому что на одной из вкладок используется микрофон или камера",
"description": "It is not possible to change the group because one of the opened tabs share microphone or camera"
"message": "Эти вкладки используют микрофон, камеру или доступ к экрану и продолжат это делать: «$titles$». Нажмите здесь, чтобы переключиться всё равно.",
"description": "Warning shown when switching a group would hide tabs that share microphone, camera or screen. Lists the tabs and lets the user switch anyway by clicking.",
"placeholders": {
"titles": {
"content": "$1",
"example": "some titles"
}
}
},
"foundHiddenUnSyncTabsDescription": {
"message": "Найдены скрытые не синхронизированные вкладки. Нажмите на вкладку, чтобы отобразить ее в текущей группе/окне или:",
Expand Down Expand Up @@ -747,6 +753,10 @@
"message": "Выгрузить вкладку из памяти",
"description": "Discard tab"
},
"pinTabInCurrentGroupTitle": {
"message": "Закрепить в текущей группе",
"description": "Pin a tab that is not yet in a group into the window's active group (pinned only while that group is active)"
},
"folderNameTitle": {
"message": "Имя папки",
"description": "Folder name title"
Expand Down Expand Up @@ -1369,21 +1379,61 @@
"message": "Синхронизировать",
"description": "Start synchronization"
},
"syncStartTrustLocal": {
"message": "Синхронизировать и доверять локальным данным",
"description": "Start synchronization and trust local data"
"cloudSettingsTitle": {
"message": "Облако",
"description": "Title of the section grouping the cloud access, sync and backup settings blocks"
},
"githubGistAccessTitle": {
"message": "Доступ к GitHub Gist",
"description": "Title of the GitHub Gist access settings block (token, file, storage location)"
},
"githubGistAccessLocation": {
"message": "Хранить настройки облака в",
"description": "Label for the selector choosing where the roaming sync option bag is stored (Firefox Sync or local profile)"
},
"githubGistNameTitle": {
"message": "Имя Gist",
"description": "Label for the gist name (the gist description) used to find or create the cloud gist"
},
"githubGistNameHelp": {
"message": "Задаёт Gist, используемый для синхронизации. То же имя на другом устройстве подключается к тому же Gist.",
"description": "Help text under the gist name field in the GitHub Gist access block"
},
"syncStartTrustCloud": {
"message": "Синхронизировать и доверьтесь облачным данным",
"description": "Start synchronization and trust cloud data"
"githubGistNameChangeWarning": {
"message": "Изменение имени Gist приведёт к тому, что __MSG_extensionName__ забудет текущий Gist: он останется на GitHub, но больше не будет синхронизироваться. Синхронизация начнётся заново из текущего состояния этого устройства.",
"description": "Warning shown when the user changes the gist name to a different value"
},
"syncDataInCloudCanBeDifferent": {
"message": "Данные в облаке могут сильно отличаться от текущего состояния.",
"description": "The data in the cloud can be very different from the current state."
"githubGistBackupFileNameTitle": {
"message": "Имя файла резервной копии",
"description": "Label for the cloud backup file name field"
},
"githubGistBackupFileNameChangeWarning": {
"message": "Изменение имени файла резервной копии приведёт к тому, что __MSG_extensionName__ забудет предыдущие резервные копии: они останутся на GitHub, но больше не будут отображаться и восстанавливаться.",
"description": "Warning shown when the user changes the cloud backup file name"
},
"githubGistSyncTitle": {
"message": "Облачная синхронизация",
"description": "Title of the cloud sync settings block"
},
"githubGistBackupTitle": {
"message": "Облачная резервная копия",
"description": "Title of the cloud backup settings block"
},
"createBackupButton": {
"message": "Создать резервную копию",
"description": "Button that pushes the current full state to the cloud as a new gist revision"
},
"syncEnableTitle": {
"message": "Включить автоматическое резервное копирование в облако",
"description": "Enable auto backup to the cloud"
"message": "Включить синхронизацию с облаком",
"description": "Enable sync to the cloud"
},
"autoSyncEnableTitle": {
"message": "Включить автоматическую синхронизацию с облаком",
"description": "Enable auto sync to the cloud"
},
"cloudSyncEveryTitle": {
"message": "Синхронизировать с облаком каждые",
"description": "Cloud sync every"
},
"syncSettingsLocation": {
"message": "Расположение настроек синхронизации",
Expand Down Expand Up @@ -1423,6 +1473,18 @@
"message": "Резервная копия GitHub Gist содержит неверные данные",
"description": "GitHub Gist backup has incorrect data"
},
"githubGistFileNotInRevision": {
"message": "В этой ревизии нет файла резервной копии.",
"description": "The selected gist revision does not contain the cloud backup file"
},
"githubGistBackupFileNameInvalid": {
"message": "Укажите имя файла, оканчивающееся на .json и не начинающееся с «STG-sync-» (этот префикс зарезервирован для облачной синхронизации).",
"description": "Cloud backup file name is empty, not .json, or uses the reserved STG-sync- prefix"
},
"githubBackupFileNameReserved": {
"message": "Имя файла облачной резервной копии не должно начинаться с «STG-sync-»; этот префикс зарезервирован для файлов облачной синхронизации.",
"description": "Backup push refused because the file name collides with the reserved sync namespace"
},
"githubInvalidToken": {
"message": "Ваш токен GitHub недействителен",
"description": "Your GitHub token is invalid"
Expand Down
Loading