{
  "markdown": "# XAF Logic Explainer\n\n[![CI](https://github.com/peopleworks/XAFLogicExplainer/actions/workflows/ci.yml/badge.svg)](https://github.com/peopleworks/XAFLogicExplainer/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/github/license/peopleworks/XAFLogicExplainer?color=blue)](LICENSE)\n[![NuGet CLI](https://img.shields.io/nuget/v/XafLogicExplainer.Cli?logo=nuget&label=CLI)](https://www.nuget.org/packages/XafLogicExplainer.Cli)\n[![NuGet Core](https://img.shields.io/nuget/v/XafLogicExplainer.Core?logo=nuget&label=Core)](https://www.nuget.org/packages/XafLogicExplainer.Core)\n[![NuGet MCP](https://img.shields.io/nuget/v/XafLogicExplainer.Mcp?logo=nuget&label=MCP%20server)](https://www.nuget.org/packages/XafLogicExplainer.Mcp)\n[![.NET 10](https://img.shields.io/badge/.NET-10-512BD4?logo=dotnet&logoColor=white)](https://dotnet.microsoft.com/)\n[![MCP registry](https://img.shields.io/badge/MCP_registry-io.github.peopleworks%2Fxaf--logic--explainer-000000?logo=modelcontextprotocol&logoColor=white)](https://registry.modelcontextprotocol.io/v0/servers?search=xaf-logic-explainer)\n[![Available on CodeGuilds](https://img.shields.io/badge/Available_on-CodeGuilds-6366f1)](https://codeguilds.dev/packages/xaf-logic-explainer)\n[![Listed on Glama](https://img.shields.io/badge/Listed_on-Glama-a855f7)](https://glama.ai/mcp/servers/tnzvgbukeb)\n[![XAF](https://img.shields.io/badge/DevExpress-XAF-FF7200?logo=devexpress&logoColor=white)](https://www.devexpress.com/products/net/application_framework/)\n[![GitHub stars](https://img.shields.io/github/stars/peopleworks/XAFLogicExplainer?style=social)](https://github.com/peopleworks/XAFLogicExplainer/stargazers)\n\n**Teach your AI coding agent what *your* XAF application actually does.**\n\n**[See how it works &rarr;](https://peopleworks.github.io/XAFLogicExplainer/)**\n\nPoint it at an XAF module. It reads your entities, controllers, actions, business rules,\nnavigation and Model Editor customizations straight from source — and hands the result to\nwhatever agent you code with.\n\n---\n\n## Why this exists\n\nDevExpress has done excellent work making AI agents fluent in XAF. Two pieces already exist,\nand this is the third:\n\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/how-it-fits-dark.svg\">\n  <img alt=\"Three kinds of knowledge an agent needs about an XAF codebase. Two are already solved by DevExpress tooling; the third — what your own application does — is the gap this project fills.\" src=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/how-it-fits-light.svg\">\n</picture>\n\n| Teaches the agent… | Tool |\n| --- | --- |\n| How XAF works in general | [DevExpress `agent-skills`](https://github.com/DevExpress/agent-skills) |\n| What the official documentation says | [DevExpress Docs MCP Server](https://docs.devexpress.com/) |\n| **What YOUR application does** | **XAF Logic Explainer** ← *you are here* |\n\nAn agent that has read every page of the XAF documentation still does not know that your `Invoice`\ntotal is calculated from its lines, that `ApproveController` refuses to run when the period is\nclosed, or that three columns were hidden in the Model Editor and appear in no C# file at all. It\nwill confidently invent all three.\n\nThat gap is not solvable by better prompting. It is solvable by extraction.\n\n**These tools compose.** Install the DevExpress skills for framework knowledge, use the Docs MCP\nfor the official reference, and use this for your own codebase. None of them replaces the others.\n\n## What it extracts\n\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/extraction-pipeline-dark.svg\">\n  <img alt=\"Source files are parsed as syntax by Roslyn, never compiled, producing a model rendered to agent files, an MCP server, or Markdown and JSON.\" src=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/extraction-pipeline-light.svg\">\n</picture>\n\nEverything below is read as **syntax**, using Roslyn. Your project never has to compile, and this\ntool never links against DevExpress assemblies:\n\n- **Entities** — properties, types, associations, and the XAF attributes that give them meaning\n  (`[Association]`, `[Aggregated]`, `[RuleRequiredField]`, `[Appearance]`, `[ModelDefault]`, …).\n  **XPO and EF Core**, auto-detected from your `using` statements.\n- **Controllers and actions** — `SimpleAction`, `PopupWindowShowAction`, `SingleChoiceAction`,\n  their target criteria, and the handler code that runs when they fire.\n- **Business rules** — validation attributes and code rules, with the conditions attached.\n- **Module setup** — `ModuleUpdater` seed data and what gets created on first run.\n- **Navigation** — the groups and items your users actually see.\n- **Model Editor (`.xafml`)** — the customizations that exist *only* in XML and are invisible to\n  anyone reading your C#. Module and platform files are merged the way XAF merges them.\n- **Custom property and list editors** — including the JavaScript they cannot work without, and\n  built-in editors reconfigured at run time through `View.CustomizeViewItemControl<T>()`. These\n  live in the platform project *beside* the module, so nobody reading the business objects meets\n  them.\n- **Version-gated migrations** — the `CurrentDBVersion < new Version(…)` blocks in your updater.\n  Each runs at most once for any database, and is the only explanation for data the current code\n  cannot account for.\n- **Reports** — what each one is over, the filter inside its layout, its calculated fields and bound\n  expressions, and the parameters dialog it opens with, down to the `GetCriteria()` that turns the\n  answers into a filter. Read from designer code, from a `.repx`, or from the report's own\n  constructor.\n- **Every screen, and what loads onto it** — see below.\n\nThese are the reason an agent that has read every business class can still be confidently wrong\nabout the application:\n\n<img alt=\"The custom editors section of a generated explainer: a barcode scanner property editor with what it renders, the alias XAF matches on, its base type and the JavaScript file it depends on, followed by built-in editors a controller reconfigures at run time.\" src=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/explainer-editors.png\">\n\n## What runs when you open this screen\n\nNothing in an XAF repository answers that, and both halves are missing for different reasons.\n\n**The screens themselves are in no file.** XAF generates a list, a detail and a lookup view for\nevery business class, plus a list view for every collection, and the Model Editor stores only the\nones somebody changed. Grepping your source for `Patient_Prescriptions_ListView` finds nothing —\nand that is not evidence it is missing.\n\n**Which controllers run there is decided at run time**, by four conditions XAF ANDs together:\nnesting, view type, object type and view id. Each is unrestricted when unset, so a controller that\nsets none of them loads onto *every* screen you have.\n\nThis reads all four the way `ViewController.IsFitToView` evaluates them, against a view inventory\nbuilt from the framework's own id generators — and records **why** each one matched, so the answer\ncan be checked rather than trusted:\n\n<img alt=\"The screens section of a generated explainer, showing the five views XAF generates for one business class. Each names the controllers that activate on it and the condition that made each one match; the framework's own controllers are folded away behind a single line.\" src=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/explainer-screens.png\">\n\nTwo layers, kept apart. What your team wrote gets the full treatment; what XAF provides is folded\naway behind one line, because there is a great deal of it and it is not yours to change. With a\n[ground-truth catalog](#optional-tell-your-code-apart-from-devexpresss) it is named too — scoped to\nthe modules you actually register, so a WinForms controller never appears on a Blazor screen.\n\nWhat it will not claim: a controller listed here can still switch itself off through\n`Active[\"reason\"]`, which depends on the data and the user. This is what XAF **loads** onto a\nscreen, not what will necessarily do something — and anything it could not read from the source is\nlisted apart, with the reason, instead of being quietly treated as \"runs everywhere\".\n\n## The reports are the test of whether you can trust any of this\n\nEvery other section here is a claim that we found something you could not see. This one is the\nopposite, and it is the more useful half.\n\nReports V2 lets your users design reports at run time. Those are stored as **rows in your database**,\nnot as files — so no tool that reads a repository can see them, this one included. An application\nwith forty reports and none in its source is not unusual; it is what a successful reporting setup\nlooks like.\n\nSo the answer changes shape depending on what is knowable:\n\n| Your application | What you are told |\n| --- | --- |\n| No `ReportsModuleV2` | *\"these are all of them\"* — nothing can appear at run time |\n| Module registered, reports in source | *\"this list is a **lower bound**\"* |\n| Module registered, none in source | *\"the true number is **not zero but unknown**\"* |\n\nThat last row is the common case, and it is where a confident tool does real damage. An agent told\n\"this application has no reports\" will design as though none can exist — for an application whose\nusers built forty. `AGENTS.md` says it outright:\n\n> The number is unknown, not zero — do not tell anyone this application has no reports.\n\nThe same rule governs the framework catalog. If the catalog on your machine describes DevExpress\n26.1 and your application declares 23.2, every framework answer says so, with both numbers, rather\nthan being presented as certain.\n\n**A tool that never says \"I cannot see that\" is not more capable. It is less checkable.**\n\n## Quick start\n\n```bash\ndotnet tool install -g XafLogicExplainer.Cli\n\nxaflogic agents --project \"C:\\MySolution\\MyApp.Module\"\n```\n\nThat writes `AGENTS.md`, `CLAUDE.md` and `.github/copilot-instructions.md` at your solution root.\nNo account, no API key, no server. Your agent understands the application on its next question.\n\n### What it writes, and why it is split in two\n\n`AGENTS.md` is prepended to *every* request an agent makes in the repository, so its cost is paid\nforever. Dumping 70 KB of entity detail there would crowd out the actual question. So the output is\ntiered:\n\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/two-tier-context-dark.svg\">\n  <img alt=\"What a full documentation dump costs an agent's context on every request, against the tiered output that leaves that room free.\" src=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/two-tier-context-light.svg\">\n</picture>\n\n\n| | | |\n| --- | --- | --- |\n| `AGENTS.md` | ~11 KB | Always loaded: ground rules, complete inventories, conventions, recipes |\n| `.xaflogic/*.md` | ~70 KB | Opened on demand: full properties, handler code, rule messages, `.xafml` |\n\nThe most valuable part is the smallest. `AGENTS.md` opens with **ground rules** — that this\napplication uses XPO and never EF Core, that the inventories are *complete* so anything absent\ngenuinely does not exist, and that some behavior lives in the Model Editor rather than in C#. Those\nfew paragraphs stop most of the confident invention agents produce about unfamiliar XAF codebases.\n\nExisting files are never clobbered: generated text lives between markers, anything you wrote by\nhand is preserved, and regenerating is byte-identical when nothing changed.\n\n## Or let the agent ask questions directly\n\nGenerated files are a snapshot. The MCP server is a live connection — the agent queries your\napplication while you work on it, and cannot go stale.\n\n```\n/plugin marketplace add peopleworks/XAFLogicExplainer\n/plugin install xaf-logic-explainer@peopleworks-xaf\n```\n\nThat installs a skill and an MCP server in one step. For any other MCP client, either run it\nstraight from NuGet with no install:\n\n```json\n{\n  \"mcpServers\": {\n    \"xaf\": { \"command\": \"dnx\", \"args\": [\"XafLogicExplainer.Mcp\", \"--yes\"] }\n  }\n}\n```\n\n…or point at the CLI if you already have it:\n\n```json\n{ \"mcpServers\": { \"xaf\": { \"command\": \"xaflogic\", \"args\": [\"mcp\"] } } }\n```\n\nStarted from a solution directory it finds the XAF module by itself, so neither form needs a path.\n\n| Tool | Answers |\n| --- | --- |\n| `xaf_overview` | What this application is, and the complete list of everything in it |\n| `xaf_search` | Where a field, concept or business term is defined |\n| `xaf_entity` | Every property, relationship, rule and calculation on one entity |\n| `xaf_controller` | What an action does — including the C# that runs when it fires |\n| `xaf_rules` | What the application validates, computes, hides and disables |\n| `xaf_model` | Model Editor customizations, which exist in no C# file |\n| `xaf_editors` | Custom editors, the JavaScript they need, and built-in editors changed at run time |\n| `xaf_migrations` | What ran once against a live database, and the comment explaining why |\n| `xaf_reports` | What each report is over, the filter inside it, and the dialog it opens with |\n| `xaf_view` | Everything loaded onto one screen — which controllers activate, and why |\n| `xaf_walkthrough` | **How one process works end to end** — what runs, in what order, and what it could not follow |\n| `xaf_refresh` | Re-read the source (changes are detected automatically) |\n\nAsk for something that isn't there and the answer is the useful one:\n\n> There is no entity called 'PurchaseOrder' in this application.\n> This is the complete list of 19 entities, extracted from the whole source tree: …\n> If the user expects 'PurchaseOrder' to exist, it has not been created yet.\n\n**Pair it with the official DevExpress skills.** `/plugin install dx-xaf@DevExpress-agent-skills`\nteaches how XAF works; this teaches what your application does. An agent with only the first will\nwrite correct XAF against entities you do not have.\n\n## The same knowledge, for a person\n\nAn agent reads `AGENTS.md` or queries the MCP server. Someone who has just inherited a ten-year-old\nXAF application needs the same facts arranged very differently:\n\n```bash\nxaflogic explain --project \"C:\\MySolution\\MyApp.Module\" --open\n```\n\nOne HTML file. No server, no build step, no request to the network — it opens from an email\nattachment on a machine with no internet, which is how handovers actually happen.\n\nIt draws **a map of your domain model** from the association attributes scattered across your\ncodebase. Most teams have never seen theirs: it exists in one person's head, which is exactly the\nknowledge that leaves when they do.\n\n![The domain model of a sample XAF application. Hovering an entity dims everything it does not touch, leaving only its own relationships lit — purple where deleting the parent deletes the child.](https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/domain-map.gif)\n\n<sub>Real output, from the sample application in this repository. Hover an entity and everything it\ndoes not touch fades; purple means deleting the parent deletes the child.</sub>\n\nAlongside it: every entity and what each property is, every action with the code it runs,\nvalidation with the message the user will actually see, and the Model Editor settings that appear\nin no C# file.\n\n<img alt=\"An entity card from a generated explainer: every property with its type, the calculated ones marked with the expression behind each, and the relationships whose parent owns the child marked as owned.\" src=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/explainer-entity.png\">\n\nAnd **an index of every criteria expression in the application** — a dialect that is neither SQL\nnor C#, gathered from attributes spread across the source and otherwise collected nowhere:\n\n<img alt=\"The criteria index of a generated explainer: appearance rules, validation and lookup filters in one table, each with the entity and attribute it came from.\" src=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/explainer-criteria.png\">\n\nTry it on the sample without touching your own code:\n\n```bash\nxaflogic explain --project tests/XafLogicExplainer.Tests/Fixtures/DemoSolution/PharmacyDemo.Module --open\n```\n\n## The question one application cannot answer\n\nYou have delivered XAF applications to clients for ten years. Somewhere in there you already\nmodelled the class you are about to write again, and you cannot remember which project it was in.\n\n```bash\nxaflogic projects add --name pwLegalOffice --project \"C:\\Clients\\Legal\\pwLegalOffice.Module\"\nxaflogic projects add --name Presupuesto   --project \"C:\\Clients\\Budget\\PWPresupuesto.Module\"\nxaflogic wiki --open\n```\n\nOne HTML file over **all of them**, and a section that exists in no single-project tool:\n\n- **Classes you modelled more than once** — with a property-by-property comparison, so you can see\n  which application models `Cliente` in the most detail before writing it a fourth time.\n- **The layer you wrote yourself** — base classes carried from one application into another. Your\n  own framework, the one that was never written down. A base class is listed only when its own\n  source was read in one of the projects, so nothing is matched against a list of DevExpress type\n  names that would rot at the next release.\n- **The same name, two shapes** — where `Total` is a `decimal` in one application and a `double`\n  in another. Nothing is broken; each one compiles. It is how a total ends up two cents out.\n- **Names you keep** — the vocabulary of your applications, which nobody wrote down and everybody\n  who joins has to learn by reading code.\n\nAnd a map of the whole estate, drawn from the same reading:\n\n<img alt=\"Three client applications on a ring, with the classes all three model drawn between them: AuditedEntity, Cliente and Factura sit at the centre, joined by a line to each application.\" src=\"https://raw.githubusercontent.com/peopleworks/XAFLogicExplainer/main/docs/assets/corpus-map.svg\" width=\"100%\">\n\n<sub>Real output, from the three sample client modules in this repository. Each class sits at the\naverage direction of the applications that model it, at a distance set by how much they agree — so\na class every application has falls to the centre. The middle is your common ground; the rim is the\nwork that belongs to one client.</sub>\n\nBeside it, two more that only a corpus can produce: **which two of your projects are most alike**,\nas a grid you can click to hold the page to just those two, and **the DevExpress releases your\nestate is spread across** — with the one your framework catalog actually describes marked, so every\nclaim about DevExpress types says whether it was checked against the right release.\n\nEverything in it is computed from what was read. There is no place in the page to put a sentence\nsomebody typed about the corpus, because a hand-written summary of nine applications is wrong the\nday the tenth is added and nobody notices.\n\nFilter by any project to see only what it has in common with the rest. And the honest part is on\nthe page too: two classes are matched **by name**, so the wiki tells you they share a name — the\ncomparison is what tells you whether they share an idea.\n\n## The same knowledge, as a document\n\nYou arrive at an XAF project you have never seen and, half a day later, hand someone a document\nabout it. The last step is not this tool's. `xaflogic extract` writes Markdown, and\n[mcpOffice](https://github.com/MBrekhof/mcpOffice) — an MCP server built on the DevExpress Office\nFile API — turns Markdown into `.docx` and `.docx` into PDF. With both servers connected, the agent\nhands one to the other. There is no Word exporter here and there will not be one\n([#28](https://github.com/peopleworks/XAFLogicExplainer/issues/28)): reading an XAF application\nneeds no DevExpress, and that stays true.\n\n```bash\nxaflogic extract --project \"C:\\MySolution\\MyApp.Module\"\n# writes .xaflogic-output/MyApp_Full.md, and one file per section beside it\n```\n\nThen, to the agent:\n\n> Turn `.xaflogic-output/MyApp_Entities.md` into a Word document with `word_create_from_markdown`,\n> then `word_convert` it to PDF.\n\nHand over a section file rather than `_Full.md` when the reader is one audience: `_Entities.md` is\nthe data dictionary, `_BusinessRules.md` the rules, `_Controllers.md` what the buttons do.\n`word_create_from_markdown` takes a `templatePath`, so headings, tables, header and footer can come\nfrom your own `.dotx`.\n\nVerified on the sample application in this repository: every heading becomes a Word heading and\nappears in the document outline, the property tables become real tables, fenced C# becomes shaded\nmonospace, and lists, bold and inline code survive. Nothing in the generated Markdown is HTML, and\n[a test](tests/XafLogicExplainer.Tests/PortableMarkdownTests.cs) keeps it that way.\n\nmcpOffice needs a DevExpress licence, because it writes Office files with DevExpress's API. If you\nrun an XAF application, you have one. Setup is in\n[its usage guide](https://github.com/MBrekhof/mcpOffice/blob/main/docs/usage.md).\n\n## Optional: tell your code apart from DevExpress's\n\nExtraction reads your source without knowing anything about the framework it is written against,\nwhich leaves one question unanswerable: is `DeleteObjectsViewController` something your team wrote,\nor something DevExpress ships? Without an answer, generated documentation presents framework\nbehavior and your own logic as the same thing.\n\nIf you have a DevExpress licence:\n\n```bash\nxaflogic catalog build\n```\n\nThat reads **your own installation** and records what XAF itself provides — attributes, controllers,\nmodel interfaces and modules, with the official summaries and documentation links DevExpress ships.\nOn DevExpress 26.1 that is around 850 framework types.\n\nIf you also installed the DevExpress **source code** component, it records *where each framework\ncontroller activates* — the four conditions XAF checks before running it. That cannot be read from\nthe assemblies: four out of five built-in controllers set their target inside a constructor. Pass\n`--dx-sources <Components/Sources>` if they are not beside your assemblies.\n\nExtraction then picks it up automatically and can say things it otherwise could not:\n\n- *\"`ArchiveController` extends the built-in `DeleteObjectsViewController`\"* — you are changing how\n  deletion works application-wide, not adding a feature beside it.\n- *\"`[AuditedByFinance]` is not an XAF or .NET attribute\"* — your team invented it, so its meaning\n  lives in this codebase and in no documentation anywhere.\n- *\"32 framework controllers also load onto this screen\"* — named, with what each one does, and\n  scoped to the modules your application actually registers, so a WinForms controller never appears\n  on a Blazor screen.\n\nThe catalog is written to `~/.xaflogic/catalog/`, **never into your repository**: it is derived from\nlicensed software. Everything works without it — it only sharpens the output. See\n[NOTICE.md](NOTICE.md).\n\n### Commands\n\n| Command | What it does |\n| --- | --- |\n| `agents` | **Write `AGENTS.md` / `CLAUDE.md` / Copilot instructions for your agent** |\n| `mcp` | **Run as an MCP server so agents can query the app live** |\n| `explain` | **Write a self-contained HTML page explaining the app to a person** |\n| `wiki` | **Read every project together and say what they have in common** |\n| `catalog` | Build the DevExpress ground-truth catalog (`build`, `status`) |\n| `extract` | Read the project, write Markdown + JSON locally |\n| `walkthrough` | **Trace one business process** — what runs, in what order, and what governs it |\n| `diff` | Compare against the previous extraction and report what changed |\n| `status` | Show the change-detection hash and whether a re-extract is needed |\n| `watch` | Re-extract on file change, with debounce |\n| `sync` | Extract and publish to a remote target |\n| `chat` | Ask questions about the extracted project |\n| `config` | Set defaults in `~/.xaflogic/config.json` |\n| `projects` | Manage several XAF projects; most commands accept `--all` |\n\nDocumentation is generated in **English or Spanish** (`--lang en|es`).\n\nUseful flags: `--orm auto\\|xpo\\|efcore`, `--lang en\\|es`, `--enrich` (AI-generated business-logic\nsummaries per controller and action), `--force`, `--all`.\n\n### Tracing one process\n\n```bash\nxaflogic walkthrough --from ApproveOrder            # to the screen, or > process.md\nxaflogic walkthrough --from ApproveOrder --depth 4 --out docs/approval.md\n```\n\nWhat runs, in what order, which entities it touches and which rules govern them — every step citing\n`file:line`, with a Mermaid diagram **emitted from the trace itself, never drawn by a model.** Calls\nthe trace could not follow are listed rather than skipped, so an empty list means the path really is\ncomplete. Add `--narrate` for prose over the steps; a paragraph that cannot name a real step is\ndropped before you see it.\n\n```bash\nxaflogic walkthrough --from ApproveOrder --since        # against the last extraction\n```\n\n`--since` re-walks the same process over a stored snapshot and reports what is different about\n**this** process: a step added, a rule now governing it, a body rewritten, a branch gone, a call the\ntrace can no longer follow. No conversational agent can answer that, because none of them has a\nyesterday.\n\n`--enrich` and `--narrate` need a model, and **any of these is enough** — a key on the command line\nwins, then the environment, then a PeopleWorks Copilot account if you happen to have one:\n\n```bash\nxaflogic extract --enrich --api-key sk-...              # or any OpenAI-compatible endpoint:\nxaflogic extract --enrich --api-key ... --ai-base-url http://localhost:11434/v1 --ai-model qwen2.5-coder\n\nexport OPENAI_API_KEY=sk-...        # picked up with no configuration at all\nexport ANTHROPIC_API_KEY=sk-ant-...\n```\n\nEverything else in this tool runs with no key, no account and no network — the walkthrough\nincluded, minus its prose.\n\nExtraction is **incremental** — a SHA-256 over your `.cs` and `.xafml` files means an unchanged\nproject is a no-op. There is an MSBuild `.targets` file if you want it to run on build.\n\n## Status\n\n**v0.17.0.** The extraction engine is the mature part: it runs in production against real XAF\napplications. The agent-facing surface is what is landing now, in the open.\n\n| | |\n| --- | --- |\n| ✅ | Roslyn extraction — entities, controllers, rules, updater, navigation, `.xafml` |\n| ✅ | XPO and EF Core, auto-detected |\n| ✅ | **Custom property and list editors**, their client assets, and built-in editors reconfigured at run time |\n| ✅ | **Version-gated data migrations** — what happened to databases that were not fresh |\n| ✅ | Incremental change detection, diff reports, multi-project, watch mode |\n| ✅ | **Walkthrough** — one process traced end to end, with a diagram emitted from the trace, the calls it could not follow, and `--since` |\n| ✅ | AI enrichment of controllers and actions (`--enrich`) |\n| ✅ | Blazor in-app help panel |\n| ✅ | **`AGENTS.md` / `CLAUDE.md` / Copilot instructions** — zero infrastructure, works for everyone |\n| ✅ | **`xaflogic explain`** — one self-contained HTML page, for a person rather than an agent |\n| ✅ | **`xaflogic wiki`** — every project in one page, and what they have in common |\n| ✅ | Pluggable publishing targets (`IDocumentationSink`) |\n| ✅ | **MCP server** — 12 tools, live against your source |\n| ✅ | **Installable Claude Code plugin** with skill and MCP server |\n| ✅ | **556 tests** over synthetic XPO and EF Core fixtures — no DevExpress needed |\n| ✅ | **DevExpress ground-truth catalog**, generated locally by licensees |\n\nPeopleWorks Copilot, where this tool grew up, is now one sink among several rather than the\ndestination everything was built around. The outputs that matter most need no server at all.\n\n## The long version\n\nWhy a third of an XAF application's behaviour lives outside its business classes, the four places\nit hides, and what the extracted output actually looks like:\n\n- **[Your coding agent knows XAF. It has never seen your application.](https://peopleworksgpt.com/your-coding-agent-knows-xaf-it-has-never-seen-your-application/)**\n- **[Tu agente de código sabe XAF. Nunca ha visto tu aplicación.](https://peopleworks.com.do/2026/08/13/tu-agente-de-codigo-sabe-xaf-nunca-ha-visto-tu-aplicacion/)** — *en español*\n\nEach is written in its own language rather than translated from the other. Sources in\n[`docs/Blog/`](docs/Blog/).\n\n## Repository layout\n\n```\nsrc/\n  XafLogicExplainer.Core                 Roslyn extraction engine — no DevExpress reference\n  XafLogicExplainer.Mcp                  MCP server (ModelContextProtocol 2.1)\n  XafLogicExplainer.Cli                  the `xaflogic` command\n  XafLogicExplainer.CopilotSync          PeopleWorks Copilot target + AI enrichment\n  XafLogicExplainer.DescriptionAnnotator generates missing [Description] attributes\n  XafLogicExplainer.Blazor               in-app help panel for XAF Blazor apps\nplugins/\n  xaf-logic-explainer                    the installable Claude Code plugin\n```\n\nBuilt on **.NET 10**.\n\nOnly `XafLogicExplainer.Blazor` references DevExpress packages; it needs the DevExpress NuGet feed\nand a license to build. Everything else builds anywhere, which is why CI can verify it for free.\n\n## Contributing\n\nThe single most valuable contribution is telling us **what the extractor missed**. XAF is enormous,\nevery codebase uses a different slice of it, and no single project exercises the whole framework.\nThere is an [extraction-gap issue template](.github/ISSUE_TEMPLATE/extraction-gap.yml) for exactly\nthis: show the XAF pattern your project uses and what the tool failed to see.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md). Bug reports, docs and translations are equally welcome.\n\n## License\n\n[MIT](LICENSE). See [NOTICE.md](NOTICE.md) for the relationship to DevExpress.\n\nAn independent community project — not affiliated with, endorsed by, or supported by\nDeveloper Express Inc. It contains no DevExpress source code and needs no DevExpress license to\nbuild or run. *DevExpress*, *XAF* and *eXpressApp Framework* are trademarks of Developer Express Inc.\n\nBuilt by [Pedro Hernández](https://github.com/peopleworks) (PeopleWorks),\n[Microsoft MVP for .NET](https://mvp.microsoft.com/en-US/mvp/profile/24060a02-dbc6-44ec-bca5-c213ff9835c5) —\nfor the DevExpress and XAF community.\n",
  "bytes": 30782,
  "sha": "e1a18192e8aacff3e2d8b9216fcebae2306b8479fa40f84f6f0bc7b31d932b55",
  "repo_slug": "peopleworks/xaflogicexplainer",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_peopleworks_xaf_logic_explaine_70f995db/readme"
}