# Changelog

## [v0.2.0] (2026-05-04) - Addon Load Monitor

### New Features

- **Addon Load Monitor** — New tab (`/togt al`) showing every installed addon's memory usage, load status, and load timing. Sortable by name, memory, load time, and status (failures-first when descending). Summary bar shows totals (loaded / failed / disabled / on-demand) and total memory. Requires the `!TOGT` companion addon for full timing coverage across all addons. Location: `Modules/AddonLoad/AddonLoad.lua`, `GUI/AddonLoadTab.lua`.
- **!TOGT companion integration** — `!TOGT` (companion addon) added as a required dependency. Loads before all other addons at the very start of the loading screen (the `!` prefix sorts before all letters) and records load order and per-addon offset into the `TOGToolsEarlyData` global. The Addon Load Monitor reads it at display time and shows a status-bar indicator (`!TOGT active` / `!TOGT missing`).
- **Shared `addon.RowList` component** — New file `GUI/RowList.lua`, ported and trimmed from FastGuildInvite's `GUI/RowList.lua`. Reusable sortable-row list for any tab that needs a tabular data view: brand-colored clickable header bar, click-toggle ASC/DESC sort with per-column `sortKey`/`sortDescDefault`/`sortable`/`gapBefore` opts and tie-break on `entry.name`, alternating row banding, virtual-scroll pool that grows with the parent's height, custom Blizzard-textured scrollbar, mouse-wheel scroll. Cells use `SetWordWrap(false)` + `SetMaxLines(1)` and anchor `LEFT/RIGHT` to the parent so column layouts compact elastically when the user shrinks the window — no row-wrap. Public API: `:New(parent, opts)`, `:SetData(arr)`, `:SetSort(key, desc)`, `:Refresh()`, `:Detach()`. Registered to all six TOC files after `Compat.lua`, before `MainWindow.lua`.
- **`Compat.lua` shared GUI helpers** — `addon.Tooltip.Owner` / `AnchorFrame` (smart anchor flipping based on screen half), `addon.AceGUIFrameScripts` (leak-safe raw frame scripts that restore prior handlers on pooled-widget release), `addon.GUI.AttachTooltip`, `addon.GUI.MakeColumnHeader`, `addon.GUI.ApplyMinResize`, `addon.GUI.DetachPool`. Used by every tab.

### Bug Fixes

- **Load times reporting `0.000s`** — `GetTime()` is frame-locked, so every `ADDON_LOADED` event fired in the same loading-screen frame returned the same timestamp. Per-addon deltas collapsed to zero. Switched the timing capture in `!TOGT.lua` and the fallback capture in `Modules/AddonLoad/AddonLoad.lua` to `debugprofilestop()`, which has sub-millisecond precision. Offsets are stored in seconds (ms / 1000) so downstream consumers are unchanged.
- **Load Time column sort produced random-looking order** — The sort comparator in `GUI/AddonLoadTab.lua` was reading `row.offset` (cumulative seconds since the first event) instead of `row.loadTime` (per-addon delta). Because `offset` is monotonic with load order, clicking the header effectively sorted by load order regardless of direction. Comparator now reads `row.loadTime`.
- **Addon Load tab wrapped to multiple lines on horizontal shrink** — The tab used AceGUI Flow with `widget:SetWidth(...)` per cell, so when the user shrunk the window narrower than the column-width sum AceGUI moved cells to a new line and the layout fell apart. Replaced the row-rendering path with `addon.RowList`, whose anchor-based cells truncate instead of wrapping. The window's `minWidth` was tightened from 640 to 520 now that compaction is graceful.
- **Tab status bar leaked between tabs** — `MainWindow:DrawTab` now resets the status text to the version string before delegating to the tab module, so a tab that overrides the status (e.g. Addon Load showing `!TOGT active/missing`) doesn't bleed that text into the next tab the user opens.
- **Tab content didn't reflow on tab switch** — `MainWindow:ApplyTabSize` now calls `f:DoLayout()` after sizing, so when switching between tabs whose `WINDOW_SIZE` differs, the new tab's content reflows immediately instead of inheriting stale layout.

### Improvements

- **Addon Load tab column widths tightened** — Status reduced from 175 → 85 px (fits "Wrong Version"); Memory reduced from 110 → 65 px (fits "999.9 MB"); Load Time reduced from 110 → 60 px. The auto-width Addon Name column reclaims the freed space. `RowList`'s `SCROLLBAR_GUTTER` reduced from `SCROLLBAR_WIDTH + 6` to `SCROLLBAR_WIDTH + 2` so the rightmost column sits ~5 px from the scrollbar. Status column gets `gapBefore = 5` to break the visual collision between right-justified Load Time text and left-justified Status text.
- **Sort indicator removed from active column header** — `RowList:_updateHeaderText` no longer appends a glyph (`v` / `^`) to the active sort column; WoW's default font doesn't render unicode triangles cleanly and ASCII letters look like typos. Click affordance is communicated via the column tooltip.
- **AceGUI pool-bleed protection** — `RowList:Detach()` orphans the row pool, header, and scrollbar to `UIParent` on host-widget release; a `_detached` guard on `:Refresh()` makes sure a recycled host doesn't trigger a pool grow that would re-attach rows into the next addon's widget. Wired via `body:SetCallback("OnRelease", ...)` in `GUI/AddonLoadTab.lua`.
- **`.luarc.json` updated** — Added `debugprofilestop` to `diagnostics.globals` in both `TOGTools/.luarc.json` and `!TOGT/.luarc.json` so the new timer call resolves cleanly under the Lua LSP.

