Cogworks

The shared mainspring of the Cogworks WoW addon suite — event bus, theme, and cross-cog plumbing for FlipQueue, Tempo, Maxcraft, and beyond.

File Details

v0.11.0

  • R
  • Apr 30, 2026
  • 189.57 KB
  • 7
  • 12.0.5+1
  • Retail

File Name

cogworks-v0.11.0.zip

Supported Versions

  • 12.0.5
  • 12.0.1

Cogworks

v0.11.0 (2026-04-30)

Full Changelog Previous Releases

  • chore(release): v0.11.0 — full Phase A/B/C UI primitive set
    Bumps lib.version 0.10.0 -> 0.11.0; MINOR is already 15. Closes
    out the primitive surface called for in cogworks issue #1: Forms,
    Sections, TabPanel, MiniView, Text helpers, Wizard, Tree,
    ReorderableList. Per-module load guards make future divergence
    safe.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • docs(migration): extend tempo + maxcraft plans for Phase B/C primitives
    Both docs predated the Phase B (TabPanel, MiniView, Wizard, Text)
    and Phase C (Tree, ReorderableList) primitives. Adds:
    - Updated prerequisites: load Cogworks-1.0.xml (the manifest
    pulls in all module files) instead of the single .lua entry
    point that predates Forms / TabPanel / etc.
    - New phases for ScrollTable migration, MiniView migration
    (Tempo's reset timer, Maxcraft's CoachWidget), Wizard
    migration (SetupWizard rebuilds), tabbed settings, and tree /
    forms primitives where applicable.
    - "What stays" lists no longer hold ScrollTable.lua or
    SetupWizard as un-migrateable — they have lib equivalents.
    - Revised scope estimates (~900-1000 LOC for Tempo, ~500-600
    for Maxcraft).
    The full primitive surface is documented once in flipqueue.md;
    tempo.md and maxcraft.md reference it.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • docs(migration): rewrite flipqueue plan for full Phase A/B/C primitive set
    The migration doc was anchored on v0.10.0 era primitives (theme +
    ScrollTable + Forms). With Phase B (TabPanel / MiniView / Wizard /
    Text helpers) and Phase C (Tree / ReorderableList) now shipped, the
    doc was significantly understating what's possible. Rewrites the
    whole thing around the current primitive surface, adds a phased
    plan that covers FlipQueue's full UI rebuild, and a file-by-file
    mapping table so the FlipQueue agent has one place to look up
    "which Cogworks primitive does this file get".
    Revised LOC estimate is ~1,700-2,600 lines removed (vs the earlier
    80-120 number) since ScrollTable.lua + the local mini-view / wizard
    chrome / quality-color tables all delete entirely.
    Sequencing section at the bottom maps user-prioritized FQ issues
    (#18, #14, #15) to which Cogworks phases each one needs.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • feat(COG-1): CreateTree + CreateReorderableList (Phase C)
    CreateTree (Cogworks-1.0/Tree.lua) — hierarchical expand/collapse
    list. Nodes are { key, label, count?, children? }; chevrons render
    only on branches; click chevron to toggle, click row to select.
    Public API: SetNodes, Expand, Collapse, Toggle, ExpandAll,
    CollapseAll, SetSelected, GetSelected, IsExpanded. Non-virtualized
    row pool — fine up to a few hundred visible nodes. FlipQueue's
    ResearchPage migrates to this.
    CreateReorderableList (Cogworks-1.0/ReorderableList.lua) — vertical
    drag-to-reorder list. Caller owns row contents via renderRow(row,
    item, index); onReorder(items, from, to) fires on drop. Sibling
    rows shift visually during drag so the user can preview the drop
    target. FlipQueue's AllocWidget migrates to this.
    Closes the Phase B + Phase C primitive set in #1: with TabPanel,
    MiniView, Text, Wizard, Tree, and ReorderableList all available,
    FlipQueue has the toolkit it needs to rebuild its full UI on
    Cogworks primitives.
    Showcase entries at /cogworks ui -> Tree and Reorderable.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • feat(COG-1): CreateWizard — multi-step flow widget (Phase B)
    Header (title + progress dots), lazy-built per-step content area,
    footer (Cancel / Previous / Next-or-Finish). Each step takes an
    optional validate() that gates the Next button; callers wire
    wizard:Refresh() to revalidate after the user changes input. The
    Next button auto-relabels to opts.finishLabel (default "Finish") on
    the last step. onComplete fires on Finish, onCancel on Cancel,
    onStepChange(key, idx) for telemetry.
    Closes the Phase B set in #1: TabPanel + MiniView + rich-text
    helpers + Wizard now all available. FlipQueue's SetupWizard,
    config migrators, and import-confirmation flows all reach for this
    shape.
    Showcase entry at /cogworks ui -> Wizard demos a 4-step flow with
    validation gates (checkbox required on step 2, non-empty input
    required on step 3) plus a final review step.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • feat(COG-1): CreateMiniView + rich-text helpers (Phase B)
    CreateMiniView (Cogworks-1.0/MiniView.lua) — draggable, resizable,
    pinnable heads-up frame. Title bar with title text + pin + close;
    bottom-right resize grip; content area for caller widgets. Position,
    size, and pinned state persist into a caller-supplied savedvars
    table; geometry restored on every Show(). Pin locks the frame and
    hides the grip. Honors the suite's uiScale setting via
    SettingsChanged. Consumers: FlipQueue heads-up, Tempo reset timer,
    Tally running net-worth, Maxcraft profession progress.
    Rich-text helpers (Cogworks-1.0/Text.lua) — QualityColorName,
    QualityColorHex, ClassColor, ClassColorName, FormatGoldValue,
    FormatGSC, FormatGoldShort. Lifted from FlipQueue's UI/Shared.lua so
    all cogs render quality-colored item names, class-colored character
    names, and gold values the same way. Quality accepts numeric IDs or
    canonical name strings; gold formatting comes in three flavors
    (rounded-thousand, full G/S/C breakdown, abbreviated short).
    Both have showcase entries at /cogworks ui -> MiniView and Text.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • feat(COG-1): CreateTabPanel — inline horizontal tab panel (Phase B)
    Tab strip on top, content area below; pages are lazy-built on first
    activation. Tabs auto-fit their label width with a 60 px floor and
    reflow on fontScale / fontFamily changes. Active tab carries the gold
    accent on its bottom edge; hover and active states mirror the
    CreateNavButton pattern for visual consistency across the suite.
    Distinct from CreateNavButton: nav buttons are sidebar entries that
    pick which page to show; CreateTabPanel is the in-page horizontal
    selector for settings dialogs, multi-step forms, breakdown views,
    etc. — the shape FlipQueue's MainFrame and ResearchPage migrations
    need next.
    Showcase exercise lives at /cogworks ui -> Tabs.
    MINOR 14 -> 15.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • feat(lib): per-module load guards for safe version divergence
    Cogworks-1.0.lua's LibStub NewLibrary call short-circuits older copies of
    the main file, but module files (Sections, Forms, Icons, Items, Realms,
    API) historically had no equivalent guard — they just did
    lib = LibStub("Cogworks-1.0") and then assigned methods. When a sibling
    cog vendored an older Cogworks copy and loaded after the standalone
    library, the cog's older module files would clobber the standalone's
    newer methods. Surfaced today as MINOR-13 standalone Cogworks attaching
    section:SetContentHeightFn, then FQ's vendored MINOR-12 Sections.lua
    loading and redefining lib:CreateCollapsibleSection without the new
    method, breaking the showcase.
    Each module now starts with:
    local MODULE_MINOR = 14
    lib._modules = lib._modules or
    if (lib._modules.<Name> or 0) >= MODULE_MINOR then return end
    lib._modules.<Name> = MODULE_MINOR
    First writer at a given MODULE_MINOR wins; older copies skip cleanly.
    The convention (and when to bump MODULE_MINOR) is documented in
    CLAUDE.md's "When adding new library features" section.
    This fix only takes effect once consumer cogs vendor a Cogworks copy
    that has the guards — older releases (e.g. v0.10.0) will still clobber.
    The local FQ / Tally vendored copies are resynced to HEAD so all three
    addons load identical guarded module files until v0.11.0 ships.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • chore(lib): bump MINOR 13 -> 14 for SetContentHeightFn
    Forgot to bump when 86b8d74 added section:SetContentHeightFn. With FQ /
    Tally still vendoring MINOR 12 lib copies, the load-order interaction
    exposed the gap: those copies' Sections.lua re-runs after standalone
    Cogworks's, redefines lib:CreateCollapsibleSection with the v12 closure
    that has no SetContentHeightFn, and the showcase's call errors.
    Bumping MINOR doesn't on its own prevent the overwrite (older module
    files don't carry version guards), but it lets standalone Cogworks
    short-circuit FQ / Tally's main file properly. Local FQ / Tally lib
    copies will be resynced to HEAD in a follow-up so module files match.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • fix(sections): contentHeightFn + post-show settle pass
    Two coupled bugs surfaced when exercising collapse / re-expand on a
    section whose body is a wrapping FontString:
    1. Calling SetContentHeight from inside a relayout closure on every
    pass overwrote a previously-correct stored height with a stale
    single-line value when the body happened to be measured during a
    hidden state. Subsequent expand sized the section for the stale
    value and the wrapped body overflowed downward.
    2. body:GetStringHeight() returns the unwrapped single-line height
    when measured in the same render tick as the content:Show() that
    made the body visible. The first user-driven expand of a
    start-collapsed section therefore sized the section for one line
    and only "settled" if the user closed and reopened it.
    Section now exposes SetContentHeightFn(fn) — applyLayout calls it
    fresh each pass, so the height is always derived from current state
    rather than being a stored snapshot. When applyLayout transitions to
    the visible branch, it schedules a one-shot OnUpdate to re-run
    applyLayout on the next render tick — the wrapped height has settled
    by then and the section resizes itself correctly.
    Showcase makeTextSection switched to SetContentHeightFn. The
    formSection's row stack also uses it, with anchorFormRows folded into
    the contentHeightFn so a single applyLayout pass anchors rows and
    returns the resulting height. Page-level OnUpdate settle is no longer
    needed (Sections.lua handles it internally).
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • fix(showcase): OnUpdate settle pass to catch wrapped string heights
    WoW resolves FontString wrapped heights asynchronously. body:GetStringHeight()
    returns the unwrapped single-line height when measured during the same tick
    as the anchor chain that gives body its width. The page's first relayout
    therefore stores single-line contentHeights for sec1 / sec2, leaves sibling
    sections anchored at single-line Y offsets, and Section A's actual wrapped
    body overlaps Section B (visible in /cogworks ui Sections page on first
    navigation).
    The heightFn-recomputes-body-height pattern self-heals as soon as the
    wrapped heights are available — but that requires another relayout pass
    after WoW's next layout tick. One-shot OnUpdate at end of page build does
    exactly that. Same pattern added to pages.layout for consistency.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • fix(sections): early-exit + re-entrancy guard around contentHeight
    Two bugs surfaced when a collapsible section's body FontString is
    measured at construction time before the section has a position anchor
    on its parent:
    1. body:GetStringHeight() returned the unwrapped single-line height
    because the anchor chain hadn't resolved to a proper effective
    width. SetContentHeight stored that small value. On first user
    expand, body wrapped for real (anchor chain by then resolved via
    the showcase relayout) but the section frame was sized for the
    stale single-line value, so wrapped text overflowed downward into
    the next sibling.
    2. The onLayoutChanged callback I added previously fired from every
    applyLayout, including the one inside SetContentHeight. Caller
    relayout closures naturally call SetContentHeight again from
    inside the callback, which re-entered applyLayout, fired
    onLayoutChanged again, and recursed without bound.
    SetContentHeight now early-exits when the value is unchanged, and
    applyLayout now bails on re-entry. Together they let the showcase's
    heightFn-recomputes-body-height pattern self-heal once the page
    finishes its first relayout pass: sections store the correct wrapped
    height before the user ever clicks to expand them.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • fix: shrink minimap gear from 53 to 32 px
    CogBorder.tga's silhouette fills nearly the full 128x128 texture rect.
    LDBIcon's tracking-border default of 53x53 is sized for a much sparser
    ring asset; rendering CogBorder at that footprint visually overshoots
    the ~31px LDBIcon button by roughly 70% on each side.
    Tally tuned to 32x32 in its pre-adoption overlay-swap workaround. When
    TLY-003 dropped that workaround in favour of cw:RegisterCogMinimapButton
    the size regressed to 53. Both FlipQueue and Tally now show oversized
    gears post-adoption. Pinning the lib at 32 makes the visible footprint
    sit just past the button edge for every consumer.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • fix(showcase): refactor layout page onto collapsible sections
    The Layout page was the last showcase page using a hand-managed y-cursor
    with hardcoded gaps after CreateSectionHeader. At raised font scales the
    header consumed more vertical space than the cursor advanced, leaving
    the next demo overlapping the header. Converted each demo group into a
    CreateCollapsibleSection participating in the same y-stack + relayout
    pattern pages.sections uses, so font-scale changes always reflow and
    the headers no longer collide with their content.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • fix(sections): GetConsumedHeight reads fresh; onLayoutChanged hook
    Two coupled fixes for the close/reopen overlap reported in /cogworks ui:
    1. Sections.lua: section:GetConsumedHeight() now computes the height
    from current internal state (header height + content padding +
    contentHeight) rather than returning section:GetHeight(). Removes
    a class of staleness where GetHeight could read pre-applyLayout
    values during a relayout walk.
    2. Sections.lua: new opts.onLayoutChanged(h) callback fires on every
    applyLayout — toggle, font reflow, or SetContentHeight. Cleaner
    semantics than onToggle for callers that own a sibling stack and
    want to reflow on any size change, not just user-initiated toggles.
    Showcase pages.sections wires onLayoutChanged for relayout, recomputes
    each section body's GetStringHeight inside the heightFn (so font-scale
    changes propagate without manual subscription per section), and
    subscribes to SettingsChanged at the page level for an immediate reflow
    the moment scale changes.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • fix(showcase): collapsible sections relayout siblings on toggle
    The Sections page anchored each item once at construction with absolute
    y offsets, so toggling a collapsible's content open/closed left siblings
    in their original positions and made the expanded body overlap the next
    section. Refactored to a y-stack of (frame, heightFn, gap) items with a
    single relayout() closure; each section's onToggle and each form-row's
    onHeightChanged push back through it. Toggling now reflows the whole
    page below the change point.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • fix(gears): mesh Maxcraft and Tally edge gears with hub and cores
    Earlier CLUSTER_POSITIONS placed Maxcraft and Tally at y=31 with edge
    ring radius 22 while the meshed core trio sat at y=-21, leaving the
    edge gears ~9px shy of any neighbour. Pulled them down to y=17 so each
    edge meshes with both its core neighbour (TM/FQ) and the hub (CW)
    with the same ~5px overlap as the CW<->FQ<->TM mesh.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • docs(migration): note newly available Cogworks primitives for FlipQueue
    The flipqueue migration plan was written before ScrollTable, Sections,
    Forms, and dropdown auto-width landed in the library. Adds a status-update
    section listing the new primitives and removes the now-stale "ScrollTable
    stays in FlipQueue" claim.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • feat(COG-1): showcase page for sections + form helpers + dropdown auto-width
    Adds a "Sections" page to /cogworks ui that demos:
    - CreateCollapsibleSection (open / collapsed variants)
    - CreateSettingsCheckbox / Button / Input stacked with a y-cursor inside
    a collapsible section, with onHeightChanged-driven full-stack reflow
    - CreateDropdown autoWidth vs legacy fixed width, side by side
    Standalone-only change; no library API surface added, no MINOR bump.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • feat(COG-1): settings form helpers + dropdown auto-width
    Adds Cogworks-1.0/Forms.lua with CreateSettingsCheckbox, CreateSettingsButton,
    and CreateSettingsInput. Each helper returns (row, consumedHeight) so callers
    can stack rows with a y-cursor. All rows re-font and re-lay on SettingsChanged.
    Extends lib:CreateDropdown with an additive 5th opts arg accepting autoWidth /
    minWidth / maxWidth / width. With autoWidth=true, the dropdown measures every
    item label and fits to the widest, clamped by min/max; re-fits on SetItems and
    on font-scale / family changes.
    Bumps MINOR 12 -> 13. Existing four-arg dropdown callers are unaffected.
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
  • docs: document Player summary convention for SCRIBE release announcements
    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com