Skip to content

Releases: mendixlabs/mxcli

v0.13.0

20 Jun 10:45

Choose a tag to compare

[0.13.0] - 2026-06-20

Headline: the roundtrip codec engine is now the default. Reads and writes route through the new modelsdk codec engine — a Go-native, roundtrip-safe metamodel codec spanning 53 domains — replacing the legacy sdk/mpr write path. Legacy remains available as an explicit --engine legacy (or MXCLI_ENGINE=legacy) fallback for the few constructs the codec can't yet reproduce (e.g. SOAP), and refuses an op rather than dropping data where it can't. This release also lands an experimental MCP/PED backend for authoring against a running Studio Pro.

A big thank-you to engalar. The roundtrip codec engine and the expression type-checker that anchor this release are built on his contributions — his modelsdk codec work (the 53-domain, roundtrip-safe metamodel implementation) and exprcheck port were cherry-picked and adapted here. Much of what makes v0.13.0 possible is his. Thank you!

Added

  • Experimental MCP/PED backend (mxcli mcp) — author Mendix models against a running Studio Pro over the Model Edit Protocol (PED/MCP) transport, instead of writing the .mpr on disk. mxcli mcp capabilities reports what the connected Studio Pro version supports (a version-keyed capability registry), and CREATE/ALTER ops are gated on that model — unsupported constructs are refused with an actionable message rather than silently dropped. Covers entity create/update with NOT NULL / UNIQUE validation rules, ALTER ENTITY ADD ATTRIBUTE, ALTER STYLING design properties, page authoring (typed params, edit-button actions, design properties), folder placement, and business-event/workflow reads. Honoured in both exec and the interactive REPL (--mcp). Verified against Studio Pro 11.11.

  • Graph community detection & centrality (refresh catalog communities) — a pure-Go (no CGO, no deps) graph engine over the refs graph: Leiden community detection, Tarjan cycles, topological layering, PageRank, and betweenness. refresh catalog communities [resolution n] computes them (in the full-refresh transaction) into new catalog tables/views — communities + community_summary, graph_cycles, graph_layers, graph_centrality, graph_integration_surface (cross-community edges → OData/REST/event mechanisms), graph_module_dependencies — and adds PageRank/betweenness columns to graph_god_nodes. Surfaced via SHOW COMMUNITIES / SHOW COMMUNITY [MEMBERS] OF Module.Asset, and exposed to Starlark lint rules (community_of, layer_of, cycles, module_dependencies, centrality, god_nodes, integration_surface, refs_from) so teams validate their own architecture guidelines. The native Leiden matches the leidenalg reference exactly (105 communities on Evora). Targets two refactoring journeys: spaghetti → layered/modular (cycles + layer sequence numbers) and monolith → multi-app (community cut → integration-contract list).

  • mxcli graph-report — architecture map from the dependency graph — renders six analyses over new CATALOG.graph_* views: god nodes (degree centrality), cross-module coupling ("surprise edges"), module cohesion (intra/inter ratio), dead documents (no inbound edge), the reference-kind distribution, and entity hotspots (used by the most flows). Framework/marketplace modules are excluded by default (--include-framework to keep them); --top N, --format markdown|json, -o file. Each section is a thin SELECT over a graph_* view, so it's reproducible directly (select * from CATALOG.graph_god_nodes). Built on the now-substantially-complete refs graph; requires refresh catalog full (the command runs it). Also made CATALOG.<name> query translation generic (regex strip) so new catalog views work without a per-name allowlist.

  • Marketplace download & install — the content API now returns a per-version downloadUrl, so the previously-parked install path is unblocked. mxcli marketplace download <id> [--version X] [-o file] fetches a content version's .mpk (two-step: MxToken-authed 303 on marketplace.mendix.com → public CDN, no token sent to the CDN). mxcli marketplace install <id> -p app.mpr is type-aware: widgets are copied into widgets/, new modules are imported via mx module-import, other types are downloaded with import instructions. Module updates are intentionally reported-not-applied — re-importing an existing module would discard local edits and change persistent-entity IDs (data loss); that path is left to Studio Pro pending an ID-preserving merge

  • Marketplace search caching — the first mxcli marketplace search fetches the full catalog listing once and caches it under ~/.mxcli/marketplace-catalog-<profile>.json (24h TTL, mode 0600); subsequent searches (any keyword) are served from the cache instantly. --refresh bypasses the cache and re-fetches. An interactive progress line ("Searching marketplace… N items scanned") shows during a fresh scan

  • describe auto-detects the document type — the type is now optional for a qualified name: mxcli describe MyModule.Customer resolves the type itself (entity, microflow, page, snippet, enumeration, constant, java action, nanoflow, workflow, association incl. cross-module, …). Resolution prefers the catalog cache (O(1) lookup, no overhead vs. the explicit form) and falls back to a live project scan when the catalog is absent. An ambiguous name (e.g. an entity and a microflow sharing a name) is reported with its candidates. The explicit describe <type> <name> form is unchanged, and is still required for the forms that have no single qualified name (module, settings, navigation, module role)

  • Bare describe Module.Name works as MDL, not just as a CLI flag — the auto-detect form is now part of the MDL grammar, so it parses and runs everywhere MDL does: the REPL, exec scripts, check, and the LSP (previously describe Sales.Order in the REPL was a parse error and only mxcli describe Sales.Order worked). The bare form resolves the type from the project's catalog objects index at execution time (built on demand, fresh — no staleness concern); all typed describe <type> … forms still take precedence, and an ambiguous or unknown name returns an actionable error

  • Pop-up page geometryCREATE PAGE and ALTER PAGE can now set a pop-up page's width, height, and resizable in the page header (#661). DESCRIBE PAGE round-trips them.

  • Compound (nested) design properties — design properties on pages and snippets that nest (a group containing sub-properties) are now written and round-tripped by DESCRIBE PAGE/DESCRIBE STYLING, on both the codec engine and over MCP (#668)

  • Quoted identifiers in member lists and attribute refs — names that collide with MDL reserved words can now be quoted in member lists and attribute references (#675), extending the reserved-word-quoting support to more positions (DESCRIBE emitters now quote reserved-word names in the remaining strict-identifier spots, #619)

Changed

  • The codec engine (modelsdk) is the default; sdk/mpr is the explicit fallback — all reads and writes now route through the roundtrip codec engine by default. The legacy path is reachable via --engine legacy or MXCLI_ENGINE=legacy for the constructs the codec can't yet reproduce (notably SOAP); where the codec path can't reproduce a construct it refuses the op rather than dropping data. This is the culmination of the Issue 7 parity effort that brought every document type — domain models, microflows, pages, workflows, security, REST/OData, agent-editor docs, settings, and more — to mx check parity on the codec path.

  • Catalog objects index includes associations — the unified objects view now unions the associations table (ObjectType = ASSOCIATION), so it is a complete index for the cataloged document types and consumers no longer need a separate associations query. Catalog schema bumped to v3; cached .mxcli/catalog.db files rebuild automatically on the next refresh catalog.

  • Catalog indexes image collections, JavaScript actions, and data transformers — these document types had no catalog table at all; they are now built (via the raw-unit surface, so no CatalogReader/backend change) into their own tables and unioned into objects (IMAGE_COLLECTION, JAVASCRIPT_ACTION, DATA_TRANSFORMER). describe auto-detect resolves image collections and data transformers by bare name. Catalog schema bumped to v4.

  • Catalog indexes agent-editor documents — agents, AI models, knowledge bases, and consumed MCP services (one shared CustomBlobDocuments$CustomBlobDocument BSON wrapper, distinguished by CustomDocumentType) are now cataloged into their own tables and unioned into objects (AGENT, AI_MODEL, KNOWLEDGE_BASE, CONSUMED_MCP_SERVICE). The document name turned out to be a top-level wrapper field (not buried in the inner JSON blob), so this reads through the raw-unit surface with no CatalogReader/backend change, and describe auto-detect resolves all four by bare name. Catalog schema bumped to v5; this completes the objects index for the document types tracked in #658. (Verified against test3-app: 8 agent-editor docs across all four types.)

Fixed

  • Page authoring fidelity — several page constructs that were silently dropped or mis-stored are fixed: DYNAMICTEXT Attribute bindings are no longer dropped (#650); ALTER PAGE can set conditional Visible/Editable expressions without tripping CE0117 (#627); a ComboBox datasource property that was silently dropped is now caught at check time (#643); a quoted where '<xpath>' constraint is no longer mis-stored as CE0161 (#642); and gallery DesktopColumns + class are honoured on pluggable widgets.
  • check catches more page errors — forward widget→page references (#674) and invalid static widget values (#672, #673) are now flagged at check time instead of surfacing later in Studi...
Read more

v0.12.0

04 Jun 13:21

Choose a tag to compare

What's Changed

  • fix #583: parse StringAttributeType.Length across BSON numeric widths by @ako in #584
  • fix: CREATE ODATA CLIENT strips uppercase MICROFLOW keyword prefix (#573) by @ako in #586
  • fix #585: parse remaining numeric BSON fields across all numeric widths by @ako in #587
  • fix: ALTER STYLING writes design properties on pages and snippets (#631) by @peterjumpnl in #632
  • deps: bump github.com/mattn/go-runewidth from 0.0.23 to 0.0.24 by @dependabot[bot] in #611
  • deps: bump modernc.org/sqlite from 1.50.1 to 1.51.0 by @dependabot[bot] in #612
  • deps: bump github.com/alecthomas/chroma/v2 from 2.24.1 to 2.26.1 by @dependabot[bot] in #613

Full Changelog: v0.11.0...v0.12.0

v0.11.0

21 May 18:09

Choose a tag to compare

What's Changed

  • deps: bump modernc.org/sqlite from 1.50.0 to 1.50.1 by @dependabot[bot] in #562

Full Changelog: v0.10.0...v0.11.0

v0.10.0

12 May 15:54

Choose a tag to compare

What's Changed

  • deps: bump github.com/fsnotify/fsnotify from 1.10.0 to 1.10.1 by @dependabot[bot] in #537
  • deps: bump golang.org/x/term from 0.42.0 to 0.43.0 by @dependabot[bot] in #536
  • ci: bump actions/cache from 4 to 5 by @dependabot[bot] in #535

Full Changelog: v0.9.0...v0.10.0

v0.9.0

08 May 16:38

Choose a tag to compare

What's Changed

  • fix: skip System.* references in mxcli check --references by @hjotha in #523
  • fix: classify reverse-Reference traversal through entity inheritance by @hjotha in #522
  • feat: support inheritance split and cast statements by @hjotha in #365
  • Pull by @ako in #531
  • fix: roundtrip REST mapping cardinality via as list of syntax by @hjotha in #519
  • fix: emit "empty" keyword for typed Java action arguments by @hjotha in #521
  • fix: prevent catalog crash on duplicate business event channels by @dhruvbehl in #533

New Contributors

Full Changelog: v0.8.0...v0.9.0

v0.8.0

05 May 06:40

Choose a tag to compare

What's Changed

  • Misc by @ako in #247
  • fix: handle missing TaskPage key in workflow activity mutation by @retran in #243
  • Add test enablers: MockPageMutator, MockWorkflowMutator, registry completeness by @retran in #244
  • test: add visitor tests for 20 untested source files by @retran in #245
  • fix: make workflow mutator property lookup case-insensitive; fix REST… by @ako in #248
  • feat: Support local file metadata for OData clients by @dionesiusap in #210
  • feat: add mxcli catalog search and show commands by @dionesiusap in #218
  • feat: support full user targeting on workflow USER TASK (fixes #169) by @ako in #251
  • feat: self-describing syntax feature registry for LLM-friendly help discovery by @ako in #252
  • test: add mock tests for 8 executor handler files by @retran in #253
  • test: expand mock tests for 28 executor handler files by @retran in #254
  • test(linter): add unit tests for all 14 untested linter rules by @retran in #255
  • test(catalog): add unit tests for builder pure helper functions by @retran in #256
  • fix: preserve MPR v1 contents hash and UnitID across DROP+CREATE by @hjotha in #258
  • Misc by @ako in #269
  • fix: accept qualified function calls in expression parser by @hjotha in #259
  • fix: normalise built-in Mendix function case in expression roundtrip by @hjotha in #260
  • fix: gate Mx 9 microflow roundtrip keys by project version by @hjotha in #261
  • fix: treat terminal nested IF as returning in flow builder by @hjotha in #262
  • fix: preserve decision/loop captions across nested control flow by @hjotha in #263
  • fix: preserve rule-based decision subtype across microflow roundtrips by @hjotha in #265
  • fix: preserve rule split describer output and free annotations by @hjotha in #266
  • fix: correct microflow body syntax in bug-test 258 by @hjotha in #270
  • fix: DESCRIBE PAGE recurses into ScrollContainer / TabControl children by @hjotha in #271
  • Misc by @ako in #278
  • fix: support log node expressions and harden microflow describe roundtrip by @hjotha in #264
  • fix: stabilize MDL roundtrip and integration test harness by @hjotha in #267
  • refactor: remove ExecContext.executor back-pointer by @retran in #274
  • feat: @anchor annotation for microflow sequence flow endpoints by @hjotha in #276
  • refactor: extract CatalogDB interface for WASM portability by @retran in #277
  • deps: bump github.com/jackc/pgx/v5 from 5.9.1 to 5.9.2 by @dependabot[bot] in #284
  • feat: import consumed REST client from OpenAPI 3.0 spec by @ako in #286
  • fix: create OpenApiTest module before use in openapi-import doctype test by @ako in #288
  • fix: preserve change-member name when entity type is unknown (#282) by @hjotha in #283
  • fix: traverse through unpaired ExclusiveMerge in describe (#281) by @hjotha in #285
  • refactor: quick-win cleanup — panic stubs, SaveToFile, dead code, error handling, syncWriter by @retran in #287
  • refactor: introduce LintReader interface, decouple linter from sdk/mpr by @retran in #289
  • refactor: add type-safe BSON helpers in writer_security by @retran in #297
  • deps: bump modernc.org/sqlite from 1.48.2 to 1.49.1 by @dependabot[bot] in #300
  • fix: drop empty else branch from describer output by @hjotha in #305
  • fix: preserve commit error handling through describe/exec/describe by @hjotha in #309
  • fix: honor branch anchor destination on split-to-merge flows by @hjotha in #311
  • fix: skip reference checks for excluded microflows by @hjotha in #313
  • feat(executor): allow MXCLI_EXEC_TIMEOUT to override the per-statement timeout by @hjotha in #315
  • refactor: extract microflow anchor selection helpers by @hjotha in #325
  • feat: support microflow download file statement by @hjotha in #333
  • fix: write valid show-page parameter mappings by @hjotha in #338
  • fix: refresh empty change-object actions by @hjotha in #340
  • fix: preserve microflow-call BSON field order by @hjotha in #342
  • fix: preserve compact reverse-association retrieves by @hjotha in #356
  • fix: emit ResultHandlingHttpResponse for REST 'returns response' by @hjotha in #378
  • fix: write REST HttpResponse result variable type by @hjotha in #376
  • fix: write valid change-action item storage lists by @hjotha in #374
  • fix: emit list retrieve for owner-both reverse references by @hjotha in #381
  • fix: preserve void EndEvent returns in describe by @hjotha in #371
  • fix: infer java action result variable types by @hjotha in #357
  • fix: register import mapping result variable types by @hjotha in #360
  • fix: preserve object-valued owner-both reverse retrieves by @hjotha in #384
  • fix: preserve manual while-true loop roundtrips by @hjotha in #354
  • feat: full nanoflow support — CREATE, DROP, SHOW, DESCRIBE, DIFF, MERMAID, security, and agentic skill by @retran in #301
  • fix(writer): drop synthetic trailing newline from EndEvent ReturnValue by @hjotha in #317
  • feat: support free microflow annotations by @hjotha in #319
  • fix: do not emit annotations before unsupported-action comments by @hjotha in #307
  • fix: suppress default anchor fragments in describe by @hjotha in #321
  • fix: preserve multiline source expression whitespace by @hjotha in #323
  • fix: pair microflow splits with nearest merge by @hjotha in #327
  • fix: preserve nested loop body flow traversal by @hjotha in #329
  • feat: preserve change object refresh modifier by @hjotha in #363
  • feat: support legacy microflow call web service statement by @hjotha in #334
  • fix: preserve attribute-based list operations by @hjotha in #344
  • fix: preserve incoming anchors for inheritance splits by @hjotha in #454
  • fix: emit loop captions during microflow describe by @hjotha in #444
  • test: cover empty EndEvent return serialization by @hjotha in #446
  • feat: support enum split microflow statements by @hjotha in #364
  • fix: preserve mapping result range cardinality by @hjotha in #372
  • feat: support empty Java action arguments by @hjotha in #336
  • fix: preserve no-merge branch continuations by @hjotha in #355
  • deps: bump github.com/microsoft/go-mssqldb from 1.9.8 to 1.10.0 by @dependabot[bot] in #485
  • deps: bump go.uber.org/zap from 1.27.1 to 1.28.0 by @dependabot[bot] in #484
  • deps: bump github.com/fsnotify/fsnotify from 1.9.0 to 1.10.0 by @dependabot[bot] in #483
  • deps: bump github.com/alecthomas/chroma/v2 from 2.23.1 to 2.24.1 by @dependabot[bot] in #482
  • deps: bump modernc.org/sqlite from 1.49.1 to 1.50.0 by @dependabot[bot] in #481
  • fix: preserve annotations attached inside loop bodies by @hjotha in #331
  • fix: stabilize integration CI baseline by @hjotha in #412
  • fix: reject duplicate microflow output variables by @hjotha in #337
  • fix: p...
Read more

v0.7.0

21 Apr 08:35

Choose a tag to compare

What's Changed

  • fix: resolve page context tree for ALTER PAGE and check --references by @engalar in #158
  • fix: docker cache detection on Windows and reload schema warning by @engalar in #160
  • feat: workflow microflow actions and COMPLETE_TASK page action by @engalar in #159
  • feat: generate .gitignore for Mendix projects during init by @engalar in #163
  • fix: run mx update-widgets before mx check to prevent false CE0463 by @engalar in #164
  • fix: association navigation expression missing target entity and extra spaces by @engalar in #165
  • fix: augment nested ObjectType properties from .mpk to prevent CE0463 by @engalar in #166
  • feat: add data container context hints to DESCRIBE PAGE by @engalar in #168
  • fix: strip REST path slashes and validate microflow param entity refs by @engalar in #170
  • deps: bump github.com/mattn/go-runewidth from 0.0.22 to 0.0.23 by @dependabot[bot] in #187
  • deps: bump modernc.org/sqlite from 1.48.1 to 1.48.2 by @dependabot[bot] in #188
  • fix: emit correct enum value format for XPath vs expression contexts by @engalar in #167
  • fix: remove broken GRANT/REVOKE EXECUTE ON WORKFLOW by @engalar in #173
  • fix: improve data container context hints and LSP completion by @engalar in #184
  • fix: add 168 missing lexer tokens to keyword rule by @engalar in #186
  • fix: support @Module.Const syntax in expressions by @engalar in #179
  • fix: prefer Studio Pro over CDN downloads on Windows by @engalar in #195
  • fix: microflow layout issues (ConnectionIndex, redundant Merge, DESCRIBE roundtrip) by @engalar in #204
  • fix: skip Attribute fallback for custom-content datagrid columns by @ako in #208
  • docs: add mxcli-dev contributor command namespace and /mxcli-dev:review by @yscraft in #220
  • fix: route path/query params correctly and suppress BodyVariable for JSON bodies in SEND REST REQUEST by @yscraft in #215
  • docs: add fix-issue skill with TDD protocol and symptom→layer table by @yscraft in #216
  • feat: add typed error system for executor by @retran in #222
  • feat: dispatch registry, backend interfaces, and MockBackend by @retran in #224
  • docs: add fork PR flow diagram to CONTRIBUTING.md by @yscraft in #223
  • ci: bump softprops/action-gh-release from 2 to 3 by @dependabot[bot] in #226
  • ci: bump actions/upload-pages-artifact from 4 to 5 by @dependabot[bot] in #227
  • refactor: migrate executor handlers to free functions with ExecContext by @retran in #225
  • Context & catalog isolation — ExecContext gains Backend, handlers decoupled from mpr by @retran in #229
  • deps: bump github.com/spf13/pflag from 1.0.9 to 1.0.10 by @dependabot[bot] in #228
  • feat: add comprehensive mock-based handler tests (189 tests) by @retran in #232
  • refactor: extract shared types and utility functions to mdl/types by @retran in #235
  • refactor: define mutation backend interfaces by @retran in #236
  • refactor: implement mutation backends and migrate handlers by @retran in #237
  • refactor: decouple executor from storage layer by @retran in #238
  • refactor: code quality — deterministic output, doc comments, naming by @retran in #239

New Contributors

Full Changelog: v0.6.0...v0.7.0

v0.6.0

09 Apr 16:13

Choose a tag to compare

What's Changed

  • feat: ALTER WORKFLOW command with full activity manipulation by @engalar in #107
  • fix: align BSON properties with Mendix schema for mx diff compatibility by @engalar in #109
  • feat: add virtual System module for complete module listing by @engalar in #110
  • fix(security): validate demo user password against project policy by @engalar in #140
  • refactor: split 5 large files into smaller modules by @engalar in #141

Full Changelog: v0.5.0...v0.6.0

v0.5.0

06 Apr 12:52

Choose a tag to compare

What's Changed

  • fix: int32→int64 for BSON property values by @engalar in #71
  • fix: CREATE OR REPLACE PAGE reuses existing UUID by @engalar in #72
  • feat: diag --check-units + grammar fixes by @engalar in #67
  • feat: SHOW/DESCRIBE/CREATE/DROP JSON STRUCTURE by @peterjumpnl in #80
  • docs: MDL i18n design proposal by @engalar in #87
  • ci: bump actions/deploy-pages from 4 to 5 by @dependabot[bot] in #92
  • ci: bump actions/checkout from 4 to 6 by @dependabot[bot] in #93
  • ci: bump actions/upload-pages-artifact from 3 to 4 by @dependabot[bot] in #94
  • deps: bump github.com/mattn/go-runewidth from 0.0.21 to 0.0.22 by @dependabot[bot] in #95
  • deps: bump @vscode/vsce from 2.32.0 to 3.7.1 in /vscode-mdl by @dependabot[bot] in #96
  • deps: bump modernc.org/sqlite from 1.48.0 to 1.48.1 by @dependabot[bot] in #97
  • deps: bump typescript from 5.9.3 to 6.0.2 in /vscode-mdl by @dependabot[bot] in #99
  • deps: Bump esbuild from 0.27.7 to 0.28.0 in /vscode-mdl by @dependabot[bot] in #98
  • fix: remove invalid ParentConnection/ChildConnection from CrossAssociation BSON (#50) by @engalar in #105
  • docs: workflow improvements design proposal by @engalar in #88
  • feat: pluggable widget engine v2 by @engalar in #68
  • feat: WidgetDemo baseline by @engalar in #69

New Contributors

Full Changelog: v0.4.0...v0.5.0

v0.4.0

01 Apr 06:54

Choose a tag to compare

What's Changed

  • Fix batch of reported issues (#18, #19, #23, #25, #26, #27, #28) by @engalar in #35
  • feat(tui): add agent channel for external automation by @engalar in #38
  • docs: add comprehensive theme & styling skill by @engalar in #40
  • fix(catalog): recurse into loop bodies when extracting references by @engalar in #45
  • feat: add custom pluggable widget AIGC skill by @engalar in #42
  • feat(init): add OpenCode tool support by @retran in #47
  • feat: pluggable widget engine with data-driven definitions by @engalar in #28
  • fix: address PR #28 review follow-ups by @ako in #48
  • docs: add mxbuild setup & mx tool skill by @engalar in #43
  • deps: bump modernc.org/sqlite from 1.42.2 to 1.48.0 by @dependabot[bot] in #57
  • deps: bump go.mongodb.org/mongo-driver from 1.17.6 to 1.17.9 by @dependabot[bot] in #60
  • deps: bump github.com/spf13/cobra from 1.8.0 to 1.10.2 by @dependabot[bot] in #62
  • deps: bump github.com/mattn/go-runewidth from 0.0.19 to 0.0.21 by @dependabot[bot] in #61
  • deps: bump go.uber.org/zap from 1.21.0 to 1.27.1 by @dependabot[bot] in #59
  • deps: bump github.com/jackc/pgx/v5 from 5.8.0 to 5.9.1 by @dependabot[bot] in #58

New Contributors

Full Changelog: v0.3.0...v0.4.0