DEV Community

Cover image for I built an AI-collaborative UML editor that puts πŸ’© on smelly code
dhq_boiler
dhq_boiler

Posted on Originally published at zenn.dev

I built an AI-collaborative UML editor that puts πŸ’© on smelly code

TL;DR β€” I really just wanted to put πŸ’© icons on UML class diagrams. Along the way it turned into Kata, a two-way class diagram editor for C# / C++/CLI solutions that (1) detects 22 out of Fowler's 24 code smells and pins a πŸ’© badge to the exact type or member, (2) lets you fire Fowler-catalog refactorings straight from the diagram and writes them back into the source, and (3) forwards "I don't know how to fix this" to Claude Code / Codex CLI and previews the returned unified diff before applying.

Site: https://kata.dhq-boiler.dev/ Β· Repo: https://github.com/dhq-boiler/Kata

Why I built it

I know the Refactoring book. I've read Refactoring the way most of us have β€” I can name Extract Method, I can spot a big switch statement, and I nod when someone says "feature envy". But knowing the catalog and actually running through it on a real codebase are two different sports.

The gap for me was step zero: finding code smells at all. Once you know a method reeks, half the fight is over. The catalog tells you what to do next. But there's no "smelly bit" indicator on a real project β€” you just stare at 200,000 lines and hope a bad smell walks up and introduces itself.

So the pitch was really that literal:

If I could see a πŸ’© icon sitting on top of the classes that need attention, the rest of the workflow would fall into place.

That's it. The editor grew around that one need.

The core workflow

  1. Human β€” opens the class diagram, scans for πŸ’© badges (the tool does this part).
  2. AI β€” applies the refactoring recipe (Claude Code or Codex, whichever you already pay for).
  3. Human β€” reviews the diff and clicks Apply.

The important bit is that humans stay in the review seat. AI never writes to disk without you seeing the exact diff first.

What the tool actually does

1. .sln / .slnx β†’ live class diagram

Open a solution, get a real class diagram back. Symbol resolution is done through Roslyn for C# and through a hand-written semantic layer (Kata.Cpp) for C++/CLI, so mixed-language WPF-plus-native-library projects render correctly.

2. Ctrl+Click navigation (cross-language)

Click any type or member to jump to its definition. C# ↔ C++/CLI navigation works both ways β€” chase a P/Invoke or a ref class from either side.

3. Fowler refactorings, driven from the diagram

Right-click a class β†’ pick a refactoring β†’ Kata rewrites the source. The current set covers Extract Method / Extract Interface / Extract Class, the whole Rename family (type / member / field / parameter), Move Method / Move Field, Extract Hierarchy, and more.

The same operations are exposed as MCP tools, so an external agent (Claude Code, Codex, or anything speaking MCP) can drive Kata programmatically the same way a human does from the UI.

4. Code-smell analyzer + πŸ’© badges

22 of Fowler's 24 smells are implemented as deterministic detectors that run over the semantic model. Results show up in two places:

  • top-right of a type node for type-level smells (God Class, Data Class, Feature Envy…)
  • end of a member row for member-level smells (Long Method, Long Parameter List, Divergent Change…)

Tiered badges β€” the more severe ones get a rainbow halo β€” so a screen full of nodes reads at a glance.

5. AI-generated diffs, with preview

Two AI paths, both piggy-backed on your existing subscription:

  • claude -p "<prompt>" β€” Claude Code CLI (headless mode)
  • codex exec "<prompt>" β€” Codex CLI

Kata builds the prompt from (the smell, the enclosing type / member source, the catalog recipe for that smell, and a strict "return a unified diff" instruction), runs it, parses the returned diff, and drops you into a preview dialog. Nothing hits disk until you approve.

Two design choices that matter here:

  • No API key management. You're not billed by Kata β€” it uses whatever Claude / ChatGPT plan you already have.
  • Deterministic first, AI second. For a growing set of categories (currently 20 rewriters across three tiers) Kata has an in-tool Roslyn rewriter that produces the exact same diff without hitting the network. For the harder cases (data-flow, cross-file design changes) it falls back to the AI path.

There's also a behavior-change caution pane in the diff preview when a fix is technically correct but semantically shifts something β€” e.g. OrderBy(...).FirstOrDefault() β†’ MinBy(...) throws on empty sequences where the original returned default(T). That's the kind of "the diff is right, please just be aware" moment that a plain patch view swallows.

Architecture, briefly

  • Source is SSOT. Kata is a mirror of the codebase. Only pure UI state (node positions, zoom, filter selections) lives in a side file.
  • Intent-driven. Every user action becomes a strongly-typed Intent (RenameIntent, ExtractMethodIntent, PerfFixIntent, …). Language-specific adapters translate intents into source edits. Both the UI and the MCP surface fire the same intents through the same handlers.
  • MCP externalized. Kata.Mcp runs over Streamable HTTP + stateless, so a Kata.App user and one or more AI agents can all talk to the same live model without sessions fighting each other.
  • Language-neutral core. Kata.Core has no dependency on any language adapter. Adding a new language means implementing ILanguageAdapter plus a smell detector set, not editing the core. C# is the mature adapter today; Java is next up (JDT-Core-based load benchmarked at 4.6 s for a large real project).

Perf note: rendering a live class diagram of a big solution used to hitch hard because Nodify wants to materialize every visual up front. VirtualizingNodifyCanvas (a "realize-all, measure-only-viewport" trick) took that hitch from ~845 ms to invisible without breaking Nodify's null-unsafe container assumptions.

Trying it out

Requirements: .NET 10 SDK on Windows (WPF).

git clone https://github.com/dhq-boiler/Kata
cd Kata
dotnet build Kata.slnx
dotnet run --project src\Kata.App\Kata.App.csproj
Enter fullscreen mode Exit fullscreen mode

After the app launches, use File β†’ Open Solution to point at any .sln / .slnx. The rendered graph is your live model β€” everything you click on will call back into the source.

If you prefer an installer, the site links to signed Setup.exe / portable zip builds with auto-updates via Velopack.

Licensing

  • Community build β€” PolyForm Noncommercial 1.0.0. Free for personal use, learning, research, hobby projects.
  • Commercial use β€” needs a Pro license (Lemon Squeezy, one-time buyout or per-seat).
  • AI cost β€” you own the Claude / Codex subscription. Kata never bills you for tokens. The monthly quota you'll see in the Community build isn't a cost gate, it's a "please try Pro for heavy workloads" gate.

Roadmap

Near-term:

  • Team Collab β€” team-lead workflows: author a refactor instruction packet, hand it to the team with impact focus visualization and diff previews, get consistent execution across contributors.
  • More language adapters β€” Java is next (in progress), then Kotlin and TypeScript.
  • Beyond class diagrams β€” sequence diagrams and state diagrams, mostly to reuse the same intent-driven refactoring plumbing on a wider slice of the codebase view.

Feedback wanted

Bug reports, especially reproduction samples for C++/CLI mixed solutions, are welcome β€” that's the corner where semantic resolution has the most sharp edges.

If you try it and it puts πŸ’© on the exact class you were already avoiding, I want to hear about that too.

Top comments (0)