Skip to content

Sync global placeholders, brand profiles and language with guides - #187

Merged
Twest2 merged 5 commits into
mainfrom
feat/sync-shared-settings
Oct 29, 2026
Merged

Twest2 merged 5 commits into
mainfrom
feat/sync-shared-settings

Conversation

@Twest2

@Twest2 Twest2 commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Why

Cloud sync only ever uploaded guides. Global placeholders and brand profiles stayed on each computer, so a guide using [[Company]] or a brand profile exported differently on every computer. It showed raw [[Company]] text, unbranded output, or quality-check warnings on a computer missing the values.

What syncs now

On by default whenever guide sync is on, with no separate toggle:

  • Global placeholders
  • Brand profiles, with the logos, banners, fonts and PNG drawings they use, and which profile is active
  • Language (settings.language). Nothing on main sets it yet, so in practice this starts with the translations branch (see below).

Other capture options, AI, storage and backups stay per computer.

How

  • Format. One settings-v1 archive per version, versioned exactly like a guide: immutable versions, parent/merged properties, heads, and pruning to the current version plus two before it (one on Free up space). It's a plain zip rather than parts, so old StepForge versions running part cleanup can't delete anything it depends on.
  • Merging (core/shared-settings.js) is three-way by key, like guide merge:
    • Different placeholders or profiles changed on different computers all survive.
    • When the same one changed on both, the newest wins. Profiles compare by updatedAt.
    • An edit beats a deletion.
    • Without a base, nothing counts as deleted.
  • Defaults never win. Settings at their default aren't stored, so a new computer's defaults can't override another computer's choice.
  • Settings dialog. Incoming settings wait while the Settings dialog is open, so saving it can't undo them. Closing it triggers a sync. A window reload clears the flag.
  • Downloads are untrusted. The hash is checked, each image and font is re-added through BrandingStore.addAsset (SVGs sanitized again; I checked that the sanitizer is idempotent, so this can't loop), and unknown entries are refused with "synced by a newer StepForge" so an older version can't merge them away.
  • Applying is quiet. Profiles are written with their own timestamps (BrandingStore.replaceProfiles), so a synced profile doesn't come back as a new edit, and unchanged files aren't rewritten.
  • Replace Drive with this computer replaces settings too.
  • Listings. listSettings() was added to Google Drive and to folder storage (OneDrive, Dropbox, WebDAV).

Notes

Tests

npm test: 1029 pass. New tests/unit/shared-settings.test.js covers:

  • everything reaching a second computer (including an SVG's PNG drawing), with no re-uploads once both agree
  • edits to different placeholders and profiles combining, and deletions propagating
  • the newest edit winning a conflict
  • a new computer's defaults not winning
  • waiting while Settings is open
  • "newer StepForge" and hash-mismatch refusals
  • pruning and Replace cloud with local
  • merges coming out the same on either computer
  • archive round-trips

Writing these caught a bug before commit: a computer with no sync history was using the cloud version as its merge base, so its empty settings would have deleted everyone's.

Recording shortcuts

Capture and Pause/resume shortcuts from Settings → Capture → Hotkeys now sync too. Each binding has its own edit clock, so edits to different shortcuts combine and unrelated capture changes do not promote an older binding. Cleared bindings and explicit resets to defaults sync; untouched defaults on a new computer do not override existing choices. Incoming shortcuts re-register immediately in the running app. Other capture options stay local.

Validation for this addition: npm test — 1,046 passed, 20 skipped, zero failures. Five new regression cases fail on the prior implementation and pass with the change; repository structure and whitespace checks pass.

@Twest2
Twest2 merged commit 785ef5c into main Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant