docs: unify documentation and streamline code comments

- Translated project documentation (LEARNING-JOURNEY, CONTRIBUTORS, AI_DISCLOSURE) to English for better accessibility.
- Standardized internal code documentation by converting XML-doc blocks to standard comment format.
- Cleaned up inline comments and removed redundant versioning metadata across the codebase.
- Refactored non-functional text elements to improve readability and maintain a consistent style.
This commit is contained in:
2026-05-11 00:52:15 +02:00
parent a37882893e
commit c4c85cf4b8
33 changed files with 666 additions and 1364 deletions
+12 -9
View File
@@ -56,15 +56,18 @@ Both are good projects. Use what fits you best.
## Tooling
| Tool | Purpose |
| ----------------------------------------------------- | ------------------------------------------------------------- |
| [Claude](https://claude.ai) (Anthropic) | Pair-level AI assistance via Claude Code CLI |
| [VS Code](https://code.visualstudio.com) + C# Dev Kit | Primary IDE |
| Dedicated Windows 11 VM | Build and in-game test environment (Dalamud requires Windows) |
| [dalamud.dev](https://dalamud.dev) | Dalamud API reference |
| [Microsoft Learn](https://learn.microsoft.com) | .NET and C# documentation |
| [Context7](https://context7.com) | Up-to-date library docs for Claude context |
| [Stack Overflow](https://stackoverflow.com) | General C# and .NET problem-solving |
| Tool | Purpose |
| ----------------------------------------------------- | ------------------------------------------------------------------- |
| [Claude](https://claude.ai) (Anthropic) | Pair-level AI assistance via Claude Code CLI |
| [VS Code](https://code.visualstudio.com) + C# Dev Kit | Primary IDE |
| Dedicated Windows 11 VM | Build and in-game test environment (Dalamud requires Windows) |
| [dalamud.dev](https://dalamud.dev) | Dalamud API reference |
| [Microsoft Learn](https://learn.microsoft.com) | .NET and C# documentation |
| [Context7](https://context7.com) | Up-to-date library docs for Claude context |
| [Stack Overflow](https://stackoverflow.com) | General C# and .NET problem-solving |
| Custom build test suite | Pattern-based integration tests written from scratch, drawing on |
| | conventions from Lightless, Umbra and other standard FFXIV plugins. |
| | Not publicly available. Yet. |
## Contact
+49 -53
View File
@@ -1,87 +1,83 @@
# Contributors — Hellion Chat
Hellion Chat ist von der Code-Seite ein Ein-Personen-Projekt. Aber ohne die Leute auf dieser Seite gäbe es weder die
Bug-Fixes noch die UX-Verbesserungen, die seit den frühen Versionen reingelaufen sind. Jeder Eintrag hier hat das Plugin
konkret besser gemacht.
Hellion Chat is a one-person project on the code side. But without the people on this page, the bug fixes and UX
improvements that have landed since the early versions would not exist. Every entry here has made the plugin concretely
better.
Die Anerkennung an die Upstream-Autoren von Chat 2 (Infi und Anna) liegt bewusst in [`../NOTICE.md`](../NOTICE.md),
nicht hier. Diese Datei deckt explizit Beiträge zur Hellion-Chat-Seite ab.
Attribution for the upstream Chat 2 authors (Infi and Anna) is intentionally in [`../NOTICE.md`](../NOTICE.md), not
here. This file covers contributions to the Hellion Chat side specifically.
---
## Entwicklung
## Development
### JonKazama (Florian Wathling) — Maintainer
Hellion Chat ist mein erstes FFXIV-Plugin und mein erstes größeres C#-/Dalamud-Projekt. Mein beruflicher Hintergrund ist
Webentwicklung (Next.js, React, TypeScript, Prisma). Plugin-Entwicklung in einer fremden Codebase, ImGui,
FFXIV-Game-Hooks und der gesamte Dalamud-Stack waren Neuland.
Hellion Chat is my first FFXIV plugin and my first larger C#/Dalamud project. My professional background is web
development (Next.js, React, TypeScript, Prisma). Plugin development in an unfamiliar codebase, ImGui, FFXIV game hooks
and the entire Dalamud stack were new territory.
Privacy-First-Defaults, Per-Channel-Retention, Auto-Tell-Tabs, Pop-Out-Input, ChatColours-Presets, Hellion-Theme plus
Exo-2-Font und der v1.0.0-Standalone-Cut sind die Hellion-spezifischen Surface-Areas, die ich auf das Chat-2-Fundament
aufgebaut habe. Die Lern-Geschichte dahinter steht in [`LEARNING-JOURNEY.md`](LEARNING-JOURNEY.md).
Privacy-first defaults, per-channel retention, Auto-Tell-Tabs, pop-out input, ChatColours presets, the Hellion theme
plus Exo 2 font, and the v1.0.0 standalone cut are the Hellion-specific surface areas I built on top of the Chat 2
foundation. The learning story behind that is in [`LEARNING-JOURNEY.md`](LEARNING-JOURNEY.md).
Hellion Chat ist Teil von [Hellion Online Media](https://hellion-media.de).
Hellion Chat is part of [Hellion Online Media](https://hellion-media.de).
---
## Tester
## Testers
Eine kurze Notiz vorneweg: Ich teste das Plugin nicht allein. Die Leute hier haben mir Bugs gemeldet, bevor sie bei mehr
Nutzern aufgeschlagen wären. Sie haben UX-Probleme angesprochen, die ich blind nicht mehr gesehen habe. Und sie haben
Feature-Wünsche eingebracht, die das Plugin in Richtungen geschoben haben, in die ich von alleine nicht gegangen wäre.
Das ist nicht selbstverständlich. Externe Tester sind ihre Zeit wert.
A quick note: I do not test this plugin alone. The people listed here reported bugs before they hit more users, raised
UX problems I had gone blind to, and brought in feature requests that pushed the plugin in directions I would not have
gone on my own. That is not a given. External testers are worth their time.
### Carl Beleandis (Carla) — Beta-Tester
### Carl Beleandis (Carla) — Beta Tester
Carl testet seit der Bootstrap-Phase und hat sowohl die Pop-Out-Mechanik als auch die Theme-Richtung geprägt. Sein
Feedback kommt direkt und ohne Umschweife und das ist genau, was ich beim Testen brauche.
Carl has been testing since the bootstrap phase and has shaped both the pop-out mechanics and the theme direction.
Feedback comes direct and without detours, which is exactly what I need when testing.
Konkrete Beiträge:
Concrete contributions:
- **Pop-Out-Discoverability** — der Hinweis, dass Pop-Outs nur per Rechtsklick erreichbar waren, hat den Header-Button
und den einmaligen Hint-Banner in v0.6.1 ausgelöst. Ich kannte den Rechtsklick-Pfad blind, deshalb hatte ich nicht
mehr gesehen, dass neue Nutzer die Funktion gar nicht finden.
- **/tell-Pop-Out-Mode** — der Wunsch, /tell-Tabs direkt als Pop-Out zu öffnen statt über den Tab-Umweg, ist in v0.6.1
als opt-in Settings-Toggle gelandet. Bonus: Bei der Implementation ist ein alter Ghost-Window-Bug aufgefallen
(LRU-Drop ließ Pop-Out-Fenster als Geister stehen), der gleich mit gefixt wurde.
- **Theme-Varianten mit Helligkeits-Abstufungen** — der Wunsch nach einer Grün-Familie hat mein Verständnis von "ein
Theme = eine Farbe" auf "Theme-Familien mit Stimmungs-Varianten" verschoben. Steht in der [Roadmap](ROADMAP.md) für
einen späteren Cycle.
- **Pop-out discoverability** — pointing out that pop-outs were only reachable via right-click triggered the header
button and the one-time hint banner in v0.6.1. I knew the right-click path by heart and had stopped seeing that new
users could not find the feature at all.
- **/tell pop-out mode** — the request to open /tell tabs directly as a pop-out instead of going through the tab sidebar
landed in v0.6.1 as an opt-in settings toggle. Bonus: during implementation an old ghost-window bug surfaced (LRU drop
left pop-out windows as ghosts), which got fixed at the same time.
- **Theme variants with brightness gradations** — the request for a green family shifted my thinking from "one theme =
one colour" to "theme families with mood variants". On the [roadmap](ROADMAP.md) for a later cycle.
### Jin (Jingliu) — Alpha-Tester
### Jin (Jingliu) — Alpha Tester
Jin ist der aktive Tester der ersten Stunde und hat den Pop-Out-Workflow architektonisch in eine andere Richtung
geschoben.
Jin is the active tester from day one and pushed the pop-out workflow architecture in a different direction.
Konkrete Beiträge:
Concrete contributions:
- **Pop-Out-Tab mit Input-Feld** — der Vorschlag, in einem Pop-Out auch tippen zu können (statt nur lesen), hat die
v0.6.0 Pop-Out-Input-Bar ausgelöst. Das war ein größerer Refactor: Der Input-Layer aus `ChatLogWindow` musste so
geöffnet werden, dass er auch in `Popout.cs` lebt, mit unabhängigem Text-Buffer und History-Cursor pro Pop-Out. Hat
den Cycle dominiert, weil das Design erst sauber sein musste, bevor Code passieren konnte.
- **TempTell Persistence** — der Wunsch, /tell-Tabs per Pin-Toggle einen Relog überleben zu lassen, steht in der
[Roadmap](ROADMAP.md) für einen späteren Cycle. Berührt das Tab-System architektonisch und braucht eigenes Design.
- **Pop-out tab with input bar** — the suggestion to be able to type in a pop-out (instead of just reading) triggered
the v0.6.0 pop-out input bar. That was a larger refactor: the input layer from `ChatLogWindow` had to be opened up so
it could also live in `Popout.cs`, with an independent text buffer and history cursor per pop-out. It dominated the
cycle because the design had to be clean before any code could happen.
- **TempTell persistence** — the request for /tell tabs to survive a relog via a pin toggle is on the
[roadmap](ROADMAP.md) for a later cycle. It touches the tab system architecturally and needs its own design work.
---
## Übersetzungen
## Translations
Hellion-eigene UI-Strings werden in `HellionChat/Resources/HellionStrings.<lang>.resx` gepflegt.
Hellion-specific UI strings are maintained in `HellionChat/Resources/HellionStrings.<lang>.resx`.
- **Deutsch (DE):** JonKazama (Native Speaker, Hauptsprache des Projekts)
- **German (DE):** JonKazama (native speaker, primary project language)
Die Upstream-Sprach-Dateien (`Language.<lang>.resx`) sind nicht Teil dieser Datei. Sie werden über das
[Chat-2-Crowdin-Projekt](https://github.com/Infiziert90/ChatTwo) gepflegt; Crowdin-Übersetzer findest du in den
Plugin-Settings unter **Info → "Chat 2 community translators"**.
Upstream language files (`Language.<lang>.resx`) are not covered here. They are maintained via the
[Chat 2 Crowdin project](https://github.com/Infiziert90/ChatTwo); Crowdin translators are listed in the plugin settings
under **Info → "Chat 2 community translators"**.
---
## Wie du beitragen kannst
## How to Contribute
Bug-Reports, Feature-Wünsche und Pull-Requests laufen über
[Gitea Issues](https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/issues). Workflow und Erwartungen stehen
in [`../CONTRIBUTING.md`](../CONTRIBUTING.md), Code of Conduct in [`../CODE_OF_CONDUCT.md`](../CODE_OF_CONDUCT.md).
Bug reports, feature requests and feedback are welcome — the best place to reach me is the Hellion Forge Discord:
[discord.gg/X9V7Kcv5gR](https://discord.gg/X9V7Kcv5gR). Join and ping me in the Hellion Chat channel.
Tester-Pool für neue Versionen läuft über den Hellion-Forge-Discord:
[discord.gg/X9V7Kcv5gR](https://discord.gg/X9V7Kcv5gR). Wer in den Tester-Channel rein will, einfach im Forge melden.
For pull requests and contribution guidelines see [`../CONTRIBUTING.md`](../CONTRIBUTING.md), Code of Conduct in
[`../CODE_OF_CONDUCT.md`](../CODE_OF_CONDUCT.md).
+218 -223
View File
@@ -1,336 +1,331 @@
# Entwicklungsgeschichte und Lernprozess
# Development History and Learning Process
## Hintergrund
## Background
Ich bin Autodidakt. Hellion Chat ist mein erstes FFXIV-Plugin und mein erstes größeres C#-Projekt. Mein beruflicher
Hintergrund ist Webentwicklung (Next.js, React, TypeScript, Prisma, MySQL), also Browser-Welt mit JavaScript-Toolchain.
C# kannte ich vor diesem Projekt nur oberflächlich, ImGui gar nicht, Dalamud nur als Endnutzer über andere Plugins.
I am self-taught. Hellion Chat is my first FFXIV plugin and my first larger C# project. My professional background is
web development (Next.js, React, TypeScript, Prisma, MySQL) — browser world with a JavaScript toolchain. I knew C# only
superficially before this project, ImGui not at all, and Dalamud only as an end user through other plugins.
Wenn ich an einer Stelle nicht weiterkomme, nutze ich AI-Tools wie Claude Code als Pair-Hilfsmittel. Wie das genau
aussieht und welche Klassifikation ich verwende, steht transparent in [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md).
When I get stuck somewhere, I use AI tools like Claude Code as a pair assistant. What that looks like exactly and which
classification I use is documented transparently in [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md).
---
## Warum überhaupt ein Chat-Plugin?
## Why a chat plugin at all?
Hellion Chat soll Chat 2 nicht ersetzen. Chat 2 liefert ein vollständiges Chat-Erlebnis mit kompletter Historie,
Filtern, Suche und Replay. Für die meisten Nutzer ist genau das richtig.
Hellion Chat is not meant to replace Chat 2. Chat 2 delivers a complete chat experience with full history, filters,
search and replay. For most users that is exactly the right thing.
### Zwei Millionen Nachrichten in zwei Jahren
### Two million messages in two years
Mein Wunsch nach einem engeren Default war ehrlich gesagt erstmal persönlich. Nach zwei Jahren mit Chat 2 lag meine
Datenbank bei über zwei Millionen Nachrichten, der Großteil davon /say, /shout und /yell von wildfremden Leuten in
Limsa. Genau diese Daten machen Chat 2's Voll-Historie nützlich, und die meisten Nutzer behalten sie auch gerne. Mein
eigener Geschmack wollte einen kleineren Default. Also habe ich diesen Fork gebaut.
My desire for a tighter default was honestly personal at first. After two years with Chat 2 my database had grown to
over two million messages, the majority of them /say, /shout and /yell from complete strangers in Limsa. That is exactly
what makes Chat 2's full history useful, and most users are happy to keep it. My own preference wanted a smaller
default. So I built this fork.
### Greeter in mehreren Clubs
### Greeter in several clubs
Dazu kam ein zweiter Use-Case: Ich bin in mehreren FFXIV-Clubs als Greeter aktiv. Für die Greeter-Arbeit reicht die
Vanilla-Chat-Oberfläche nicht. Parallel laufende /tell-Gespräche schreiben in einem einzigen Tab durcheinander, und ich
verliere ständig den Faden, wer mir gerade was geschrieben hat. Auto-Tell-Tabs (eines der frühen Hellion-Chat-Features)
ist genau für diesen Workflow entstanden: ein Tab pro Gesprächspartner, automatisch gespawnt, mit manuellem
Greeted-Status. Dass das auch der Privacy-Hygiene gut tut, war ein netter Bonus, nicht der Auslöser.
There was a second use case: I am active as a greeter in several FFXIV clubs. The vanilla chat interface is not enough
for greeter work. Parallel /tell conversations write into a single tab at the same time, and I constantly lose track of
who wrote what. Auto-Tell-Tabs (one of the early Hellion Chat features) came directly from this workflow: one tab per
conversation partner, automatically spawned, with a manual greeted status. The privacy hygiene benefit was a nice bonus,
not the trigger.
### Hellion Online Media
Die Privacy-Defaults sind außerdem eine Position aus meinem Hauptberuf. Hellion Online Media ist mein Einzelunternehmen,
und Datenschutz gegenüber Kunden ist da kein Marketing-Slogan, sondern operativ relevant. Dieser Fork ist die
Plugin-Form derselben Haltung.
The privacy defaults also reflect a position from my main work. Hellion Online Media is my sole proprietorship, and data
protection toward clients is not a marketing slogan there but operationally relevant. This fork is the plugin form of
the same stance.
---
## Warum nicht beim Original mitarbeiten?
## Why not contribute to the original?
Drei Gründe, in absteigender Wichtigkeit.
Three reasons, in descending order of importance.
### Defaults sind nicht verhandelbar, auch nicht meine
### Defaults are not negotiable, including mine
Privacy-First als Standard ist eine Minderheits-Position. Chat 2 bedient zu Recht die breite Masse mit Voll-Historie als
Default. Diese Defaults im Upstream zu ändern wäre falsch gewesen. Ich hätte den Standard für eine große Nutzerbasis
umgekippt, die ihn so wollte, wie er ist. Saubere Trennung über einen eigenen Plugin-Slot war der respektvollere Weg.
Privacy-first as a default is a minority position. Chat 2 rightly serves the broad majority with full history as the
default. Changing those defaults upstream would have been wrong. I would have flipped the standard for a large user base
that wanted it as it was. A clean separation through a dedicated plugin slot was the more respectful path.
### Das Webinterface musste weg
### The web interface had to go
Das ist ein zentrales Chat-2-Feature für Remote-Zugriff vom Zweitgerät. Ein PR der das entfernt, hat in einem gepflegten
Upstream-Projekt keine Chance, und das ist auch richtig so. Aber genau das Webinterface kollidiert mit der
Privacy-First-These dieses Forks: Ein Chat-Plugin das einen lokalen HTTP-Server startet, ist für mein Threat-Model eine
zu große Angriffsfläche. Also raus damit.
It is a central Chat 2 feature for remote access from a second device. A PR removing it has no chance in a
well-maintained upstream project, and that is correct. But exactly that web interface conflicts with the privacy-first
premise of this fork: a chat plugin that starts a local HTTP server is too large an attack surface for my threat model.
So out it went.
### Tempo
### Velocity
Ein Solo-Maintainer-Projekt mit kleinem Tester-Pool kann schneller iterieren als ein etabliertes Plugin mit großer
Nutzerbasis. Das ist kein Vorwurf an Upstream, sondern eine andere Optimierung. Ich brauche keine Roadmap-Abstimmung,
keine Reviewer-Verfügbarkeit, und kann Audit-Konsequenzen wie das Webinterface-Removal in einer einzigen Version
durchziehen statt über mehrere Releases.
A solo-maintainer project with a small tester pool can iterate faster than an established plugin with a large user base.
That is not a criticism of upstream but a different optimization. I do not need roadmap alignment, reviewer
availability, or to spread audit consequences like the web interface removal across multiple releases.
EUPL-1.2 erlaubt das alles ausdrücklich, mit klarer Attribution. Der Code liegt offen unter derselben Lizenz wie Chat 2.
Infi, Anna oder sonst jemand dürfen reinschauen, Ideen mitnehmen, Fragen stellen oder den Fork einfach ignorieren. Alles
drei ist für mich okay.
EUPL-1.2 explicitly allows all of this with clear attribution. The code is open under the same license as Chat 2. Infi,
Anna, or anyone else can look in, take ideas, ask questions, or simply ignore the fork. All three are fine with me.
---
## Wie ich so schnell release
## How I release this fast
Wer auf den Repo schaut, sieht in kurzer Zeit viele Releases und sehr viele Commits. Beides wird von außen gerne als
Red-Flag gelesen: KI-Slop, Salami-Taktik, Code-Spam. Bei Hellion Chat ist beides eine bewusste Entscheidung, und ich
erkläre lieber einmal warum, als mich später dafür zu rechtfertigen.
Anyone looking at the repo sees a lot of releases and a high commit count in a short time. Both tend to read as red
flags from the outside: AI slop, salami tactics, code spam. In Hellion Chat both are deliberate decisions, and I would
rather explain them once than justify them later.
### Vorarbeit, lange bevor der Fork existierte
### Groundwork, long before the fork existed
Bevor ich die erste Zeile in `HellionChat/` getippt habe, war ich wochenlang nur Leser. Chat 2 ingame nutzen und damit
rumspielen. Issues im Upstream-Tracker durchgehen, vor allem die geschlossenen, weil dort steht, wie Infi und Anna Bugs
einkreisen. Commits lesen, gerne auch ältere, um zu verstehen, warum eine Architektur-Entscheidung getroffen wurde,
nicht nur, dass sie getroffen wurde. Wenn ich heute weiß, wo im Code was liegt, dann nicht, weil ich besonders schnell
durch eine Codebase navigiere, sondern weil ich den Code vorher gelesen habe.
Before I typed the first line into `HellionChat/`, I spent weeks as a reader. Using Chat 2 in-game and playing around
with it. Going through issues in the upstream tracker, especially the closed ones, because that is where you see how
Infi and Anna narrow down bugs. Reading commits, including older ones, to understand _why_ an architecture decision was
made, not just _that_ it was made. If I know today where things live in the codebase, it is not because I navigate
codebases particularly fast but because I read the code beforehand.
Klingt nach Selbstverständlichkeit, ist es aber nicht. Die übliche Reihenfolge bei Solo-Forks heißt erst forken, dann
verstehen. Ich habe es andersrum gemacht.
That sounds obvious. It is not. The usual order for solo forks is fork first, understand later. I did it the other way
around.
### Die Codebase von Infi und Anna
One thing I noticed reading the codebase closely: some patterns felt familiar in ways I had not expected, structural
choices and comment styles that show up across a lot of modern plugin and tooling code regardless of how it was written.
Nothing worth reading into. Coding workflows have changed a lot in the last few years across the board, and the traces
of that show up everywhere. It did make me less self-conscious about my own workflow.
Hellion Chat baut auf einem Boden auf, der schon flach ist. Chat 2 ist sauber strukturiert, die Naming-Konventionen sind
konsistent, die Trennung zwischen Layern (Storage, UI, Game-Hooks, IPC) ist klar gezogen. Das ist in
Open-Source-Plugin-Welten nicht selbstverständlich, und es ist der Hauptgrund, warum sich Hellion-spezifische Features
oft "fast nativ" einbauen lassen. Ich muss nicht erst Spaghetti entwirren bevor ich was Eigenes danebenstellen kann.
### Infi and Anna's codebase
Side-Fact: Selbst beim ersten Codebase-Walkthrough mit Claude kam mehrfach der Hinweis, dass die Architektur
ungewöhnlich gut aufgeräumt ist und mehrere Erweiterungspunkte vorbereitet. Das hat Gewicht, weil es von außen kommt,
aber den eigentlichen Kredit kriegen Infi und Anna, nicht Claude.
Hellion Chat builds on a foundation that is already flat. Chat 2 is cleanly structured, naming conventions are
consistent, and the separation between layers (storage, UI, game hooks, IPC) is clearly drawn. That is not a given in
open-source plugin land, and it is the main reason Hellion-specific features often slot in "almost natively". I do not
have to untangle spaghetti before I can put something of my own next to it.
### Atomar arbeiten, kleine Commits
Side note: even during the first codebase walkthrough with Claude, the comment came up several times that the
architecture is unusually tidy and has several extension points prepared. That carries weight because it comes from
outside, but the actual credit goes to Infi and Anna, not Claude.
Ein Commit, eine logische Änderung. Wenn ich einen Bug fixe, parallel eine Variable umbenenne und nebenbei einen
Kommentar einbaue, sind das drei Commits, nicht einer. Klingt nach Mikro-Management, ist es aber nicht. Wenn in sechs
Monaten ein Bug auftaucht und ich `git bisect` brauche, finde ich die kaputte Änderung in zwei Minuten statt in zwei
Stunden. Bei einem 4000-Zeilen-Mega-Commit darf ich raten, welche der hundert Änderungen die kaputte ist.
### Atomic work, small commits
Den Stil habe ich bewusst auch deshalb beibehalten, weil Infi im Upstream häufig genauso arbeitet. Manchmal ein
Sechs-Zeilen-Commit, manchmal nur ein Typo-Fix. Das ist keine Schwäche, das ist eine Entscheidung für lesbare
Git-History. Den Stil im Fork beizubehalten ist ein Respekt-Move: Wer die beiden Repos vergleicht, soll den gleichen
Lese-Rhythmus haben.
One commit, one logical change. If I fix a bug, rename a variable and add a comment at the same time, that is three
commits, not one. Sounds like micro-management, it is not. If a bug surfaces in six months and I need `git bisect`, I
find the broken change in two minutes instead of two hours. With a 4000-line mega-commit I get to guess which of the
hundred changes is the broken one.
Bonus für mich persönlich: Kleine Commits zwingen mich, jeden Schritt einzeln zu durchdenken und zu benennen. Wenn ich
nicht in zwei Sätzen erklären kann, was ein Commit macht, ist die Änderung wahrscheinlich noch nicht klar genug. Auf
Beginner-Niveau ist das ein eingebauter Sanity-Check, den ich bei einem Big-Bang-Commit nicht hätte.
I kept this style deliberately also because Infi works the same way upstream. Sometimes a six-line commit, sometimes
just a typo fix. That is not a weakness, it is a decision for readable Git history. Keeping the style in the fork is a
respect move: anyone comparing both repos should have the same reading rhythm.
### AI als Beschleuniger, ehrlich
Personal bonus: small commits force me to think through and name each step individually. If I cannot explain what a
commit does in two sentences, the change is probably not clear enough yet. At beginner level that is a built-in sanity
check I would not have with a big-bang commit.
Ja, AI hilft beim Tempo, und nicht zu knapp. Ohne CodeRabbit hätte ich Critical-Bugs der Klasse
`Equals/GetHashCode`-Anti-Pattern, Hook-Subscription-Leaks und TOCTOU-Races nicht gefunden. Ich bin schlicht zu
unerfahren für diese Klasse von Findings, das schreibe ich genau so hin.
### AI as an accelerator, honestly
Was ich aber nicht mache: blind Code übernehmen, weil ein Tool ihn als Fix markiert hat. Bei mehreren
CodeRabbit-Findings stand in den Original-Commits von Infi oder Anna sogar ein Stackoverflow-Link mit Begründung dabei,
warum eine bestimmte Stelle so aussieht wie sie aussieht. Die habe ich gelesen, bevor ich was geändert habe. Erst
verstehen, dann anfassen, dann committen. Das ist der Unterschied zwischen "AI gibt mir Code, ich pushe" und "AI zeigt
mir wo's klemmt, ich entscheide".
Yes, AI helps with velocity, and not a little. Without CodeRabbit I would not have found critical bugs like
`Equals/GetHashCode` anti-patterns, hook subscription leaks and TOCTOU races. I am simply too inexperienced for that
class of findings, and I write that exactly as it is.
Klassifikation und konkrete Beispiele zur AI-Nutzung stehen in [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md). Hier in dieser
Sektion ging es nur um den Tempo-Aspekt: Recherche plus saubere Codebase plus atomare Commits plus AI-gestütztes
Review-Sparring sind die vier Faktoren zusammen. Kein einzelner davon erklärt das Tempo allein.
What I do not do: blindly take code because a tool marked it as a fix. On several CodeRabbit findings, the original
commits from Infi or Anna even included a Stack Overflow link explaining why a particular spot looks the way it does. I
read those before touching anything. Understand first, then change, then commit. That is the difference between "AI
gives me code, I push" and "AI shows me where it breaks, I decide".
Classification and concrete examples of AI usage are in [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md). This section was only
about the velocity aspect: research plus a clean codebase plus atomic commits plus AI-assisted review sparring are the
four factors together. No single one explains the pace on its own.
---
## Vom Web-Stack zu C# / Dalamud
## From the web stack to C# / Dalamud
### Type-System? Weniger Schock als erwartet
### Type system? Less of a shock than expected
C# nach TypeScript war angenehmer als gedacht. Properties statt getter/setter sind sauber, nullable reference types
fühlen sich an wie `strict: true` in TypeScript. Ungewohnt war Wert-Typen vs. Referenz-Typen explizit denken zu müssen
(`struct` vs. `class` mit echten Verhaltens-Konsequenzen), und Generics mit Constraints sind syntaktisch anders genug,
dass ich beim Lesen kurz stocke. `async`/`await` ist semantisch ähnlich, aber Threading-Modelle sind in C# expliziter:
`Task.Run`, `ConfigureAwait`, Synchronization-Contexts. Das hat mich mehrere Bugs gekostet, bevor ich verstanden hatte,
wann der Main-Thread (in Plugin-Welt: der Framework-Tick) wirklich kritisch ist.
C# after TypeScript was more comfortable than expected. Properties instead of getters/setters are clean, nullable
reference types feel like `strict: true` in TypeScript. What was unfamiliar was having to think explicitly about value
types versus reference types (`struct` vs. `class` with real behavioural consequences), and generics with constraints
are syntactically different enough that I stumble on them while reading. `async`/`await` is semantically similar, but
threading models are more explicit in C#: `Task.Run`, `ConfigureAwait`, synchronization contexts. That cost me several
bugs before I understood when the main thread (in plugin land: the framework tick) is actually critical.
### Build-Toolchain: ähnlich, aber anders
### Build toolchain: similar, but different
`dotnet` CLI, csproj-XML, NuGet sind funktional nicht weit weg von npm und tsconfig. Aber das XML-Format der csproj ist
eine andere Sprache als JSON-Configs. Die Lock-Datei (`packages.lock.json`) musste ich erst aktiv aktivieren
(`RestorePackagesWithLockFile=true`); das ist nicht Default. Im Web-Stack ist Lock-File-First Standard, im .NET-Stack
offenbar nicht. Das war eine echte Überraschung.
`dotnet` CLI, csproj XML, NuGet are functionally not far from npm and tsconfig. But the XML format of csproj is a
different language than JSON configs. The lock file (`packages.lock.json`) had to be actively enabled
(`RestorePackagesWithLockFile=true`); that is not the default. In the web stack, lock-file-first is standard, in the
.NET stack apparently not. That was a real surprise.
### ImGui ist eine andere Welt
### ImGui is a different world
Immediate-Mode-Rendering hat mit React-Component-Trees nichts gemein. Es gibt keine virtuelle DOM, keine Reconciliation,
keinen "State der Komponente". Pro Frame zeichnet der Code die UI komplett neu, und der State lebt entweder in lokalen
Variablen, die ich selbst verwalten muss, oder in der ImGui-eigenen ID-Stack-Logik.
Immediate-mode rendering has nothing in common with React component trees. There is no virtual DOM, no reconciliation,
no "component state". Every frame the code redraws the UI from scratch, and state lives either in local variables I
manage myself or in ImGui's own ID stack logic.
Was in React zwei Zeilen `useState` sind, ist in ImGui ein Member-Field plus manuelle ID-Stempel auf den Widgets, sonst
kollidieren zwei Selectables in derselben Loop, weil sie auf die gleiche ID zurückfallen. Die ID-Stack-Kollision in
`SearchSelector` (gefixt in v1.0.0) war genau dieses Symptom: Alle Selectables fielen auf dieselbe ambiguous ID zurück,
bis ich den Row-Index in den Push-ID gemixt habe. Klassischer "warum klickt der falsche Eintrag"-Bug, den man nur
findet, wenn man verstanden hat, wie ImGui IDs intern handhabt.
What is two lines of `useState` in React is a member field plus manual ID stamps on widgets in ImGui, otherwise two
selectables in the same loop collide because they fall back to the same ID. The ID stack collision in `SearchSelector`
(fixed in v1.0.0) was exactly that symptom: all selectables fell back to the same ambiguous ID until I mixed the row
index into the PushID. Classic "why is the wrong entry getting clicked" bug that you only find once you understand how
ImGui handles IDs internally.
### Dalamud-Spezifika
### Dalamud specifics
Plugin-Lifecycle, IPC-Subscriber-Pattern, Hook-System für Game-Functions, Game-Object-Threading. Viel davon war nur
durch Lesen der Upstream-Codebase und durch [dalamud.dev](https://dalamud.dev) zu verstehen. Meine Trainings- und
Such-Ergebnisse für "Dalamud" liefern oft veraltete API-Beispiele aus alten Versionen. dalamud.dev ist die zuverlässige
Quelle. Wenn jemand neu anfängt: dort hin, nicht zu Stack Overflow.
Plugin lifecycle, IPC subscriber pattern, hook system for game functions, game object threading. Much of that was only
understandable through reading the upstream codebase and through [dalamud.dev](https://dalamud.dev). Search results for
"Dalamud" often turn up outdated API examples from old versions. dalamud.dev is the reliable source. If someone is just
starting out: go there, not to Stack Overflow.
### Der Tag, an dem mich der DalamudPackager einen Tag gekostet hat
### The day DalamudPackager cost me a day
Dalamud SDK 15 liefert seinen eigenen Default-Packager mit, der Icons und Image-URLs ins Manifest einträgt. Ich hatte
aus dem Upstream-Repo eine eigene `DalamudPackager.targets`-Datei mit `HandleImages`-Override übernommen, und die hat
den SDK-Default überschrieben. Resultat: Das Manifest hatte keinen `IconUrl` mehr, und das Plugin tauchte in der
Plugin-Liste ohne Icon auf.
Dalamud SDK 15 ships its own default packager that writes icons and image URLs into the manifest. I had carried over a
`DalamudPackager.targets` file from the upstream repo with a `HandleImages` override, and it was overriding the SDK
default. Result: the manifest had no `IconUrl` anymore, and the plugin appeared in the plugin list without an icon.
Symptom war einfach zu sehen, Ursache hat einen Tag gekostet. Ich hatte die Override-Datei für eine Pflicht-Datei
gehalten, war sie aber nicht. Removal in v0.5.2, seitdem läuft der SDK-Default. Lektion: Erstmal mit Defaults arbeiten,
Overrides erst wenn der Default nachweislich nicht passt.
The symptom was easy to spot, the cause cost a day. I had treated the override file as mandatory when it was not.
Removed in v0.5.2, SDK default running since then. Lesson: start with defaults, add overrides only when the default
demonstrably does not fit.
---
## Was ich aus dem Fork gelernt habe
## What I learned from the fork
### Refactor in einer fremden Codebase
### Refactoring in an unfamiliar codebase
Der Standalone-Cut in v1.0.0 hat die `ChatTwo.*`-Identität komplett auf `HellionChat.*` migriert. Klingt nach
Find-and-Replace. War es nicht.
The standalone cut in v1.0.0 migrated the entire `ChatTwo.*` identity to `HellionChat.*`. That sounds like find and
replace. It was not.
Konkret bedeutete das: Code-Namespace über alle 80 Source-Files plus 100 using-Direktiven plus zwei FQN-Aliases plus die
Resource-Designer-Strings. Sechs IPC-Channels umbenannt (Breaking Change für Drittplugins, keine bekannten Anbindungen).
Repo-Ordner-Struktur (`ChatTwo/` `HellionChat/`) inklusive csproj, sln, allen GitHub-Workflows und der dependabot.yml.
Public-Facing-Branding in README, repo.json, yaml auf Standalone-Framing umformuliert.
In concrete terms: code namespace across all 80 source files plus 100 using directives plus two FQN aliases plus the
resource designer strings. Six IPC channels renamed (breaking change for third-party plugins, no known integrations).
Repo folder structure (`ChatTwo/` -> `HellionChat/`) including csproj, sln, all GitHub workflows and dependabot.yml.
Public-facing branding in README, repo.json and yaml reformulated to standalone framing.
Das war kein Solo-Find-and-Replace, weil Unicode-String-Pfade in Workflow-YAMLs anders quotiert werden müssen als
C#-Strings. Weil Resource-Designer-Files generierte Inhalte haben, die nicht jede Toolchain im Blick hat. Und weil die
`ChatTwo.*`-IPC-Channel-Namen Strings in `GetIpcSubscriber`-Calls sind: kein Symbol, kein Compile-Error, wenn man einen
vergisst. Da merkst du, was alles still bleibt.
It was not a solo find-and-replace because Unicode string paths in workflow YAMLs need different quoting than C#
strings. Because resource designer files have generated content that not every toolchain tracks. And because the
`ChatTwo.*` IPC channel names are strings in `GetIpcSubscriber` calls: no symbol, no compile error if you miss one. That
is when you find out what stays quiet.
### Sicherheit ist kein abstraktes Thema mehr
### Security is no longer abstract
Vor diesem Projekt war Supply-Chain-Sicherheit für mich akademisch. Drei konkrete Lektionen haben das geändert.
Before this project, supply chain security was academic for me. Three concrete lessons changed that.
**SQLite-Native-Binary.** Ich musste auf 3.50.3 pinnen (`SQLitePCLRaw.lib.e_sqlite3` Override), weil
`Microsoft.Data.Sqlite` die transitiv nachgezogene Lib in einer Version mitschleppte, die CVE-2025-6965
(Memory-Corruption durch Aggregate-Term-Overflow) und CVE-2025-7709 enthielt. Der Managed-Wrapper war neu, die
Native-Lib war es nicht. Lektion: Transitive Dependencies prüfen sich nicht von selbst, du musst hinschauen.
**SQLite native binary.** I had to pin to 3.50.3 (`SQLitePCLRaw.lib.e_sqlite3` override) because `Microsoft.Data.Sqlite`
was pulling in a transitively referenced library at a version containing CVE-2025-6965 (memory corruption via aggregate
term overflow) and CVE-2025-7709. The managed wrapper was new; the native library was not. Lesson: transitive
dependencies do not audit themselves, you have to look.
**Lock-File-Drift.** `packages.lock.json` honored bei `dotnet restore` (per `RestorePackagesWithLockFile=true` in der
csproj) verhindert, dass transitive Versionen zwischen meiner Maschine und CI silent driften. Erst nach einem
Build-Output-Mismatch zwischen lokal und GitHub-Actions hatte ich überhaupt verstanden, warum das nicht der Default ist.
**Lock file drift.** `packages.lock.json` honoured via `RestorePackagesWithLockFile=true` in the csproj prevents
transitive versions from silently drifting between my machine and CI. I only understood why this is not the default
after a build output mismatch between local and GitHub Actions.
**WrapText und der CodeQL-Alarm der drei Releases gekostet hat.** CodeQL hat in `ImGuiUtil.WrapText` einen
Critical-Alert wegen "unvalidated local pointer arithmetic" geworfen. v0.5.2 hat einen Edge-Case validiert. Alert kam
wieder. v0.5.3 hat den Buffer-Length via `GetByteCount` vor der Pointer-Math gecheckt. Alert kam wieder. v0.5.4 hat den
ganzen Algorithmus auf `Span` und int-Offsets umgebaut, mit einem 16-KiB-Cap auf den ArrayPool-Rent. Erst da war Ruhe.
**WrapText and the CodeQL alert that cost three releases.** CodeQL flagged a critical alert in `ImGuiUtil.WrapText` for
unvalidated local pointer arithmetic. v0.5.2 validated an edge case. Alert came back. v0.5.3 checked buffer length via
`GetByteCount` before the pointer math. Alert came back. v0.5.4 rebuilt the whole algorithm on `Span` and int offsets
with a 16 KiB cap on the ArrayPool rent. Only then did it go quiet.
Lektion: Wenn ein statischer Analyzer drei Mal hintereinander meckert, ist nicht der Analyzer überempfindlich. Die
Datenflusslogik ist es.
Lesson: when a static analyser complains three times in a row, the analyser is not oversensitive. The data flow logic
is.
### CodeRabbit als externer Code-Reviewer
### CodeRabbit as an external code reviewer
Der v1.0.0-Sweep hat 3 Critical und 21 Major Findings hochgespült. Drei Klassen davon waren besonders lehrreich:
The v1.0.0 sweep surfaced 3 critical and 21 major findings. Three classes were particularly instructive:
- **`Equals`-Methoden die `GetHashCode()` vergleichen.** Klassisches Hash-Kollisions-Anti-Pattern. Klingt nach "ist doch
egal, wenn Hashes gleich sind, sind die Objekte auch gleich", ist aber genau falsch. Hashes können kollidieren,
Objekte sind dann nicht gleich.
- **`Dispose`-Methoden die nur einen Teil der Subscriptions wieder abmelden.** Leak bei jedem Plugin-Reload. Im
Nutzer-Alltag merkst du das nicht sofort, im Long-Running-Test schon.
- **TOCTOU-Races.** Zwischen Bounds-Check und Read kann ein anderer Thread das Array unter dir austauschen
- **`Equals` methods comparing `GetHashCode()`.** Classic hash collision anti-pattern. Sounds like "if hashes are equal
the objects are equal", which is exactly backwards. Hashes can collide; the objects are not equal.
- **`Dispose` methods that only unsubscribe part of their subscriptions.** Leak on every plugin reload. In normal use
you do not notice it immediately; in a long-running test you do.
- **TOCTOU races.** Between a bounds check and a read another thread can swap out the array underneath you
(`GlobalParametersCache`, `AutoTranslate`).
Davon hatte ich vorher bestenfalls die Theorie gelesen, nicht selbst diagnostiziert. CodeRabbit war für mich der Moment,
wo "akademisches Wissen" zu "okay, das ist mein Code, das ist mein Bug" wurde.
I had at best read the theory on all of these before, never diagnosed them in my own code. CodeRabbit was the moment
where "academic knowledge" became "okay, that is my code, that is my bug".
### Externe Tester sind ihr Gewicht in Gold wert
### External testers are worth their weight
Carlas Feedback zur Pop-Out-Discoverability hat den Header-Button in v0.6.1 ausgelöst. Dass Pop-Outs nur per Rechtsklick
erreichbar waren, hatte ich als Maintainer nicht mehr gesehen, ich kannte den Pfad blind. Carls Wunsch nach
Theme-Varianten mit Helligkeits-Abstufungen hat mein Verständnis von "ein Theme = eine Farbe" auf "Theme-Familien mit
Stimmungs-Varianten" verschoben. Jingliu hat TempTell-Persistence gefordert, was das Tab-System architektonisch in Frage
stellt.
Carla's feedback on pop-out discoverability triggered the header button in v0.6.1. That pop-outs were only reachable via
right-click was something I as maintainer had stopped seeing; I knew the path by heart. Carl's request for theme
variants with brightness gradations shifted my thinking from "one theme = one colour" to "theme families with mood
variants". Jingliu asked for TempTell persistence, which puts the tab system architecturally into question.
Solo hätte ich diese drei Dinge nicht erkannt. Punkt.
Solo I would not have seen any of those three things. Full stop.
### release.yml und die Markdown-Hölle
### release.yml and the YAML rabbit hole
Der `release.yml`-Workflow ist beim ersten v0.6.0-Tag-Push einfach nicht losgegangen. Ich habe Stunden in Permissions,
Secret-Scopes und Tag-Trigger-Konfiguration gegraben, bevor ich verstand, was eigentlich los war: Der
PowerShell-Heredoc-Footer im "Generate release body"-Step enthielt eine `---`-Markdown-Horizontal-Rule an Spalte 1, und
genau das hat das YAML-Block-Scalar von `run: |` beendet. GitHub konnte die Workflow-Datei nicht parsen, also hat der
Push-Tag-Trigger nie registriert.
The `release.yml` workflow simply did not fire on the first v0.6.0 tag push. I dug through permissions, secret scopes
and tag trigger configuration for hours before I understood what was actually happening: the PowerShell heredoc footer
in the "Generate release body" step contained a `---` Markdown horizontal rule at column 1, and that terminated the YAML
block scalar of `run: |`. GitHub could not parse the workflow file, so the push-tag trigger never registered.
Fix: Footer in eine externe `.github/release-footer.md` extrahiert, Workflow liest sie via `Get-Content` ein. Lektion:
Wenn ein Workflow nicht triggert, verifiziere als Erstes, dass GitHub die Datei überhaupt parsen kann. Das war einer der
Bugs, bei denen ich nach dem Fix kurz gelacht habe und mich dann gefragt, wie viele andere YAML-Dateien ich noch habe,
die so eine Falle drin haben könnten.
Fix: extracted the footer into an external `.github/release-footer.md`, workflow reads it via `Get-Content`. Lesson: if
a workflow does not trigger, verify first that GitHub can even parse the file. That was one of the bugs where I laughed
briefly after the fix and then asked myself how many other YAML files I had that might have the same trap in them.
---
## Was ich noch lerne
## What I am still learning
### Performance-Profiling im Game-Context
### Performance profiling in a game context
Der FPS-Drop-Bug aus Upstream Chat 2 ([#145](https://github.com/Infiziert90/ChatTwo/issues/145)) ist auch in Hellion
Chat noch nicht reproduziert oder verifiziert. v1.0.0 hat mehrere Fixes auf den verdächtigen Pfaden (DbViewer O(N²)
O(N), AutoTranslate Lock-Serialisierung, EmoteCache HttpClient-Reuse), aber das systematische Vermessen unter Last fehlt
mir. Ich muss noch lernen, wie man im Plugin-Kontext sauber misst, was wirklich das Frame-Budget frisst.
The FPS drop bug from upstream Chat 2 ([#145](https://github.com/Infiziert90/ChatTwo/issues/145)) has not been
reproduced or verified in Hellion Chat. v1.0.0 applied several fixes on the suspected paths (DbViewer O(N²) -> O(N),
AutoTranslate lock serialisation, EmoteCache HttpClient reuse), but systematic measurement under load is missing. I
still need to learn how to properly measure what is actually consuming the frame budget in a plugin context.
### Native-Interop und Pointer-Math
### Native interop and pointer math
Auch nach dem WrapText-Span-Refactor in v0.5.4 ist mir Pointer-Math unsicher. ImGui zwingt einen an mehreren Stellen in
`unsafe`-Code, und der Sicherheitsabstand zur "unbounded ArrayPool allocation"-Klasse von Bugs ist schmaler als mir lieb
ist. Da will ich besser werden, bevor ich tieferes ImGui-Custom-Drawing anfasse.
Even after the WrapText Span refactor in v0.5.4, pointer math makes me uneasy. ImGui forces you into `unsafe` code in
several places, and the safety margin from the "unbounded ArrayPool allocation" class of bugs is narrower than I would
like. I want to get better at that before touching deeper ImGui custom drawing.
### Test-Disziplin für Plugin-Code
### Test discipline for plugin code
Aktuell hat das Repo kein Test-Projekt. Das ist eine bewusste Entscheidung, keine vergessene. Plugin-Code mit
FFXIV-Hooks und Dalamud-Lifecycle sauber zu testen ist nicht trivial, und ich hatte keinen Ansatz gefunden, der ohne
riesiges Mocking-Gerüst sinnvoll wirkte. Privacy-Filter und Configuration-Migration wären gute Testkandidaten, weil sie
isoliert sind. Steht auf der Liste, ist aber kein Quick-Win.
The repo currently has no test project. That is a deliberate decision, not a forgotten one. Testing plugin code with
FFXIV hooks and Dalamud lifecycle cleanly is non-trivial, and I had not found an approach that made sense without a
large mocking scaffold. Privacy filter and configuration migration would be good test candidates because they are
isolated. On the list, but not a quick win.
### Linux-Eigenheiten unter Wine
### Linux quirks under Wine
XDG-Compliance, libnotify-Integration, WireGuard-Network-Detection, alles in der [Roadmap](ROADMAP.md), und alles
technisch noch nicht ganz klar. Wine und sandboxed Plugin-Code teilen nicht alle System-APIs, und ich weiß nicht, wo die
Stolperfallen liegen, bevor ich sie gefunden habe.
XDG compliance, libnotify integration, WireGuard network detection, all on the [roadmap](ROADMAP.md), and all
technically still unclear. Wine and sandboxed plugin code do not share all system APIs, and I do not know where the
pitfalls are until I have found them.
---
## Einsatz von AI-Tools
## Use of AI tools
Ich verwende Claude Code als Hilfsmittel, nicht als Ersatz für eigene Arbeit.
I use Claude Code as an assistant, not as a replacement for my own work.
**Wofür ich AI einsetze:**
**What I use AI for:**
- Debugging von Problemen, bei denen ich nach längerer Eigenrecherche nicht weiterkomme
- Mustererkennen über große Codebasen hinweg (z. B. der ChatTwoHellionChat-Sweep über 80 Dateien)
- Verständnisfragen zu C#- und Dalamud-Konzepten, die mir noch nicht geläufig sind
- Code-Review-Sparring, bevor ich CodeRabbit drauflasse
- Debugging problems where I am stuck after extended research of my own
- Pattern recognition across large codebases (e.g. the ChatTwo -> HellionChat sweep across 80 files)
- Understanding questions on C# and Dalamud concepts I am not yet familiar with
- Code review sparring before I run CodeRabbit on something
**Was ich selbst mache:**
**What I do myself:**
- Architektur und Designentscheidungen
- Privacy-First-Defaults und das Threat-Model dahinter
- Tester-Kommunikation und Roadmap-Priorisierung
- Reviewen, Verifizieren, Pushen
- Architecture and design decisions
- Privacy-first defaults and the threat model behind them
- Tester communication and roadmap prioritisation
- Reviewing, verifying, pushing
Die Klassifikation und konkrete Beispiele stehen in [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md). Mir ist wichtig, dass Nutzer
und potenzielle Beiträger verstehen, wie der Code zustande gekommen ist, gerade bei einem Plugin, das mit Nutzerdaten
arbeitet.
Classification and concrete examples are in [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md). It matters to me that users and
potential contributors understand how the code came together, especially for a plugin that handles user data.
Ja, AI. Ja, alleine. Beides öfter erwähnt als nötig. Willkommen im Open-Source-Plugin-Klima.
Yes, AI. Yes, alone. Both mentioned more than strictly necessary. Welcome to the open-source plugin climate.
---
## Warum diese Transparenz
## Why this transparency
Wer sich den Quellcode ansieht, soll wissen:
Anyone reading the source code should know:
- Ich bin kein professioneller C#- oder Plugin-Entwickler und lerne weiterhin dazu
- AI-Unterstützung ist ein Werkzeug, kein Ghostwriter
- Die Privacy-Position, die Designentscheidungen und die Roadmap sind meine
- Ich versuche, meinen Code so sauber und sicher zu halten, wie meine aktuellen Fähigkeiten es zulassen
- I am not a professional C# or plugin developer and am still learning
- AI assistance is a tool, not a ghostwriter
- The privacy position, the design decisions and the roadmap are mine
- I try to keep my code as clean and secure as my current skills allow
Hellion Chat ist auch ein Lernprojekt, und das soll man dem Repository ansehen dürfen.
Hellion Chat is also a learning project, and that should be visible in the repository.
---
## Verlinkungen
## Links
- [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md) — KI-Pair-Disclosure mit Klassifikations-Schema
- [`CONTRIBUTORS.md`](CONTRIBUTORS.md) — wer hat dieses Plugin neben mir besser gemacht
- [`../NOTICE.md`](../NOTICE.md) — Anerkennung an Infi und Anna für das Chat-2-Fundament
- [`ROADMAP.md`](ROADMAP.md) — geplante Cycles und Themen
- [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md) -- AI pair disclosure with classification schema
- [`CONTRIBUTORS.md`](CONTRIBUTORS.md) -- who has made this plugin better alongside me
- [`../NOTICE.md`](../NOTICE.md) -- attribution to Infi and Anna for the Chat 2 foundation
- [`ROADMAP.md`](ROADMAP.md) -- planned cycles and topics