Releases: garneck/PugHelper
Releases · garneck/PugHelper
v2.1
Changelog
v2.1
Maintenance release — no in-game changes; packaging and release-process improvements only.
v2.0
First CurseForge release.
- Draggable window of per-tab raid and heroic boss/trash callouts.
- Role tokens (e.g.
{TANK},{HEAL}) substituted with player names, sent to chat on click. - Drag any callout to your action bar as a self-updating macro.
- In-game editor for callouts, plus a Set Names overlay to rename and reorder roles per tab.
v2.0
PUG Helper
v2.0 (2026-06-23)
Full Changelog Previous Releases
- Add CurseForge packaging via BigWigs packager
- Tag .toc with X-Curse-Project-ID 1585189
- Add .pkgmeta (package-as PugHelper, ignore dev-only files)
- Add release workflow that packages and uploads on tag push
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- Add per-line "drag to action bar" callout macros
Each callout line gets a drag handle (normal mode) that turns the line
into a self-contained WoW macro ("/pug send ") and puts it on
the cursor to drop on an action bar -- a one-click broadcast button.
The macro substitutes {TOKENS} and resolves the channel LIVE at click
time (same Chat.SendLine path as the in-window click), and is a snapshot
that survives /reload, relog, and updates with no saved-vars mapping.- Core/Macro.lua: PickupForLine/Fits/Explain; body-hash names (PH+base36,
<=16 chars) reuse one macro per line. All macro API is api.has-guarded
and CreateMacro is pcall'd (it errors when the macro list is full). - Core/Api.lua: api.InCombat shim; the gesture is refused in combat
(CreateMacro/PickupMacro are #nocombat and bar drops are protected). - Core/Slash.lua: new "/pug send " subcommand.
- UI/Window.lua: pooled per-row grip (normal mode only, hidden in edit
mode), reserved label width, tooltip that warns in amber on unset
{TOKEN}s (mirrors the in-window send guard), updated hint + once-ever tip. - Over-long callouts (>~245 chars) are refused, never truncated.
- Config/Namespace/.toc/.luacheckrc/CLAUDE.md updated.
Verified macro API signatures + #nocombat behavior against warcraft.wiki.gg.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- Core/Macro.lua: PickupForLine/Fits/Explain; body-hash names (PH+base36,
- Set Names: edit roles + drag-to-reorder, scoped per tab
Add an Edit button (rename any role's label; change the {TOKEN} for custom
roles only, since built-in tokens are referenced by callouts) and drag-to-
reorder to the Set Names overlay, mirroring the callout section/line drag.
Engine (Config/Content):- customRoles gains per-tab
labels(token -> label override) andorder
(token list); merged into old saves and swept by PruneCustomization. - EffectiveRoles applies the per-tab label override + display order and
exposes baseLabel; new EditRole/MoveRole/SetRoleLabel. - A custom token change migrates the saved name and follows the token through
the order/label/hidden maps (renameTokenInMaps); deleting/reset clean up
stale label/order entries.
UI: - Role rows are draggable buttons with a per-row Edit button, a drop
indicator, and a trailing end-zone for the last slot; a modal role-edit
popup (label for all, token for customs). Row body is drag-only so it
never fights the dropdown's click area. - Editor popup closes on tab switch and window hide.
Editing/reordering are per-tab; Reset roles drops the tab's customs, hides,
labels, and order. luacheck clean; CLAUDE.md updated.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- customRoles gains per-tab
- Fix 14 issues from a comprehensive adversarial review
All findings were low/nit (the WoW-API surface came back clean). Grouped:
Display correctness (FontString '|' escaping): user-authored callouts,
section titles, the instance note, custom-role labels, and the editor
confirm/preview/send-confirm surfaces are now escaped via a shared
util.escapePipes (display-only; what's broadcast to chat is untouched).
Fork-on-edit: SetLine/SetSectionTitle/MoveSection/MoveLine now compare
against a non-forking sourceSections() and bail on a no-op BEFORE calling
materialize(), so re-saving identical text or a drop-in-place drag no
longer falsely flags a tab "(customized)".
Custom roles: RemoveCustomRole uses an explicit branch (noa and b or c
fall-through to the global list); a global AddCustomRole now rejects a
token already used per-instance (no silent shadowing); the add-role error
is preserved across background roster-update rebuilds.
Saved-vars lifecycle: Config.PruneCustomization + Content.PruneCustomization
reap per-instance data for removed/renamed content (run from Boot), and
PruneNames no longer lets orphaned roles pin saved names.
UI lifecycle / perf: the window's OnHide hides the Set Names overlay so a
reopen lands on the callouts; ToggleNames' hide path refreshes the pane;
the roster/leader watcher skips work while the window is hidden (channel
button catches up on reopen).
Nits: UTF-8-safe util.truncate replaces byte-based :sub truncation in the
delete-line/live/send previews.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com - Add a UI design-token module for a cohesive, professional look
Introduce UI/Theme.lua (ns.UI.Theme) as the single source of truth for
the UI's colours, the cross-file sizes, and font roles, then migrate every
UI module onto it. This is an internal token layer, not a user-facing
theming system - nothing is configurable or saved.
Collapses the value drift the UI had accumulated:- 4 near-identical dark panel fills -> one panelBg
- 3 different border greys (+ the Set Names panel had none) -> one
panelBorder, applied via a shared UI.PanelChrome helper - multiple blues/greens/oranges -> one accent / ok / unset token each
- the unset-{TOKEN} cue was literally two different oranges (vertex vs
inline text); both now derive from one token via Theme.hex, so they
can't drift again
Structure/polish: - UI.TitleBar gives the editor popup and Set Names overlay the same
title-bar strip as the main window - a vertical divider between the tab list and the message pane
- ROW_INSET 22 -> 18 so wrapped callout text fills the row (no dead strip)
- distinct flash token keeps the send-confirmation pulse vivid
Adds wrap-safe Theme.addLine so a coloured+wrapped GameTooltip line can't
truncate the colour's returns against the trailing wrap flag. All texture-
based, no :SetBackdrop, no new API; luacheck clean.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- Third UX pass: unset-send guard, terminology, onboarding, feedback
Driven by a multi-agent UX review (9 lenses, findings adversarially verified
against the source and the project's constraints).
Send-loop safety:- Gate sending a line that still has an unset {TOKEN} behind a "Send anyway"
confirm showing the exact text + channel, so a click mid-pull can't broadcast
a literal "{MT} tanks ..." to the raid. Resolved lines still send on one click. - Double-send guard: swallow a repeat click within ~0.4s (guarded C_Timer shim;
never latches when no timer exists, so sends always work). - Flash "sent" only when a line actually went out (empty/whitespace sends none).
Terminology & microcopy: - Set Names panel: 5-man Heroics are "tab", not "raid"; fix "Reset raid"
references (the control is "Reset roles"); reset confirm reads "Reset callouts". - Slash: /pug show only shows; /pug edit forces edit ON (idempotent); /pug
channel reports the resolved channel; /pug names states its scope; unknown
commands warn; /pug reset clarified as window-position only. - Channel codes upper-cased in the tooltip; line-drag tooltip scoped
"within section" (cross-section drops are a no-op).
Onboarding & clarity: - Content hint adapts when a tab has no callouts yet (the framework model).
- Edit-button tooltip sets the "tabs ship blank, author here" expectation.
- Load message names the minimap button alongside /pug.
Other: - "Reset callouts" reachable whenever a tab is customized, not only in edit mode,
so the always-on "(customized)" badge has a remedy. - Stale-assignment cue backed with text, not color-only (accessibility).
- Add-role Tab key cycles Name<->Token; brighter edit-mode tint; clear the
left-list search filter on window reopen.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
- Gate sending a line that still has an unset {TOKEN} behind a "Send anyway"
- UX pass: modal signalling, channel safety, feedback, and clarity
From the third (UX-focused) adversarial review. Core one-click send keeps no
added friction; shipped content stays a framework (empty-state messaging only).
Modality (the headline gap):- Modal blockers now DIM the window behind them, so the lock is visible instead
of clicks silently dying on a transparent scrim. - Confirm dialog is named + in UISpecialFrames, so Escape cancels the confirm
instead of closing the whole window. - Edit mode tints the message pane amber, so "click edits, not sends" is obvious.
Channel safety: - The channel button turns red when the live target is SAY/GUILD (public), and
shows "(now: X)" instead of an unexplained ">". - Right-click the channel button to step back (one-click overshoot recovery).
- RAID_WARNING downgrades to RAID when you're in a raid but not lead/assist
(it was silently delivering nothing); new guarded api.CanRaidWarn() shim. - /pug channel (no arg) now reports the current channel + where it lands.
Feedback / clarity: - Unfilled {TOKEN}s are tinted orange in the line text ...
- Modal blockers now DIM the window behind them, so the lock is visible instead