Skip to content

Sync ako/mxcli: diff-local headers and bodies, export mapping order, syntax verb lookup - #1397

Merged
ako merged 11 commits into
mendixlabs:mainfrom
ako:main
Oct 12, 2026
Merged

ako merged 11 commits into
mendixlabs:mainfrom
ako:main

Conversation

@ako

@ako ako commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

Syncs ako/mxcli:main into mendixlabs/mxcli:main: 5 commits since #1394, landed in the fork through PRs ako#1127–ako#1131.

diff-local (#1393)

  • Headers name the unit and revision, with the module-qualified name, instead of Microflow.<uuid> (current) / (script). An MPR v2 .mxunit does not carry its container, so the module is now resolved from the project hierarchy.
  • Pages, nanoflows and layouts render their bodies. A changed one counted as modified but printed no hunk, because the renderers emitted a fixed placeholder. Nanoflows were also dispatched to the microflow parser, because Microflows$Nanoflow contains Microflow.

Integration

Syntax lookup

Tests

claude and others added 11 commits October 12, 2026 08:12
…gets (mendixlabs#1393)

`diff-local --ref HEAD~1..HEAD` printed
  --- Microflow.<uuid> (current)
  +++ Microflow.<uuid> (script)
rendered the microflow without its module, and a page whose container
gained a conditional Visible reported "0 new, 1 modified, 0 deleted"
with no hunk.

- An MPR v2 .mxunit does not carry its container (the .mpr Unit table
  does), so the `$Container` lookup never hit. Resolve the module from
  the project hierarchy keyed on the unit ID, and use the qualified
  name for the header too. Nameless domain models now take the
  module's name instead of the UUID.
- DiffResult gains FromLabel/ToLabel; diff-local sets the two git
  revisions (range) or ref / "working tree" (single ref). The script
  diff keeps "current"/"script".
- Pages and snippets render their widgets through the DESCRIBE widget
  renderer over the revision's raw BSON instead of a fixed
  "-- (page widgets)" body.

Control: reverting the fix fails both new tests with the reported
output; a real PedApp copy in git reproduces the issue byte for byte
with the old binary and shows `container box1 (Visible: [false])` with
the new one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sv4XfyPYBFZdzsecgqNcXB
…#1389)

`mxcli syntax grant` (also revoke, refresh) answered "Unknown topic: grant"
although grant is a listed keyword of security.entity-access: syntax.Lookup
only consulted topic paths, and a verb is nobody's path segment. It now falls
back to the topics' keyword lists (whole words, exact keyword ranked first)
after the segment match, so it cannot shadow a path hit.

`mxcli syntax integration message-definition` printed
`No topic "integration.message-definition"` and recovered only through the
fallback. A leading word that names a topic, in front of words that name a
different topic exactly, now resolves to that topic — unless the leading
topic has its own segment match for the word (`workflow microflow` keeps
workflow.call-microflow).

The fallback heading moves to Match.Heading so `mxcli syntax` and the REPL's
HELP say the same thing, and say what a fallback matched on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CkQ5WmhG8gwuMhPQQTsAJz
Same defect as pages: a changed nanoflow or layout counted as modified
and printed no hunk, because both renderers emitted a fixed placeholder
body. Nanoflows never reached theirs: the dispatch tested "Microflow"
first and "Microflows$Nanoflow" contains it, so the microflow parser
got the document, returned nil, and both sides became the same
"parse failed" stub.

- Dispatch Nanoflow before Microflow.
- Add ParseNanoflowFromRaw to the backend (modelsdk implementation,
  mock, regenerated unimplemented/unsupported stubs) and render
  nanoflows through renderMicroflowMDL, as DESCRIBE NANOFLOW does
  (nanoflowAsMicroflow is now shared). Nanoflow names join the call
  lookup.
- Render layouts as DESCRIBE LAYOUT does, via a raw-data variant of
  getLayoutWidgetsFromRaw.

Control: with the executor changes reverted, the new nanoflow and
layout tests fail with "1 modified" and no hunk; a git-tracked PedApp
copy prints only the summary with the old binary and both hunks with
the new one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sv4XfyPYBFZdzsecgqNcXB
fix(syntax): resolve statement verbs and qualified topics (mendixlabs#1389)
fix(diff-local): name units and revisions in headers, render page/snippet/nanoflow/layout bodies (mendixlabs#1393)
… creates

mendixlabs#1361 reported check passing a create or modify microflow
that exec refuses (a variable clash, an edit inside a loop body) when the
new body calls a microflow the same script creates. The reporter's nightly
(5c321d0) predates cc69904, which resolves such calls in the verdict
build; that commit only tested the "still used by" refusal.

Pin both reported shapes, each with a no-call control. Stubbing the
script-flow lookup makes every call variant fail with the body reported
unpredicted and no violation, the reported symptom.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MhMxqP7CUTdD49zYkgRxkf
An export mapping over a message definition kept its members in script
order, and mx check refused it with CE5015 "The order of the schema
elements under 'Orders/Order' does not match the schema." The builder
now stable-sorts each level's children by their position in the
definition, so any script order — and members appended by
`alter message definition … add member` after a nested object — writes
the order mxbuild accepts.

Measured on 11.12.1: the import twin and both JSON-structure mappings
check clean in either order, so only the export path is changed.
Stubbing the sort brings back 2 x CE5015 on the bug-test MDL; the fixed
build checks 0 errors.

Fixes mendixlabs#1387

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KjNNxUzbRxZAn1DEyHPy1V
test(check): pin mendixlabs#1361's refusal shapes for calls to flows the script creates
fix: write export mapping members in message definition order (mendixlabs#1387)
@github-actions

Copy link
Copy Markdown

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

The PR successfully addresses four distinct issues with appropriate fixes and test coverage:

  1. diff-local (diff-local --ref a..b: header shows Microflow.<uuid>/(current)/(script), module dropped, and modified page prints no hunk #1393):

    • Fixed header naming to show module-qualified names instead of UUIDs
    • Implemented proper rendering of page/nanoflow/layout bodies using existing renderers
    • Corrected nanoflow dispatch order to check for nanoflow before microflow
    • Added comprehensive test coverage verifying header names and hunk generation
  2. Export mapping order (Export mapping: elements written in a different order than the schema are accepted, then mx check fails with CE5015 #1387):

    • Implemented sorting of export mapping members by message definition order
    • Added test verifying schema order compliance and subset preservation
    • Maintained backward compatibility for import mappings and JSON-structure mappings
  3. Syntax lookup (mxcli syntax lookup misses common statement verbs (grant) and two-level names (integration message-definition) #1389):

    • Enhanced topic resolution to check keyword lists for verbs like grant/revoke/refresh
    • Added qualified topic resolution (e.g., integration message-definition)
    • Improved error messaging with contextual headings for fallback matches
    • Added thorough test coverage for all new lookup scenarios
  4. Test coverage for check passes a create or modify microflow that exec refuses ("Nothing was written") when the flow calls a microflow created earlier in the same script #1361:

    • Added test scripts pinning both refusal shapes (variable clash and loop body)
    • Included no-call controls to validate the fix
    • Verified the check command now properly predicts exec refusals

The changes follow established patterns:

  • Uses existing rendering infrastructure (DESCRIBE-compatible)
  • Maintains separation of concerns (executor/backend logic)
  • Preserves backward compatibility where appropriate
  • Adds tests at appropriate levels (unit, integration, MDL examples)
  • Clear commit separation by concern
  • Comprehensive comments explaining non-obvious logic

Recommendation

Approve the PR. The changes are well-implemented, thoroughly tested, and address the reported issues without introducing regressions or violating project guidelines. The fixes are minimal and focused, with appropriate test coverage to prevent future regressions. All checklist items have been satisfied.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@ako
ako merged commit 6a54a8e into mendixlabs:main Oct 12, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants