diff --git a/HellionChat/HellionChat.csproj b/HellionChat/HellionChat.csproj index d3cba89..b03c0c0 100644 --- a/HellionChat/HellionChat.csproj +++ b/HellionChat/HellionChat.csproj @@ -1,7 +1,7 @@ - 1.5.1 + 1.5.2 enable enable diff --git a/HellionChat/HellionChat.yaml b/HellionChat/HellionChat.yaml index 29f356b..926450b 100755 --- a/HellionChat/HellionChat.yaml +++ b/HellionChat/HellionChat.yaml @@ -35,6 +35,56 @@ tags: - Replacement - Privacy changelog: |- + **v1.5.2 — First-Run Wizard Rework (2026-05-18)** + + UX patch. The first-run wizard becomes a four-step flow with a + new Roleplay privacy profile and a power-settings step that + surfaces previously-hidden defaults. Existing v1.5.1 users see + the new wizard once on first v1.5.2 boot. + + What changes user-visible: + + - Wizard navigation: Welcome → Privacy profile → Power settings + → Done. Forge-Bronze pagination dots, dedicated stage for the + power settings so they are no longer buried in Settings. + - Fourth privacy profile "Roleplay": Privacy-First plus Say and + both emote types, with a 30-day window for Say and a 90-day + window for emotes. Shout, Yell and Novice Network stay out. + - Privacy picker becomes a 2x2 grid. Casual stays the + recommended option with a ★ marker. + - Power-settings step covers Load Previous Session, Filter + Include Previous Sessions, Auto-Tell-Tabs History Preload, + Compact Density, Prettier Timestamps and a built-in theme + picker. All six map to existing Configuration fields — no new + settings introduced. + - Staged commit: the wizard only writes to Config on the Finish + step. Decide-later or X-close at any point leaves the existing + config untouched. + - Inline test hint on the done step: "type /tell + into chat" surfaces the auto-tell-tab spawn mechanism. + - Window starts at 720x480 (was 900x560) and can shrink to + 600x400; Step 1 keeps the fox banner in a folded TreeNode so + the onboarding copy stays primary. + - Existing users get the new wizard surfaced once on first boot + after the update via the new WizardLastShownVersion config + field. Future cycles bump the constant only when the wizard + itself changes shape. + + Under the hood: + + - WizardStateSmokeStep added to /xlperf alongside the FontManager + and ThemeSwitch self-tests. + - Twelve new pure-helper xUnit Facts in the Build Suite cover + all four privacy profile sets and their retention overrides. + + Migration v17 stays (no schema bump). The Configuration grows + one optional string field (WizardLastShownVersion) which + defaults to empty for legacy users. + + Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2). + + --- + **v1.5.1 — FontAtlas Refactor and Hellion Forge Signature (2026-05-17)** Hybrid FontManager refactor plus an embedded provenance mark. @@ -177,42 +227,4 @@ changelog: |- --- - **v1.4.9 — Plugin-Load Render Polish (2026-05-15)** - - Tenth sub-patch of the v1.4.x polish-sweep series. First-frame - render cost drops from ~127 ms median to ~76 ms median, - comfortably under Dalamud's 100 ms HITCH warning threshold. - - - First-frame defer: six non-essential rendering sections inside - ChatLogWindow skip their first Draw and run one frame later - (bottom status bar, channel-name SeString chunks, window bounds - check, v0.6.1 hint banner, autocomplete, input-preview - calculation). User-visible delay is ~17 ms at 60 fps, hidden - inside the post-reload font-atlas build window. - - Slash-command centralisation: /hellion, /hellionView, - /hellionSeString and /hellionDebugger are registered in - LoadAsync instead of inside the corresponding window - constructors. The plugin-manager Open and configuration buttons - hang on the same path. - - Plugin-load profiling logs stay on at Information level - (MessageStore connect/migrate, FilterAllTabs, auto-translate - warmup) as a regression tripwire — a future load past 100 ms - will show up in /xllog without a Debug filter. - - ChatTwo IPC compatibility layer: HellionChat now mirrors - ChatTwo's full IPC surface (GetChatInputState, - ChatInputStateChanged, Register, Unregister, Available, - Invoke) under the ChatTwo.* namespace in addition to our - existing HellionChat.* provider gates. Third-party - integrations that historically only subscribe to ChatTwo's - IPC — for example Artisan's and AllaganTools' context-menu - hooks — keep working without requiring a code change on their - side. Conflict detection prevents ChatTwo from loading in - parallel with HellionChat, so there is no slot-collision risk - at runtime. - - Migration v17 stays (no schema bump). - - Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2). - - --- - Full history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases diff --git a/README.md b/README.md index fbd9f71..67190f8 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Build](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/actions/workflows/build.yml/badge.svg?branch=main)](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/actions/workflows/build.yml) [![License: EUPL-1.2](https://img.shields.io/badge/License-EUPL--1.2-blue.svg)](LICENSE) -[![Latest release](https://img.shields.io/badge/release-v1.5.1-brightgreen)](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/latest) +[![Latest release](https://img.shields.io/badge/release-v1.5.2-brightgreen)](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/latest) [![Dalamud API](https://img.shields.io/badge/Dalamud-API_15-purple)](https://github.com/goatcorp/Dalamud) [![.NET](https://img.shields.io/badge/.NET-10.0-512BD4)](https://dotnet.microsoft.com/) [![FFXIV](https://img.shields.io/badge/FFXIV-Dawntrail-c3a37f)](https://www.finalfantasyxiv.com/) @@ -11,7 +11,7 @@ Hellion Forge

-**Version 1.5.1** — Privacy-first chat plugin for FINAL FANTASY XIV / Dalamud, built on +**Version 1.5.2** — Privacy-first chat plugin for FINAL FANTASY XIV / Dalamud, built on [Chat 2](https://github.com/Infiziert90/ChatTwo) (EUPL-1.2). Hellion Chat is a privacy-first plugin built on the Chat 2 foundation. The majority of the engine @@ -299,6 +299,22 @@ An optional submission to the Dalamud main plugin repo (in addition to the custo ## Project Status +**Version 1.5.2** — First-Run Wizard Rework. The single-page wizard becomes a four-step +staged-commit flow (Welcome → Privacy → Power Settings → Done). The privacy picker becomes a 2×2 +grid with a fourth profile "Roleplay" that extends Privacy-First with `Say` and both emote types +under a 30-/90-day retention window. A power-settings stage surfaces six previously-hidden +`Configuration` defaults in one place without introducing any new settings. The wizard window +shrinks to 720×480 default (was 900×560, MinimumSize 600×400) after smoke feedback and Step 1 +keeps the fox banner in a folded TreeNode so the onboarding copy stays primary. Existing v1.5.1 +users see the new flow once on first v1.5.2 boot via a new `WizardLastShownVersion` config marker. +Under the hood: a `WizardStateSmokeStep` joins `/xlperf`, the Build Suite gains twelve pure-helper +xUnit Facts pinning all four privacy profile sets and the new Roleplay retention overrides. +Migration v17 stays — `Configuration` only grows one optional string field. + +--- + +### Project status (pre-v1.5.2, kept for context) + **Version 1.5.1** — FontAtlas Refactor and Hellion Forge Signature. The FontManager moves from the inherited Chat 2 anti-pattern (null! fields + a separate BuildFonts method) to a hybrid model where the game fonts and FontAwesome are init-only handles and only the user-configurable delegate fonts @@ -318,10 +334,6 @@ defer their font-atlas build to land at ~7 ms; Chat 2 + HellionChat were ~75 ms) cost lives in the UiBuilder first-frame render path, not in the atlas build. A first-frame render investigation is reserved for a later cycle. ---- - -### Project status (pre-v1.5.1, kept for context) - **Version 1.5.0** — DI Foundation and Service Refactor. Major architecture cycle: the plugin bootstrap moves to a generic-host DI container (`Microsoft.Extensions.Hosting` + `IServiceCollection`) modelled on Lightless Sync. All 18 instance-class services migrate from a diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 5a3c273..9c7f38b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -11,6 +11,53 @@ releases as an overview and links to the release pages for details. --- +## Hellion Chat 1.5.2 — First-Run Wizard Rework (2026-05-18) + +UX patch. The single-page first-run wizard becomes a four-step staged-commit flow, the privacy +profile catalogue gains a fourth entry "Roleplay", and a new power-settings stage surfaces six +previously-hidden Configuration defaults. Existing v1.5.1 users see the new wizard once on first +v1.5.2 boot via a new `WizardLastShownVersion` config marker. + +User-visible: + +- Wizard layout: Welcome → Privacy profile → Power settings → Done. Forge-Bronze pagination dots, + per-step Back / Decide later / Next footer. Decide-later and X-close both leave the existing + config untouched; only the Finish ✓ click commits pending choices. +- Fourth privacy profile "Roleplay": Privacy-First whitelist plus `Say` and both emote types, with a + 30-day retention window for `Say` and 90 days for the two emote channels. `Shout`, `Yell` and + `NoviceNetwork` stay out — public-distance noise from strangers is not story content. +- Privacy picker becomes a 2×2 grid. Casual stays the recommended option with a ★ marker. +- Power-settings stage surfaces six existing `Configuration` fields in one place: Load Previous + Session, Filter Include Previous Sessions, Auto-Tell-Tabs History Preload, Compact Density, + Prettier Timestamps, plus a built-in theme picker. No new settings are introduced — the stage just + collects what was previously buried in Settings → Privacy / Chat / Data Management / Optik. +- Inline test hint on the done stage: `type /tell into chat` surfaces the auto-tell-tab + spawn mechanism for new users. +- Wizard window starts at 720×480 (was 900×560) and can shrink to 600×400. Step 1 wraps the fox + banner in a collapsible TreeNode, folded by default — onboarding copy stays primary. +- Existing v1.5.1 users get the new wizard surfaced once on first v1.5.2 boot. A new + `WizardLastShownVersion` config field tracks the most recent version whose wizard was shown; + Plugin.LoadAsync resets `FirstRunCompleted` once when the constant `1.5.2` doesn't match. + +Under the hood: + +- `WizardStateSmokeStep` registered with `/xlperf`. Variant 1 walks the four steps with empty + pending state to pin the no-op CommitPending path. Variant 2 picks Roleplay on Step 2, skips + Step 3, commits, and asserts `LoadPreviousSession` / `FilterIncludePreviousSessions` stayed on + their pre-test value — pinning the null-semantics contract. The step snapshots six privacy / + retention fields before Variant 2 and `CleanUp()` restores them, so back-to-back runs don't drift + the active profile. +- Twelve pure-helper xUnit Facts in the Build Suite (`Privacy/PrivacyDefaultsTests.cs`) cover all + four profile whitelists plus the new Roleplay retention overrides. +- `Configuration` grows one optional string field `WizardLastShownVersion` (default empty). No + schema bump — migration v17 still applies. + +Based on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2). EUPL-1.2. + +[Full release notes on the Gitea release page.](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/tag/v1.5.2) + +--- + ## Hellion Chat 1.5.1 — FontAtlas Refactor and Hellion Forge Signature (2026-05-17) Hybrid FontManager refactor plus an embedded Hellion Forge provenance mark. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 4e5cc37..23cb108 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -10,14 +10,33 @@ be a poor fit for the plugin's privacy-first scope during brainstorming. --- -## Next Cycle (v1.5.2) +## Next Cycle (v1.5.3) -**First-Run-Wizard rework with curated defaults beyond the three privacy profiles.** Jin's discovery -in v1.4.10 surfaced the wizard's three-card layout as too thin — power users want richer presets out -of the box. After that, FR localisation (Hezcal native-speaker review confirmed), then the Plugin -Integrations Wave 2-6 (Context-Menu, NotificationMaster, Moodles, ExtraChat, XIVIM Quick-DM). The -UiBuilder first-frame HITCH investigation that v1.5.1 surfaced sits as a separate spike near the -Wine/Linux scroll-rubber-band investigation at the tail. +**French localisation.** Strings from `Resources/HellionStrings.resx` get a FR translation pass +(DeepL first draft), then Hezcal native-speaker review before release. After that, the Plugin +Integrations Wave 2-6 (Context-Menu, NotificationMaster, Moodles, ExtraChat, XIVIM Quick-DM) and the +UiBuilder first-frame HITCH investigation that v1.5.1 surfaced are queued behind it, alongside the +Wine/Linux scroll-rubber-band spike at the tail. + +--- + +## v1.5.2 — First-Run Wizard Rework (released 2026-05-18) + +Multi-step wizard replacement: Welcome → Privacy → Power Settings → Done with staged-commit so +Decide-later or X-close at any point leaves the existing config untouched. New fourth privacy +profile "Roleplay" extends Privacy-First with `Say` and both emote types under a 30-/90-day +retention window. Privacy picker becomes a 2×2 grid; Casual keeps the ★ recommended marker. A new +power-settings stage surfaces six previously-hidden `Configuration` fields (Load Previous Session, +Filter Include Previous Sessions, Auto-Tell-Tabs History Preload, Compact Density, Prettier +Timestamps, built-in theme picker) without introducing any new fields. + +Window default size shrinks from 900×560 to 720×480 (MinimumSize 600×400) and Step 1 wraps the fox +banner in a folded TreeNode after smoke feedback. Existing v1.5.1 users see the new wizard once on +first v1.5.2 boot via a new `WizardLastShownVersion` config marker. + +Under the hood: `WizardStateSmokeStep` joins the `/xlperf` lineup, the Build Suite gains twelve +pure-helper xUnit Facts pinning all four privacy profile sets and the new Roleplay retention +overrides. Migration v17 stays — `Configuration` only grows one optional string field. --- diff --git a/repo.json b/repo.json index 287821d..34cdb1d 100644 --- a/repo.json +++ b/repo.json @@ -3,8 +3,8 @@ "Author": "Jon Kazama (Hellion Forge)", "Name": "Hellion Chat", "InternalName": "HellionChat", - "AssemblyVersion": "1.5.1.0", - "Description": "A Hellion Forge plugin — privacy-focused chat replacement for FINAL FANTASY XIV, built for EU, US and JP data rules.\n\nBy default only your own conversations are stored. Public chat, NPC dialogue, system messages and battle logs are discarded at the storage layer unless you opt in. Retention windows are configurable per channel, history can be wiped retroactively, and everything can be exported on demand.\n\nFeatures:\n- Channel whitelist with a Privacy-First default\n- Per-channel retention with a daily background sweep\n- Retroactive cleanup with preview and Ctrl+Shift confirm\n- Export to Markdown, JSON or CSV\n- First-run wizard with three profiles: Privacy-First, Casual, Full History\n- Bilingual UI (EN/DE) with live language switching\n- Own config and database — no shared state with other plugins\n\nBased on Chat 2 by Infi and Anna (EUPL-1.2).\nSupport: https://discord.gg/X9V7Kcv5gR", + "AssemblyVersion": "1.5.2.0", + "Description": "A Hellion Forge plugin \u2014 privacy-focused chat replacement for FINAL FANTASY XIV, built for EU, US and JP data rules.\n\nBy default only your own conversations are stored. Public chat, NPC dialogue, system messages and battle logs are discarded at the storage layer unless you opt in. Retention windows are configurable per channel, history can be wiped retroactively, and everything can be exported on demand.\n\nFeatures:\n- Channel whitelist with a Privacy-First default\n- Per-channel retention with a daily background sweep\n- Retroactive cleanup with preview and Ctrl+Shift confirm\n- Export to Markdown, JSON or CSV\n- First-run wizard with three profiles: Privacy-First, Casual, Full History\n- Bilingual UI (EN/DE) with live language switching\n- Own config and database \u2014 no shared state with other plugins\n\nBased on Chat 2 by Infi and Anna (EUPL-1.2).\nSupport: https://discord.gg/X9V7Kcv5gR", "ApplicableVersion": "any", "RepoUrl": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat", "Tags": ["Social", "UI", "Chat", "Replacement", "Privacy"], @@ -14,12 +14,12 @@ "CanUnloadAsync": false, "LoadPriority": 0, "Punchline": "A Hellion Forge plugin. Privacy-first chat for FFXIV, built to stay out of your way.", - "Changelog": "**v1.5.1 \u2014 FontAtlas Refactor and Hellion Forge Signature (2026-05-17)**\n\nHybrid FontManager refactor plus an embedded provenance mark.\n\nWhat changes under the hood:\n\n- FontManager handle creation moves into the ctor inside a single\n atlas.SuppressAutoRebuild() block. The font atlas now builds\n once per plugin load instead of four to five times \u2014 less CPU\n and GPU pressure in the first seconds after a reload, less\n atlas texture memory churn.\n- Hybrid property model: Axis, AxisItalic and FontAwesome become\n init-only handles. RegularFont and ItalicFont stay mutable\n because the eight font settings still need to replace them at\n runtime \u2014 that path is funnelled through RebuildDelegateFonts()\n now and runs without a plugin reload.\n- FontAwesome reuses Dalamud's UiBuilder.IconFontFixedWidthHandle\n instead of building its own atlas slot. One delegate-build\n step less in the ctor.\n- BuildFontsAsync and BuildFonts are removed; the live mutation\n path is RebuildDelegateFonts() now.\n- Two FontManager self-test steps registered with /xlperf: ctor\n smoke (every handle non-null after Phase-1 resolve, no atlas\n load-exception) and push smoke (Push() returns without throwing).\n\nHonorific full-gradient port (originally the v1.5.1 main item)\nwas dropped: Honorific 3.2 exposes no IPC for the rendered\ngradient frame, and an in-plugin port of the colour palette was\ndeclined. The integration stays at the v1.4.7 glow-only shape.\n\nUser-visible:\n\n- Hellion Forge signature: a small fox-head ASCII silhouette is\n emitted to /xllog on every plugin load, and a full fox banner\n with \"Hellion Forge\" set inside the body is available as a\n folded TreeNode in the First-Run Wizard and Settings ->\n Information tab. Drawn by Julia Moon, embedded in the plugin DLL.\n- No settings changes, no migration. v17 stays.\n\nNote on performance: the cross-plugin baseline target from\nv1.5.0 (matching Lightless and XIVInstantMessenger at ~7 ms\nHITCH) did not land this cycle. HITCH stays around 80 ms because\nthe cost is in the UiBuilder first-frame render path, not in the\natlas build (which this cycle did reduce from 4-5 builds per\nload to 1). A first-frame render investigation is reserved for\na later cycle.\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.5.0 \u2014 DI Foundation and Service Refactor (2026-05-17)**\n\nMajor architecture cycle. The plugin bootstrap moves to a\ngeneric-host DI container (Microsoft.Extensions.Hosting +\nIServiceCollection) modelled on Lightless Sync. Service logging\nmoves from a static Plugin.LogProxy locator to typed\nMicrosoft.Extensions.Logging.ILogger via constructor injection,\nbridged over Dalamud's IPluginLog by a custom DalamudLogger trio.\n\nWhat changes under the hood:\n\n- 18 instance-class services migrate to ILogger via constructor\n injection across four slices: data layer (MessageStore,\n MessageManager, AutoTellTabsService), IPC and integrations\n (HonorificService, IpcManager, TypingIpc, ExtraChat, the three\n GameFunctions classes), UI window layer (ChatLogWindow,\n DbViewer, Popout, three settings tabs), and root (Commands,\n ThemeRegistry, PayloadHandler).\n- Plugin.LogProxy stays in place for the eight buckets ctor\n injection cannot reach: static helpers (EmoteCache,\n AutoTranslate, MemoryUtil, WrapperUtil), Dalamud-reflected\n types (Configuration), the Message data class, and instance\n classes that only log from static methods (FontManager, one\n GameFunctions site).\n- Plugin.cs finishes at 1012 lines \u2014 virtually identical to the\n pre-cycle 1013. The new Phase-1 host build and Plugin.X bridge\n wiring trade out exactly the service and window allocations\n that previously lived in LoadAsync.\n- Cross-plugin baseline confirms no performance penalty against\n Chat 2: HellionChat first-frame HITCH 77 ms median, Chat 2\n 74 ms median. Lightless and XIVInstantMessenger sit around\n 7 ms by deferring their font-atlas build past Finished\n loading \u2014 that pattern is the v1.5.1 follow-up.\n\nUser-visible:\n\n- Slash-command insert fix: pasting a slash command into the\n chat input (Friend List \"/tell\" action, plugin-driven inserts\n from Artisan, AllaganTools etc.) now replaces the existing\n input instead of concatenating. Cherry-picked from ChatTwo\n upstream ee7768ac with namespace adaptation.\n\nMigration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.10 \u2014 Symbol-Picker and Tell-History Fix (2026-05-16)**\n\nEleventh and final sub-patch of the v1.4.x polish-sweep series.\nSymbol picker for the chat input, a tell-history reload fix for\nusers with many active partners, and a closing cleanup sweep\nbefore v1.5.0 picks up the DI-container adoption.\n\n- Symbol picker: a small smile-icon button left of the channel\n indicator opens a popup with two tabs. The first lists all 161\n FFXIV PUA glyphs (Dalamud's SeIconChar enum); the second\n carries 97 server-verified BMP symbols (latin marks, currency,\n the full Greek alphabet, geometric shapes, suits, notes) \u2014\n every one of them round-tripped through /echo and /say in a\n four-round probe so the in-channel render matches what the\n picker shows. Click drops the glyph at the caret, multi-insert\n keeps the popup open, and a recent-used strip floats the last\n sixteen picks across both tabs. Toggle in Settings \u2192 Chat \u2192\n Message behaviour, default on.\n- Pinned auto-tell tabs reload their full history again: a\n hidden 500-row scan cap in PreloadHistory used to override the\n user-configurable AutoTellTabsHistoryPreload setting, so\n less-frequent pinned partners (rare /tell sessions in an\n otherwise busy week) lost their backlog. The cap is removed;\n the (Receiver, Date) index keeps SQL fast, the client-side\n loop still respects your setting as the upper bound.\n- Slash-command teardown: /hellion, /hellionView,\n /hellionDebugger (and #if DEBUG /hellionSeString) wrappers are\n now cached as private fields. Plugin teardown detaches the\n live registration instead of re-Register'ing with identical\n args \u2014 closes a latent maintenance hazard from v1.4.9.\n- v1.4.x polish-sweep wraps up here. The ImGuiListClipper render\n refactor that was on the v1.4.10 reserve list got dropped\n after cross-platform smoke showed the scroll rubber-band is a\n Wine / Linux render-pipeline quirk, not universal \u2014 Windows\n users never saw it. It will get its own platform-targeted\n spike in a later patch. Next major cycle is v1.5.0 with the\n DI-container adoption (Microsoft.Extensions.Hosting +\n ILogger) modelled on Lightless.\n- Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.9 \u2014 Plugin-Load Render Polish (2026-05-15)**\n\nTenth sub-patch of the v1.4.x polish-sweep series. First-frame\nrender cost drops from ~127 ms median to ~76 ms median,\ncomfortably under Dalamud's 100 ms HITCH warning threshold.\n\n- First-frame defer: six non-essential rendering sections inside\n ChatLogWindow skip their first Draw and run one frame later\n (bottom status bar, channel-name SeString chunks, window bounds\n check, v0.6.1 hint banner, autocomplete, input-preview\n calculation). User-visible delay is ~17 ms at 60 fps, hidden\n inside the post-reload font-atlas build window.\n- Slash-command centralisation: /hellion, /hellionView,\n /hellionSeString and /hellionDebugger are registered in\n LoadAsync instead of inside the corresponding window\n constructors. The plugin-manager Open and configuration buttons\n hang on the same path.\n- Plugin-load profiling logs stay on at Information level\n (MessageStore connect/migrate, FilterAllTabs, auto-translate\n warmup) as a regression tripwire \u2014 a future load past 100 ms\n will show up in /xllog without a Debug filter.\n- ChatTwo IPC compatibility layer: HellionChat now mirrors\n ChatTwo's full IPC surface (GetChatInputState,\n ChatInputStateChanged, Register, Unregister, Available,\n Invoke) under the ChatTwo.* namespace in addition to our\n existing HellionChat.* provider gates. Third-party\n integrations that historically only subscribe to ChatTwo's\n IPC \u2014 for example Artisan's and AllaganTools' context-menu\n hooks \u2014 keep working without requiring a code change on their\n side. Conflict detection prevents ChatTwo from loading in\n parallel with HellionChat, so there is no slot-collision risk\n at runtime.\n- Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\nFull history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases", + "Changelog": "**v1.5.2 \u2014 First-Run Wizard Rework (2026-05-18)**\n\nUX patch. The first-run wizard becomes a four-step flow with a\nnew Roleplay privacy profile and a power-settings step that\nsurfaces previously-hidden defaults. Existing v1.5.1 users see\nthe new wizard once on first v1.5.2 boot.\n\nWhat changes user-visible:\n\n- Wizard navigation: Welcome \u2192 Privacy profile \u2192 Power settings\n \u2192 Done. Forge-Bronze pagination dots, dedicated stage for the\n power settings so they are no longer buried in Settings.\n- Fourth privacy profile \"Roleplay\": Privacy-First plus Say and\n both emote types, with a 30-day window for Say and a 90-day\n window for emotes. Shout, Yell and Novice Network stay out.\n- Privacy picker becomes a 2x2 grid. Casual stays the\n recommended option with a \u2605 marker.\n- Power-settings step covers Load Previous Session, Filter\n Include Previous Sessions, Auto-Tell-Tabs History Preload,\n Compact Density, Prettier Timestamps and a built-in theme\n picker. All six map to existing Configuration fields \u2014 no new\n settings introduced.\n- Staged commit: the wizard only writes to Config on the Finish\n step. Decide-later or X-close at any point leaves the existing\n config untouched.\n- Inline test hint on the done step: \"type /tell \n into chat\" surfaces the auto-tell-tab spawn mechanism.\n- Window starts at 720x480 (was 900x560) and can shrink to\n 600x400; Step 1 keeps the fox banner in a folded TreeNode so\n the onboarding copy stays primary.\n- Existing users get the new wizard surfaced once on first boot\n after the update via the new WizardLastShownVersion config\n field. Future cycles bump the constant only when the wizard\n itself changes shape.\n\nUnder the hood:\n\n- WizardStateSmokeStep added to /xlperf alongside the FontManager\n and ThemeSwitch self-tests.\n- Twelve new pure-helper xUnit Facts in the Build Suite cover\n all four privacy profile sets and their retention overrides.\n\nMigration v17 stays (no schema bump). The Configuration grows\none optional string field (WizardLastShownVersion) which\ndefaults to empty for legacy users.\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.5.1 \u2014 FontAtlas Refactor and Hellion Forge Signature (2026-05-17)**\n\nHybrid FontManager refactor plus an embedded provenance mark.\n\nWhat changes under the hood:\n\n- FontManager handle creation moves into the ctor inside a single\n atlas.SuppressAutoRebuild() block. The font atlas now builds once\n per plugin load instead of four to five times \u2014 less CPU and GPU\n pressure in the first seconds after a reload, less atlas texture\n memory churn.\n- Hybrid property model: Axis, AxisItalic and FontAwesome become\n init-only handles. RegularFont and ItalicFont stay mutable because\n the eight font settings still need to replace them at runtime \u2014\n that path is funnelled through RebuildDelegateFonts() now and\n runs without a plugin reload.\n- FontAwesome reuses Dalamud's UiBuilder.IconFontFixedWidthHandle\n instead of building its own atlas slot. One delegate-build step\n less in the ctor.\n- BuildFontsAsync and BuildFonts are removed; the live mutation\n path is RebuildDelegateFonts() now.\n- Two FontManager self-test steps registered with /xlperf: ctor\n smoke (every handle non-null after Phase-1 resolve, no atlas\n load-exception) and push smoke (Push() returns without throwing).\n\nHonorific full-gradient port (originally the v1.5.1 main item) was\ndropped: Honorific 3.2 exposes no IPC for the rendered gradient\nframe, and an in-plugin port of the colour palette was declined.\nThe integration stays at the v1.4.7 glow-only shape.\n\nUser-visible:\n\n- Hellion Forge signature: a small fox-head ASCII silhouette is\n emitted to /xllog on every plugin load, and a full fox banner\n with \"Hellion Forge\" set inside the body is available as a\n folded TreeNode in the First-Run Wizard and Settings ->\n Information tab. Drawn by Julia Moon, embedded in the plugin DLL.\n- No settings changes, no migration. v17 stays.\n\nNote on performance: the cross-plugin baseline target from v1.5.0\n(matching Lightless and XIVInstantMessenger at ~7 ms HITCH) did\nnot land this cycle. HITCH stays around 80 ms because the cost is\nin the UiBuilder first-frame render path, not in the atlas build\n(which this cycle did reduce from 4-5 builds per load to 1). A\nfirst-frame render investigation is reserved for a later cycle.\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.5.0 \u2014 DI Foundation and Service Refactor (2026-05-17)**\n\nMajor architecture cycle. The plugin bootstrap moves to a\ngeneric-host DI container (Microsoft.Extensions.Hosting +\nIServiceCollection) modelled on Lightless Sync. Service logging\nmoves from a static Plugin.LogProxy locator to typed\nMicrosoft.Extensions.Logging.ILogger via constructor injection,\nbridged over Dalamud's IPluginLog by a custom DalamudLogger trio.\n\nWhat changes under the hood:\n\n- 18 instance-class services migrate to ILogger via constructor\n injection across four slices: data layer (MessageStore,\n MessageManager, AutoTellTabsService), IPC and integrations\n (HonorificService, IpcManager, TypingIpc, ExtraChat, the three\n GameFunctions classes), UI window layer (ChatLogWindow,\n DbViewer, Popout, three settings tabs), and root (Commands,\n ThemeRegistry, PayloadHandler).\n- Plugin.LogProxy stays in place for the eight buckets ctor\n injection cannot reach: static helpers (EmoteCache,\n AutoTranslate, MemoryUtil, WrapperUtil), Dalamud-reflected\n types (Configuration), the Message data class, and instance\n classes that only log from static methods (FontManager, one\n GameFunctions site).\n- Plugin.cs finishes at 1012 lines \u2014 virtually identical to the\n pre-cycle 1013. The new Phase-1 host build and Plugin.X bridge\n wiring trade out exactly the service and window allocations\n that previously lived in LoadAsync.\n- Cross-plugin baseline confirms no performance penalty against\n Chat 2: HellionChat first-frame HITCH 77 ms median, Chat 2\n 74 ms median. Lightless and XIVInstantMessenger sit around\n 7 ms by deferring their font-atlas build past Finished\n loading \u2014 that pattern is the v1.5.1 follow-up.\n\nUser-visible:\n\n- Slash-command insert fix: pasting a slash command into the\n chat input (Friend List \"/tell\" action, plugin-driven inserts\n from Artisan, AllaganTools etc.) now replaces the existing\n input instead of concatenating. Cherry-picked from ChatTwo\n upstream ee7768ac with namespace adaptation.\n\nMigration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\n**v1.4.10 \u2014 Symbol-Picker and Tell-History Fix (2026-05-16)**\n\nEleventh and final sub-patch of the v1.4.x polish-sweep series.\nSymbol picker for the chat input, a tell-history reload fix for\nusers with many active partners, and a closing cleanup sweep\nbefore v1.5.0 picks up the DI-container adoption.\n\n- Symbol picker: a small smile-icon button left of the channel\n indicator opens a popup with two tabs. The first lists all 161\n FFXIV PUA glyphs (Dalamud's SeIconChar enum); the second\n carries 97 server-verified BMP symbols (latin marks, currency,\n the full Greek alphabet, geometric shapes, suits, notes) \u2014\n every one of them round-tripped through /echo and /say in a\n four-round probe so the in-channel render matches what the\n picker shows. Click drops the glyph at the caret, multi-insert\n keeps the popup open, and a recent-used strip floats the last\n sixteen picks across both tabs. Toggle in Settings \u2192 Chat \u2192\n Message behaviour, default on.\n- Pinned auto-tell tabs reload their full history again: a\n hidden 500-row scan cap in PreloadHistory used to override the\n user-configurable AutoTellTabsHistoryPreload setting, so\n less-frequent pinned partners (rare /tell sessions in an\n otherwise busy week) lost their backlog. The cap is removed;\n the (Receiver, Date) index keeps SQL fast, the client-side\n loop still respects your setting as the upper bound.\n- Slash-command teardown: /hellion, /hellionView,\n /hellionDebugger (and #if DEBUG /hellionSeString) wrappers are\n now cached as private fields. Plugin teardown detaches the\n live registration instead of re-Register'ing with identical\n args \u2014 closes a latent maintenance hazard from v1.4.9.\n- v1.4.x polish-sweep wraps up here. The ImGuiListClipper render\n refactor that was on the v1.4.10 reserve list got dropped\n after cross-platform smoke showed the scroll rubber-band is a\n Wine / Linux render-pipeline quirk, not universal \u2014 Windows\n users never saw it. It will get its own platform-targeted\n spike in a later patch. Next major cycle is v1.5.0 with the\n DI-container adoption (Microsoft.Extensions.Hosting +\n ILogger) modelled on Lightless.\n- Migration v17 stays (no schema bump).\n\nBased on Chat 2 1.35.3 (upstream Infiziert90/ChatTwo, EUPL-1.2).\n\n---\n\nFull history: https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases", "AcceptsFeedback": true, - "DownloadLinkInstall": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.5.1/latest.zip", - "DownloadLinkUpdate": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.5.1/latest.zip", - "DownloadLinkTesting": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.5.1/latest.zip", - "TestingAssemblyVersion": "1.5.1.0", + "DownloadLinkInstall": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.5.2/latest.zip", + "DownloadLinkUpdate": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.5.2/latest.zip", + "DownloadLinkTesting": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/releases/download/v1.5.2/latest.zip", + "TestingAssemblyVersion": "1.5.2.0", "IconUrl": "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/raw/branch/main/HellionChat/images/icon.png", "ImageUrls": [ "https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/raw/branch/main/HellionChat/images/chatWindow.png",