Skip to content

1.0.0-beta.180

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 29 Jun 14:07
b7f6d2a

WowSync

1.0.0-beta.180 (2026-06-29)

Full Changelog Previous Releases

  • docs: update warning message in README to reflect beta status and usage caution
  • chore(release): automate CF/Wago publishing
    Add a tag-triggered GitHub Actions workflow with BigWigs packager.
    Publishes tagged builds to CurseForge and Wago from the WowSync repo.
    Add X-Curse-Project-ID and X-Wago-ID to WowSync.toc for routing.
    Supports annotated 1.0.0-beta.X release tags.
  • docs: update screenshot for WowSync window in README
  • perf(hash): avoid per-leaf concat allocations
    Replace the leaf serializer's type:value string concatenation with
    three direct part pushes (type, colon, value text).
    This preserves the canonical serialized output and resulting hashes
    while reducing intermediate string allocations during fingerprinting.
  • fix(snapshots): diff other heads vs live setup
    Previewing another character's head wrongly compared against that
    profile's latest saved snapshot, returning nil and showing nothing when
    the character had no snapshot yet.
    Route a non-current head through PreviewApplyHeadByCharKey so it diffs
    that character's stored setup against the logged-in character's live
    state. The own head keeps its unsaved-changes-vs-latest behaviour.
  • docs(screenshots): refresh UI screenshots
    Update the Imports and Profiles screenshots to reflect the aligned
    action buttons and add a new MainFrame capture for the README.
    Keeps the documented UI in sync with the current layout.
  • docs: overhaul readme and refresh screenshots
    README now describes the current data model, where profiles are
    timelines and snapshots hold the captured module data shown in Current
    and history, and explains export/import sharing and PvP Talents support.
    The main window screenshot is renamed to reflect the profiles view and a
    new imports screenshot is added so the visuals match today's UI.
  • refactor(core): group runtime features together
    Load-time behavior stays the same, but profile, snapshot, import, and
    development capabilities are now treated as one feature area.
    This clarifies the addon architecture so future work can evolve feature
    logic without mixing it with infrastructure concerns.
  • fix(toc): update notes for clarity on profile sync functionality
  • fix(snapshot): sync head preview to unsaved badge
    Change SnapshotView:Preview for head handles to preview against the
    latest saved snapshot instead of the stored head state.
    This makes the Current row preview show unsaved deltas that match the
    unsaved-changes badge, avoiding contradictory UI signals.
  • feat(snapshot-view): add selector accessor
    Add SnapshotView:GetSelector(handle) to return hash#index for saved
    snapshots and nil for character heads.
    This gives UI export code a stable way to reference saved snapshots
    without reading raw snapshot internals.
  • feat(imports): add snapshot share import/export
    Add the import/export core for shared snapshot strings in WowSync.
    Create class-locked import containers with lookup, rename/delete,
    note updates, and duplicate warnings for imported snapshots.
    Add manager APIs to encode/decode, import, preview, and apply imports.
    Wire /ws export and /ws import to open the UI share dialog with
    localized help text, and initialize import DB defaults and load order.
  • feat(actionbars): show icons for all action types
    Resolve preview icons for macros, equipment sets, battle pets,
    and flyouts alongside spells and items. When a texture cannot be
    resolved on the current character, use the empty-slot icon instead
    of a blank entry.
    This keeps ActionBars diff rows visually consistent and makes changed
    slots easier to identify at a glance, even when the referenced action
    is not available locally.
  • refactor: split core and Infrastructure code
    Startup layering now treats Core as foundational library code and
    loads Infrastructure afterward. This aligns load order with the
    refactor boundary so shared primitives are initialized before
    infrastructure services and registries are attached.
    Keeping the runtime bootstrap aligned with the architecture makes
    future moves between layers safer and reduces accidental dependency
    cycles during addon startup.
  • feat(diff): add one-line preview descriptions
    Snapshot diff rows now include one-line context beneath each item
    label, so users can understand what a change represents before
    applying a sync. Add-on entries show addon notes, keybinding entries
    show assigned keys, macro entries show the first meaningful macro
    line, and settings entries show curated CVar descriptions.
    The tracked CVar catalog is now defined as dedicated settings data
    instead of living in branding constants. This keeps constants focused
    on user-facing tunables and makes settings metadata easier to
    maintain, with description text aligned to official wording.
  • feat(snapshot): add module default icons
    Modules can now declare a default icon in Config so diff entries
    without their own icon still render with a recognizable module
    identity. This keeps preview output easier to scan while preserving
    existing per-entry icons where modules already provide them.
    The module contract now documents this capability, and snapshot access
    now exposes module defaults for consumers that render previews.
  • refactor: reorder variables
  • feat(undo): add core preview for rollback
    Expose a read-only undo preview that returns the diff between the
    current setup and the most recent rollback snapshot.
    This gives UI flows a single source for showing pending undo changes
    before the user confirms restoration.
  • feat(combat): gate snapshot actions in combat
    Snapshot save, apply, undo, and delete commands now no-op during combat
    lockdown and report a clear combat message instead of attempting the
    action. This centralizes combat protection in the snapshot flow so
    module behavior stays consistent and protected APIs are never touched
    while locked.
  • feat(pvp): add dedicated talent sync module
    Add a new PvpTalents module that captures active-spec PvP slots,
    applies valid selections per slot, and emits icon-aware diff entries.
    Remove PvP talent handling from Talents and wire module loading and
    locale text so preview and apply reflect actual PvP talent changes.
  • feat(talents): show spec icon in diff preview
    Include each flattened loadout's spec ID and resolve entry icons with
    GetSpecializationInfoByID during talent diff generation.
    This binds preview icons to the loadout specialization instead of
    the player's current specialization state.
  • feat(core): add icon-aware diff preview entries
    Diff results now carry preview entries with a label and optional icon
    instead of label-only strings, so callers can render richer change lists
    without recomputing metadata per module.
    Action bar and macro diffs now provide native textures, while modules
    without icons continue to emit label-only entries.
    This keeps existing count-based consumers unchanged and updates the
    module contract to match what the preview UI expects.
  • fix(screenshots): update MainFrame.png to reflect recent UI changes
  • fix(actionbars): clarify unnamed macro fallback
    Change the ActionBars macro fallback label from "Macro " to
    "Unnamed macro".
    Dynamic #showtooltip macros can expose a shown spell or item id,
    not a macro index. Rendering "Macro 783" implied an index that
    might not exist, which was misleading during debug and diff review.
  • fix(ModuleInterface): clarify ApplyPriority behavior in documentation
  • fix(snapshots): apply modules in a deterministic priority order
    Macros and Talents now apply before ActionBars and Keybindings so the
    macros/spells they reference exist before being placed, preventing silent
    loss of macro buttons on cross-character or exact applies. Modules declare
    Config.ApplyPriority; SnapshotManager iterates them via
    ModuleRegistry:IterableModulesByPriority.
  • fix(actionbars): capture macro names from the action slot
    GetActionInfo's id is the shown spell/item for dynamic #showtooltip
    macros, not the macro index, so GetMacroInfo couldn't name them and
    exact-mode apply cleared them without re-placing. Read the name via
    C_ActionBar.GetActionText instead, and skip placement when no name
    was captured.
  • fix(chat): restore message groups and channels via chat frame methods
    The ChatFrame_* globals used to restore a tab's message groups and
    channels were removed in retail; use the ChatFrameMixin methods.
  • feat(commands): label unpackaged builds as Prerelease
    Show "Prerelease" in /ws status when the addon version metadata is the
    unsubstituted @Project-Version@ token, instead of leaking the raw token.
  • feat(commands): group /ws status output under prefixed headers
    Add an unprefixed PrintLine and use it for /ws status detail lines so
    the addon name prefixes only each section header, not every line.
  • docs(readme): sync slash command docs
    Update the Slash Commands table to document /ws status and /ws debug
    using the same descriptions shown by /ws help.
    Add a diagnostic note for /ws debug that explains what it records,
    why it is useful for bug reports, and how to collect the saved log.
  • feat(commands): add /ws status subcommand
    Add /ws status with optional addon, profile, watcher, and debug groups.
    With no argument, the command prints all groups in sequence.
    Add localized status strings and a help entry so users can discover the
    command and inspect current runtime state quickly.
  • feat(debug): add opt-in debug event recorder
    Add a Debugger service, expose it via WowSync:GetDebugger(), and
    persist debug events in WowSyncDebugDB.
    Add /ws debug on|off|status plus localized strings, and trace command
    and UI actions so related operations keep a consistent source tag.
    Record save, apply, and undo flows with game context, character info,
    and per-module before/after state snapshots.
    Introduce module debug hooks (GetDebugState and RenderDebugPayload)
    and implement live-state coverage across core modules, including
    ActionBars payload rendering that aligns with live slot state.
    Guard SnapshotManager and command debug calls behind IsEnabled() to
    avoid building temporary debug payload tables when logging is off.
  • fix: improve snapshot apply and undo behavior
    Fix snapshot apply edge cases across action bars, chat, combat log,
    and talent loadouts to prevent partial restores and runtime errors.
    Undo now clears missing action bar slots in exact mode so restored bars
    match the rollback snapshot instead of merging onto current slots.
    Chat apply now ignores invalid zero font sizes to avoid a SetFont error
    that could stop the rest of chat settings from applying.
    Talent capture now deduplicates repeated loadout names, and apply now
    skips names that already exist to avoid import name collisions.
    Combat log apply mode is now marked exact to match its full replace
    behavior, and docs now note the talent undo limitation.
  • fix: drop Edit Mode and chat geometry sync
    Remove Edit Mode snapshot support from the addon.
    Applying Edit Mode layouts can taint secure UI paths.
    This keeps apply and undo in safe, supported areas.
    Chat snapshots now sync tabs, channels, colors, and docking.
    Position and size are no longer captured or applied.
  • refactor: reorganize addon framework file layout
    Move framework and entrypoint sources into clearer ownership groups.
    Update the addon manifest ordering to match the new structure.
    Keep runtime behavior unchanged while improving project readability.
  • refactor(hash): extract key comparison function for sorting
  • refactor(wowsync): clarify snapshot naming
    Rename ambiguous locals, parameters, and comments across core,
    profiles, runtime, snapshots, and module implementations to match
    the post-refactor model.
    Standardize terms such as capturedData, sourceMetadata,
    applyResult, undoPoint, and rollbackSnapshot, and replace stale
    "profile"/"safety snapshot" wording where operations now target
    snapshots and rollback points.
    No behavior changes are intended; this improves readability,
    reduces confusion when tracing apply and undo flows, and keeps
    module contracts consistent across callers.
  • refactor(snapshot): rename SnapshotManager API methods
    Rename SnapshotManager public methods to clearer, more specific names
    for apply, save, preview, current-state, and undo operations.
    Update all runtime consumers and snapshot view/cache call sites to use
    the new method names, and align interface/result comments with the
    renamed API surface.
    This keeps behavior unchanged while making intent clearer and reducing
    ambiguity in command and UI integrations.
  • refactor(runtime): split profile snapshot services
    Separate snapshot, apply, and undo orchestration from profile
    record access.
    Keep profile reads, deletes, and reset in a small facade and move
    snapshot workflows into a dedicated manager.
    Add a character manager for roster and token resolution, plus a save
    runner that slices work across frames while bracketing watcher flushes.
    Rewire module registration, commands, API accessors, and snapshot
    views to the new ownership boundaries and updated load order.
    Behavior is preserved, but responsibilities are now clearer and easier
    to maintain.
  • refactor(runtime): slice saves and isolate flushes
    Replace timer-deferred saves with a shared FrameTask coroutine runner.
    Save capture and fingerprint work now execute across frames with a
    bounded per-frame budget.
    Coordinate recapture with save/apply flows so Current stays stable:
    • suspend flushes while a save reads Current
    • flush accumulated dirty modules when the save completes
    • drain any in-flight save before apply, undo, and logout
    • recompress Current after logout drain so persisted data stays encoded
      Rename watcher/current-store APIs for clearer intent and update the
      watcher command and TOC load order to include FrameTask.
      Add cooperative yield points to Current capture and hash fingerprinting
      to reduce large-save frame hitches for coroutine-driven saves.
  • feat(save): defer saves and optimize snapshots
    Defer save work to the next frame so consumers can show save progress
    before capture and compression run.
    Return explicit save outcomes for in-flight and failed requests so
    users get clear feedback instead of silent failures.
    Reduce save overhead by avoiding an extra deep copy when compressed
    snapshot data is available, while preserving a safe fallback copy when
    compression is unavailable.
  • feat(commands): resolve character shorthand tokens
    Add ProfileManager.ResolveCharacter to map typed character tokens to
    stored profile keys using current-realm, other-realm, and realm-prefix
    matching.
    Route apply, delete, and list through a shared resolver helper so
    ambiguous and missing character tokens print clear feedback with
    candidate keys.
    Remove the unreachable delete not-found branch after resolution and
    guard list against nil Snapshots so it treats missing history as empty.
    Add locale strings for character ambiguity, not-found feedback, and
    single-column candidate output.
  • docs(commands): align slash help with README
    Update slash command wording in runtime help output, locale usage
    strings, and README so all command descriptions match.
    Normalize command argument tokens to use name-based selectors and add
    a /ws help entry to the printed command list for completeness.
  • docs(README): improve command descriptions for clarity and consistency
  • docs(README): clarify terminology of the word "setup"
  • feat(watcher): add on-demand lazy tracking
    Replace the watcher toggle with explicit off|lazy modes and make lazy
    the persisted default. In lazy mode, tracking runs only while a
    consumer is attached and stops after the last attachment detaches.
    Expose WowSync:Attach, WowSync:Detach, and WowSync:HasAttachments so
    consumers can request live tracking without coupling core logic to a
    specific companion addon. Refresh Current when tracking starts so it
    catches up changes made while tracking was idle.
    Update slash command handling, help text, locale strings, and README
    to reflect the new off|lazy behavior and on-demand tracking model.
  • feat(commands): update save command to include optional note and add reset database command
  • chore(pkgmeta): add Screenshots to ignore list
  • refactor(ui): centralize reset popup dialog
    Move WOWSYNC_RESET_DB registration out of Commands and into
    the shared popup-dialog module so dialog definitions stay centralized.
    Import ProfileManager in the shared dialogs module and keep the reset
    behavior unchanged, including database wipe and UI reload.
    This reduces command-module wiring noise and keeps all StaticPopup
    registrations in one place.
  • refactor(wowsync): move module runtime objects
    Move ModuleInterface and ModuleRegistry from Modules/ to Runtime/ and
    update the toc entries to load them from their new paths.
    Resolve ProfileStore and ProfileManager at file scope in SnapshotView
    and SnapshotHandleCache instead of assigning them in OnInitialized, and
    align local names with existing object-import style.
    This keeps behavior the same while simplifying object wiring and keeping
    runtime-facing objects grouped under Runtime.
  • refactor(wowsync): extract SnapshotHandleCache
    Split SnapshotView's two API shapes into separate objects. The methods
    that take a charKey and produce handles (head, latest saved, pending
    eviction, full timeline) move to a new SnapshotHandleCache; SnapshotView
    keeps only the handle accessors, mutators, and operations.
    The two objects are siblings with no dependency between them: the cache
    produces handles, SnapshotView interprets them, and the handle is the
    shared contract. SnapshotHandleCache owns the handle identity caches;
    the raw-snapshot wrap stays a private local so the only public entry
    points are keyed by character.
    Also cache GetCharacterInfo's DTO per handle, weak-keyed so an entry is
    collected with the handle it describes, avoiding a fresh table on every
    render-path lookup.
    Expose the new object through WowSync:GetSnapshotHandleCache and
    register it in the toc.
  • feat(wowsync): redesign snapshot storage api
    Store addon data in a flat WowSyncDB shape with one record per
    character, so current state, undo history, and saved snapshots now
    travel together and are managed consistently across runtime systems.
    Compress captured snapshot payloads while keeping module names available
    for lightweight listing and comparisons, which reduces saved-variable
    size without removing snapshot usability.
    Expose a dedicated snapshot view API for handle-based access so the UI
    can read and mutate snapshots without depending on storage fields
    directly.
  • chore(wowsync): split core and UI library loading
    Stop loading AceDB and CallbackHandler from the core addon and move
    those dependencies into the companion UI package where they are used.
    This keeps the core runtime focused on its own code path, prevents
    duplicate library ownership, and preserves startup ordering for the new
    core storage and snapshot view bootstrap sequence.
  • fix(wowsync): keep command syntax non-localized
    The slash help and usage output now separates literal command syntax
    from translatable descriptions. Command tokens like /ws save,
    --merge, and on|off stay fixed in code while locale entries only
    translate reader-facing text.
    This prevents translators from accidentally changing typed command
    verbs, keeps macros and guides portable across locales, and still
    allows full localization of command feedback messaging.
  • feat(commands): add database reset command
    Add /ws reset database and /ws reset db to clear WowSync data after
    an explicit confirmation prompt, so accidental command entry does not
    silently destroy saved history.
    The reset keeps user settings intact while removing profile snapshots,
    current captures, and undo history, then reloads the UI so every view
    restarts from a clean database state.
  • feat(core): unify character snapshot handling
    WowSync now treats each character as a single timeline with a derived
    Current head and a saved snapshot history that can be addressed
    unambiguously. Applying and deleting now accept hash#index selectors.
    Ambiguity errors now point players to exact selectors to avoid mistakes.
    Saving no longer silently no-ops when content matches the latest
    snapshot. Every save now records a snapshot, while pruning still
    respects pins and index ordering so pinned entries stay protected and
    selection remains stable.
    The docs now describe the updated window behavior, including the always-
    visible Current entry, pinned ordering, window lock/reset controls, and
    the latest UI screenshot so users understand the new flow quickly.
  • fix(chat): guard color capture nil-info crash
    Wrap chat color lookup in a safe helper during Chat module capture.
    Skip unsupported message types that trigger Blizzard nil-index errors.
    Prevent repeated capture failures so chat snapshots still save normally.
  • style(wowsync): normalize file header ordering
    Reorder top-of-file locals to keep each object declaration adjacent to
    its addon:GetObject dependencies.
    Move addon aliases and library bindings into a separate block after the
    object/dependency block, with local L grouped first where present.
    This makes dependency ownership easier to scan while preserving runtime
    behavior.
  • refactor(wowsync): centralize addon print helper
    Move the chat-print implementation to addon:Print in Main.lua so message
    formatting lives with addon initialization.
    Expose WowSync.Print as a public alias to preserve call sites while
    removing the duplicate method body and the local Colorizer binding.
    This keeps runtime API behavior unchanged and simplifies ownership of
    output formatting.
  • fix(loader): bootstrap addon before module init
    Move Main.lua earlier in WowSync.toc so Addon-1.0 initialization
    runs before files that call addon:NewObject(...) at load time.
    Fix chat frame method guard checks in Modules/Chat.lua by using
    dot-notation for existence checks and colon-calls for invocation.
    This prevents startup load failures seen in Talents, ActionBars,
    and Chat.
  • fix(toc): update interface version to 120007
  • refactor(modules): unify interface validation
    Define module capabilities in one place and validate registrations.
    This keeps docs and runtime checks aligned and helps future API
    changes stay enforced consistently.
  • refactor(watcher): rename module watcher contract
    Rename optional module hooks to make the capture and watch contracts
    clearer to read and maintain. Behavior stays the same, including
    debounce handling and combat-time capture deferral.
  • feat(docs): add live tracking feature and unsaved changes badge to README
  • feat(sync): announce live setup changes
    Broadcast an event whenever a character's live setup is mirrored into
    its current state, so the companion interface can reflect how far it has
    drifted from a saved profile as it happens.
    Only the single-module live path announces the change; the full
    recapture stays silent because the preview that listeners run itself
    triggers a recapture and would otherwise loop.
  • feat(sync): defer live capture during combat
    Hold off mirroring action bars while the player is in combat, when
    bonus and stance bars swap the visible slots and would otherwise be
    recorded as the real setup. The skipped capture is retried once
    combat ends.
    Preserve each module's last-known state when a refresh skips it, so
    a reload or logout in combat no longer clears modules that declined
    to capture.
  • feat(sync): mirror live changes into current
    Keep each character's Current profile in sync with in-game changes
    between saves. Modules now declare watch events, and the watcher
    refreshes only affected modules with debounce to avoid noisy recaptures.
    Add a watcher slash command and default-on setting so players can
    toggle the behavior when needed. Apply and undo now suppress watcher
    echoes during their settle window, preventing self-triggered refreshes.
  • refactor: remove redundant undo API forwards
    The public interface already hands out the profile manager, so the thin
    methods that forwarded a few undo calls to it only duplicated part of
    that object and left the surface inconsistent. Remove them and let
    callers reach the manager directly.
  • refactor: organize source into feature folders
    Replace the core and storage split and the two model subfolders with
    feature-oriented folders: shared utilities and value types together, the
    captured-state data and its stores together, the registry alongside the
    module implementations, the orchestrator with the entry points, and the
    dialog definitions on their own.
    Rename the bounded-history type to say what it is rather than how it was
    first used, and reorder the load sequence so every object is defined
    before the files that resolve it.
  • refactor: model apply results and bounded history
    Route the apply and undo paths through a dedicated result object that
    wraps the per-module outcome map and exposes sorted accessors. The
    command line and window now report applied and skipped modules in a
    stable order instead of arbitrary iteration order.
    Centralize the push-and-evict-oldest behavior, previously duplicated in
    the undo and snapshot stores, behind a bounded-history view that wraps a
    persisted list in place. Protected entries are exempt from eviction so
    pinned snapshots survive trimming.
  • docs(readme): emphasize UI-first workflow
    Restructure the README to present the UI as WowSync's main experience
    instead of framing slash commands as equal alternatives.
    Add a dedicated WowSync_UI section that explains the companion addon,
    how it loads on demand, and why the visual workflow is the product's
    core value. Expand window usage guidance with clear entry points from
    the AddOn Compartment icon and slash toggles.
    Update command documentation to reflect current syntax and placement,
    including hash-targeted apply and delete, help usage, and prefix
    matching notes. Move Undo below Slash Commands for a more logical flow
    through discovery, operation, and recovery.
  • docs(readme): clarify slash command usage
    Document that /ws and /wowsync are interchangeable for all commands.
    Update examples to include hash-targeted apply and delete operations,
    flag-style apply modes, per-profile snapshot listing, and /ws help.
    Add guidance that @hash accepts the short hash from list output and
    supports unambiguous prefix matching so users can target snapshots
    without pasting full hashes.
  • feat(cli): support snapshot hash selectors
    Add git-style snapshot selection to profile commands.
    Apply and delete now accept name@hash selectors, resolve exact hashes
    first, and then allow unambiguous prefixes when needed.
    When a selector is ambiguous or missing, the command now prints clear
    feedback so users can correct the hash instead of guessing.
    List with a profile name now shows snapshots newest first with short
    hashes and pinned markers to make target selection easier.
    Apply mode options now use --merge and --exact, and usage text was
    updated so the command help matches the new behavior.
  • refactor(core): streamline WowSync entrypoints
    Move slash-command handling into a dedicated commands object so
    Main stays focused on addon startup and database initialization.
    Expose printing and UI toggle on the public WowSync API and route
    compartment and slash interactions through that shared surface.
    Trigger a toggle event for the UI handoff instead of calling a
    global UI function directly, reducing cross-addon coupling.
    Remove obsolete feedback text tied to the old toggle flow.
  • fix(storage): surface module capture failures
    Print a diagnostic when a module's capture errors, instead of silently
    dropping it from the character's current setup, so a broken module is
    visible rather than appearing as missing data.
    Also clarify that the snapshot history cap is soft: pinned snapshots are
    never pruned and can keep the count above the configured maximum.
  • feat(profiles): save from another character
    Capture the logged-in character's setup on logout so other characters
    can browse it later without having to log in.
    Add a backend path that saves another character's stored setup into a
    profile, optionally limited to a chosen subset, sourcing the snapshot
    from that character so its identity carries through.
  • docs(readme): refresh usage for snapshots and undo
    Update the usage guide to match the snapshot-based workflow in the UI.
    Describe save dialog support for notes and module subsets.
    Document merge and exact apply modes in the command reference.
    Replace old revert wording with undo terminology and command examples.
    This keeps onboarding docs aligned with current behavior and reduces
    confusion for players moving from older versions.
  • feat: expose undo history and multi-step undo
    The undo stack was already kept per character, but only its most recent
    entry was reachable. Surface the whole history newest-first so the UI
    can list past changes, and add a cascading undo that rolls back several
    applies in one go.
    Each step still re-applies the captured pre-change state exactly, so
    undoing to a deeper point simply walks back through the intervening
    changes in order.
  • refactor(apply): clarify mode naming and API
    Apply strategies now use SnapshotApplyMode with Merge and Exact,
    which makes destructive behavior easier to understand at a glance.
    The apply command also accepts merge or exact so operator wording
    matches the behavior exposed by modules.
    The mode metadata is now exposed through the public models surface,
    and profile accessors return each module's supported apply modes.
    This gives the companion UI enough information to show safe mode
    choices without reimplementing backend bitmask rules.
  • feat(storage): expose snapshot mutation facade
    ProfileManager now exposes snapshot note updates, pin toggles, and
    snapshot deletion through its public facade.
    This lets callers manage snapshot metadata and lifecycle without
    reaching past the storage orchestrator into lower-level stores.
  • feat(wowsync): add merge diff for indexed modules
    Profile previews now report pending merge changes for indexed modules,
    so apply feedback is consistent beyond collection-based modules.
    Action bars, talents, edit mode, combat log, and tracked settings now
    show added, changed, and removed entries before apply.
    Diff scope now mirrors real apply scope for spec-specific data, so the
    preview no longer claims changes that the current apply cannot perform.
  • feat(wowsync): add merge/replace diff primitives
    Add reusable primitives so collection state can be previewed and
    applied with consistent merge/replace behavior.
    • introduce a flags enum to describe supported apply behaviors
    • introduce a keyed set comparator for preview-ready change groups
    • add diff generation and mode-aware apply for collection state
    • keep merge non-destructive and make replace remove stale entries
    • move reload prompt registration into shared initialization
    • add a localized label for character-scoped macro entries
  • feat(wowsync): rewrite storage orchestrator to snapshot history
    • Rewrite ProfileStore as a per-profile snapshot history with
      dedupe-by-hash, body/pin editing, and oldest-unpinned pruning
    • Rewrite ProfileManager into the orchestrator: Save, PreviewApply,
      Apply with per-module merge/replace, and multi-level Undo backed
      by a full safety snapshot pushed to UndoStore
    • Delete RevertManager; UndoStore now owns rollback
    • Drop RevertPoints from DB defaults
    • Rewrite /ws slash: save, apply [merge|replace], undo, delete, list
      (current/latest reserved on apply)
    • Swap the Core API revert surface for HasUndo/GetUndoInfo/Undo
    • Update enUS strings for the undo-based flow
  • feat(wowsync): add versioned-setup primitives
    • Add Hash and Time core concepts: a 64-bit FNV-1a content
      fingerprint and a shared timestamp/short-display format
    • Add Snapshot helper composing Hash and Time into the shape
      used for profile history and the undo stack
    • Add CurrentStore for per-character live setup capture
    • Add UndoStore multi-level safety-snapshot stack capped by setting
    • Add Differ to aggregate per-module apply previews
    • Validate optional module Diff and CanCapture in ModuleRegistry
    • Seed Characters and Settings defaults and register new files
  • fix(wowsync): keep revert points complete and correct macro limit
    Refuse to apply any module whose current state could not be backed
    up, so a revert always restores everything an apply changed. A module
    whose pre-apply snapshot failed is now reported as skipped instead of
    being applied with no way back.
    Correct the character macro limit fallback to match the current game
    value so the full range of character macros is captured and restored.
  • feat(pkgmeta): add WowSync_UI addon to externals and move folder
  • docs(wowsync): add usage guide and safety notice
    Add a user-facing README that explains how players save, apply,
    list, and revert profiles from the window or slash commands.
    Clarify which profile data can be synchronized so readers know
    what will and will not change on their character.
    Document that the addon is still experimental and may change
    between updates, including a caution that applying profiles can
    overwrite an existing setup.
  • fix(license): update copyright year to 2026
  • feat(wowsync): harden slash handler and localize addons
    Wrap the WowSync_UI toggle in pcall so an error in the separate UI
    addon cannot break the slash command, and trim slash input before
    parsing so whitespace no longer leaks into profile names. Localize
    the addons reload popup strings.
  • refactor(wowsync): move cvar registry to constants
    Relocate the tracked CVar list from the Settings module into
    Core/Constants so configuration data lives alongside other addon
    constants. Behavior is unchanged.
  • refactor(wowsync): localize chat module string
    Move the chat tab creation failure message into the locale table so it
    can be translated. CombatLog has no user-facing strings and needs no
    changes.
  • refactor(wowsync): localize talents module strings
    Move all user-facing messages in the Talents module, including import
    errors and apply notices, into the locale table so they can be
    translated. EditMode needs no changes.
  • refactor(wowsync): localize action bars warning
    Move the cross-class apply warning in the ActionBars module into the
    locale table so it can be translated, and load Locales ahead of the
    Modules block so feature files can capture addon.L at file scope.
  • refactor(wowsync): split profile manager
    Extract module registration, profile persistence, and revert storage
    into ModuleRegistry, ProfileStore, and RevertManager objects.
    Keep ProfileManager as the orchestration facade so external calls
    from Main and WowSync_UI remain unchanged.
    Wire the new storage objects in the TOC before ProfileManager so
    init order stays correct and module registration still works.
    Improve separation of concerns and testability with no user-facing
    behavior changes.
  • feat(wowsync): move profile storage to AceDB
    Switch WowSync persistence to AceDB-3.0 and
    load needed dependencies in the TOC.
    Add CallbackHandler-1.0 and AceDB-3.0 externals for packaging.
    Initialize addon.DB in Main and use addon.DB.global for profile and
    revert-point data in ProfileManager.
    Keep the ProfileManager API stable while replacing raw table writes
    with AceDB-backed storage.
  • feat(wowsync): initial module implementation
    Deliver the initial WowSync addon: save the current character setup as a
    named profile and reapply it to any character, with a revert point to
    undo the last apply. Each domain is its own module behind a shared
    contract, run by a central profile manager.
    Profile manager: registers modules; runs capture, save, apply, delete,
    rename, and revert, taking a revert snapshot before each apply.
    Action bars: capture and restore action slots for both shared bars and
    the active spec, resolving macros and equipment sets by name across
    characters.
    Addons: sync which addons are enabled, never disable WowSync itself, and
    prompt a reload when the list changes.
    Chat: restore chat windows with their colors, channels, message groups,
    position, and docking.
    Combat log: save and restore combat log filters and active selection.
    Edit mode: store and reapply the HUD layout using its export string.
    Keybindings: capture and reapply key bindings for the current set.
    Macros: sync both account and character macros, matching edits to the
    correct scope.
    Settings: capture and apply a broad set of tracked options, split by
    account and character scope, skipping protected values.
    Talents: export and import the talent loadout, including pvp picks.
    API: expose profile operations to other code through a small facade.
    Branding and locale: add an accent color, a text colorizer for output,
    and English strings for all command feedback.
    Entrypoint: handle the save, apply, list, delete, rename, and revert
    commands, plus a UI toggle and addon compartment launcher.
    Harden apply paths so one protected option cannot abort a batch, muted
    audio is always restored on error, and a missing binding set is guarded.
    Load order now initializes the foundation and localization first.
  • Update TOC
  • Add initial addon files