---

## [v0.1.0] (2026-05-04) - Initial Release

### New Features

- **Project scaffolding** — TOC files for all WoW versions (Vanilla 11508, TBC 20505, Wrath 30405, Cata 40402, Mists 50503, Retail 110207/120001/120000), `.pkgmeta` with BigWigs packager config, `.luarc.json` (Lua 5.1 LSP), `.markdownlint.json`, and `.github/workflows/release.yml` for tag-triggered CurseForge releases.
- **Core addon** — `TOGTools.lua`: AceAddon-3.0 instance with AceConsole-3.0, AceEvent-3.0, AceHook-3.0 mixins; AceDB-3.0 schema (`char` scope); version detection flags (`gv.isVanilla`, `gv.isTBC`, `gv.isWrath`, `gv.isCata`, `gv.isMists`, `gv.isClassic`, `gv.isRetail`, `gv.isRetail120Plus`).
- **Slash commands** — `SlashCommands.lua`: all `/togt` command registration and handling in a dedicated file, separate from core addon logic. Subcommands: `/togt` (toggle window), `/togt np` (Name Prefix tab), `/togt settings` (open settings), `/togt vc` (version check).
- **Tabbed main window** — `GUI/MainWindow.lua`: dynamic AceGUI Frame + TabGroup; tabs auto-populate from `addon.modules` sorted alphabetically by `label`; per-tab locked/unlocked window sizing via `WINDOW_SIZE`; ESC-to-close proxy; position persistence via AceDB.
- **Name Prefix module** — `Modules/NamePrefix/NamePrefix.lua` + `GUI/NamePrefixTab.lua`: wraps `ChatEdit_SendText` (Classic) or hooks `EventRegistry` (Retail 12.0+) to prepend a configurable nickname to outgoing chat messages. Settings: enable/disable, nickname, format string with live preview, per-channel toggles (Guild, Officer, Party, Raid, Instance, custom channel), skip-exclamation option, suppress-if-char-name option. Per-character DB scope. Skips messages beginning with `/` (slash commands/macros) unconditionally.
- **Minimap button** — `GUI/MinimapButton.lua`: LibDataBroker-1.1 launcher + LibDBIcon-1.0 registration. Left-click toggles the main window; right-click opens the native addon settings panel. Icon: `textures/ToGTools_PH_MMB.tga`. Button show/hide state and position persisted in `DB.char`.
- **Addon settings panel** — `GUI/Settings.lua`: AceConfig-3.0 options table registered under ESC → Interface → Addons → TOG Tools (native Blizzard panel). `addon:OpenSettings()` uses `Settings.OpenToCategory` (Classic Era 1.15+ / Retail 10+), `InterfaceOptionsFrame_OpenToCategory` (older builds), or `InterfaceOptionsFrame:Show()` as a final fallback — detected by API presence, not version flag.
- **VersionCheck-1.0 integration** — `VC:Enable(Ace)` called on all non-Retail versions in `OnInitialize`; `/togt vc` broadcasts a guild-wide version check and prints responses after 21 seconds.
- **Embedded libs** — `libs/LibDataBroker-1.1.lua`, `libs/LibDBIcon-1.0.lua` (single-file embeds, copied from TOGProfessionMaster).
- **MIT License** — `LICENSE` file added; referenced in `.pkgmeta` via `license-output`.
- **CurseForge project** — Project ID `1533830` set in `.pkgmeta` and all TOC files.
- **Governance files** — `.github/copilot-instructions.md` and `CLAUDE.md` with full project rules (module pattern, commit/tag process, changelog format, HTML doc rules, no-tag rule).

### Bug Fixes

- **Name Prefix not reaching other players** — `hooksecurefunc` fires after `SendChatMessage` has already been called. Fixed by wrapping `ChatEdit_SendText` directly (`local orig = ...; ChatEdit_SendText = function(...) ... return orig(...) end`) so the prefix is applied before the message is sent. Location: `Modules/NamePrefix/NamePrefix.lua`.
- **Macros/slash commands being prefixed** — Added an unconditional early-return in `ModifyMessage` when the message starts with `/`. Location: `Modules/NamePrefix/NamePrefix.lua`.

---
