Skip to content

Sync ako/mxcli: rename coverage, flow-argument bindings, Boolean constants, check refusals - #1332

Merged
ako merged 32 commits into
mendixlabs:mainfrom
ako:main
Oct 7, 2026
Merged

ako merged 32 commits into
mendixlabs:mainfrom
ako:main

Conversation

@ako

@ako ako commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator

Syncs ako/mxcli:main into mendixlabs/mxcli:main: 15 commits since #1320, landed in the fork through PRs ako#1008–#1014.

Rename

  • mxcli syntax rename: a new topic covering every RENAME target, DRY RUN, RENAME MODULE and what the reference rewrite covers (mxcli syntax has no rename topic: RENAME MICROFLOW/PAGE/ENTITY parse and are in 'help rename', but 'syntax rename' says Unknown topic #1318). It was "Unknown topic", so an agent concluded MDL could not rename a microflow. A test requires every renameTarget alternative in the grammar to appear in the topic.
  • mxcli rename takes java-action and workflow, the two targets only MDL could reach. One table now maps types to RENAME keywords, tested against the grammar.
  • RENAME JAVA ACTION renames the class, not just the file. The .java file kept public class JA_Old, so javac failed for run --local --watch and IDEs, while docker build still succeeded. It now rewrites exactly the three places mxbuild itself rewrites, pinned by an mxbuild-generated golden.

Pages: flow arguments (#1317)

  • An Expression-bound flow argument writes Variable: null, as Studio Pro does. Without it, Studio Pro's Changes panel threw "do not have the same properties".
  • ALTER PAGE set (Action: call microflow …($P)) binds a page parameter through Forms$PageVariable instead of the expression "$P".
  • A widget inserted into a snippet binds its flow argument as a snippet parameter (CE0115 before), for buttons and data grid columns.

Constants (#1321)

  • A Boolean constant's default and its configuration overrides are stored as "True" / "False". Studio Pro's dialog showed a stored "true" as False.

Check

claude and others added 30 commits October 6, 2026 19:10
…#1318)

`mxcli syntax rename` printed "Unknown topic: rename" although RENAME
MICROFLOW/PAGE/ENTITY/... parse, run, and are documented by
`mxcli help rename`. An agent consulting `syntax` concluded MDL could not
rename a microflow and rebuilt it by hand.

- New `rename` topic: every RENAME target, DRY RUN, RENAME MODULE, what
  the reference rewrite covers (exact/prefix qualified-name strings, not
  names inside expressions), the ALTER forms for members, and the
  `mxcli rename` CLI form with the types it lacks (JAVA ACTION, WORKFLOW).
- see_also to it from microflow, page, domain-model.entity and move.
- rename_topic_test.go reads the renameTarget rule from MDLParser.g4 and
  requires every alternative in the topic, so a new target cannot ship
  undocumented.

Control: with the topic reverted the built binary prints
"Unknown topic: rename" and TestSyntaxRenameTopic fails; dropping the
RENAME WORKFLOW line fails the grammar guard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRKF4gDAitr4oNz6DrtBaz
`create constant ... (Type: Boolean, DefaultValue: true)` rendered the
literal with fmt's %v and stored "true". Studio Pro stores "True" /
"False", and its constant dialog shows a stored "true" as False while the
runtime reads it as true. Normalise Boolean defaults on both the create
and the create-or-modify path.

Fixes mendixlabs#1321

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018KhC7qZthbY6TNuUTqURmt
Studio Pro writes Expression, Parameter and Variable on every
Forms$MicroflowParameterMapping / Forms$NanoflowParameterMapping and nulls
the unused slot. An Expression-bound argument left the gen Variable part
unset, so the encoder omitted the key, and opening the change in Studio
Pro's Changes panel threw "do not have the same properties. baseNames =
Expression, Parameter, Variable; newNames = Parameter, Expression".

Register Variable as a null field on both types, which covers the action,
nanoflow action and nanoflow data-source writers alike.

Refs mendixlabs#1317

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
convertASTAction built its pageBuilder with no parameter or variable scope,
so `set (Action: call microflow M.F(P = $P))` and a pluggable widget's
named action slot wrote a page parameter as the Expression "$P" rather
than binding it through Variable -> Forms$PageVariable (the mendixlabs#1140 form,
which Studio Pro does not resolve). Seed it from the mutator as
INSERT/REPLACE already do, including isSnippet.

Refs mendixlabs#1317

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
Regression MDL for mendixlabs#1317 and the finding: `mx diff`
reproduces Studio Pro Changes-panel crashes headless.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
The subcommand offered eight of the ten targets RENAME accepts: JAVA
ACTION and WORKFLOW were reachable only from MDL, because the subcommand
kept its own switch of types and nothing tied it to the grammar
(follow-up to mendixlabs#1318).

- One table maps the type argument to the RENAME keyword; java-action
  also accepts java_action / javaaction.
- cmd_rename_test.go reads renameTarget from MDLParser.g4 and requires
  every target to be reachable and to parse to the RENAME it names.
- Brain anchors are rewritten for Java actions and workflows too.
- Help text, `mxcli syntax rename` and CHANGELOG updated.

Control: with the table holding only the old eight types, the new tests
fail with "unknown type: java-action" / "unknown type: workflow".
Run on an 11.14 project: both renames, with and without --dry-run,
re-point the calling microflow / parent workflow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRKF4gDAitr4oNz6DrtBaz
…pet parameter

buildWidgetsFromAST and buildColumnSpecsFromAST seeded the stored parameter
scope but never isSnippet, so a button inserted into a snippet with
`call microflow M.F(P = $P)` wrote Forms$PageVariable.PageParameter
instead of SnippetParameter. mxbuild 11.12.2 reports CE0115 on that button
only; CREATE SNIPPET and ALTER SNIPPET SET were already correct. Set
isSnippet from the mutator's container type, as convertASTAction does.

Refs mendixlabs#1317

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

`alter settings constant @m.Flag value true` stored the configuration
override's value as typed ("true"), the same defect mendixlabs#1321 reports for a
constant's default. Look up the constant's type and normalise Boolean
values with storedConstantDefault; other types are stored as written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018KhC7qZthbY6TNuUTqURmt
…DL-BUTTON02)

A button directly inside data view `dvGate` passing `$dvGate` passed
`check --references` and `exec`, then `mx check` reported
`[CE0117] "Error(s) in expression." at Action button 'btnOwn'`.
A data container's widget-name variable is in scope only for the
containers nested below it; in its own context the object is
$currentObject.

The button-context walk now carries the nearest data container's name,
moving with the same rule as MDL-BUTTON01 (a control bar takes its
context from above its grid), and flags an action argument that reads it.
The flagged set matches mxbuild 11.14.0's CE0117s on a ten-button probe:
own data view (direct, through a container, from a control bar inside
it, as `$dv/Attr`), and a list view, grid or gallery read by its own name
from its item or row. The enclosing name from a nested container and a
grid's selection from its own control bar build clean and are not flagged.

Fixes mendixlabs#1324

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

`retrieve … where starts-with(Name, 'MS-' + $Key)` passed `check
--references` and `exec`, then failed mx check with CE0161 "Error(s) in
XPath constraint." (mendixlabs#1326). MDL091 only matched
expression-only function names in the rendered XPath string; it never
looked at what a function's arguments are.

Walk the retrieve constraint's AST and flag a function argument that is
itself a `+` or `-` operation. MDL091 is exec-enforced, so exec now
refuses it as well. Measured on mxbuild 11.14.0 with the check stubbed
out to force the fault in:

  starts-with(Name, 'MS-' + $Key)      CE0161
  not(contains(Name, $Key + $Key))     CE0161
  contains(Name, $Key - 'a')           CE0161
  Name = 'X-' + $Key                   0 errors
  year-from-dateTime(Due) = $N - 1     0 errors
  starts-with(Name, $P)                0 errors

`*`, `div` and `mod` are not flagged: their only possible argument is
numeric, and `contains(Name, $N)` is CE0161 with no operator, so no
measurement isolates the operator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015mwKd8LDw9MRoZ8uBbbnAg
Renaming M.JA_Old to JA_New moved javasource/m/actions/JA_Old.java to
JA_New.java and left `public class JA_Old`, its constructor and
toString's "JA_Old" inside. javac:

  class JA_Old is public, should be declared in a file named JA_Old.java

`mxcli docker build` still reported BUILD SUCCEEDED, because mxbuild
regenerates the stub in its own copy; the file on disk is what
`run --local --watch` hot reload and IDEs compile.

RenameJavaSourceFile now rewrites those three places, and only those,
via javaactions.RenameSource. The oracle is mxbuild itself: run in place
on a renamed action with an extra import, extra code and user code that
mention the old name, it changed exactly those three lines and kept the
rest byte-for-byte, CRLF included. That pair is the new golden
(testdata/mxbuild/JA_Renamed*).

Control, on a fresh 11.14.0 app: unfixed binary -> javac error above on
the renamed file; fixed -> javac exit 0, docker build BUILD SUCCEEDED.
The backend test fails against the old os.Rename-only code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRKF4gDAitr4oNz6DrtBaz
`set $Cursor = $Next;` with both variables single objects passed
`check --references` and `exec` and was written as a Change variable
action, which mxbuild refuses with CE7247 "Variable 'Cursor' does not
have a primitive type". Mendix has no action that reassigns an object
variable; #949 routed the list case to Change list Replace and
left objects on the primitive-only path.

The builder (exec) and the check validator now refuse it and name the
alternatives. The check validator typed every association retrieve as a
list, so the reported shape (a Reference followed from its FROM entity)
looked like a list to check; under --references it now takes the
association shapes MDL-ASSOCDS01 already builds and types that retrieve
as the object it is. Self-association retrieves stay lists (Mendix types
them so, and `set` on them is a valid Replace).

Measured on 11.14.0: faulted build -> CE7247; fixed build refuses in
check and exec; the self-association and recursive sub-microflow forms
in the bug-test -> 0 errors.

Fixes mendixlabs#1323

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMEw8qsiJuVoaaGJawicfo
…labs#1317 snippet case

The isSnippet fix also reaches buildColumnSpecsFromAST. Add a column with a
flow button inserted into a grid inside a snippet. Measured on mxbuild
11.12.2: before, PageParameter and CE0115 at the button; after,
SnippetParameter and 0 errors.

Refs mendixlabs#1317

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HamahFUo9MM2xuaNmm5mhr
fix(pages): flow-argument mappings crash Studio Pro's Changes panel and bind the wrong slot (mendixlabs#1317)
fix(syntax): add a rename topic so RENAME is discoverable (mendixlabs#1318)
Resolves the PR's conflict in .claude/skills/fix-issue/findings/mdl-executor.jsonl
by keeping both sides' appended findings (the file's merge=union rule, which
GitHub's mergeability check does not apply).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018KhC7qZthbY6TNuUTqURmt
…project

Plain `mxcli check` runs only the MDL0xx rule set, never validateFlowBody,
so the mendixlabs#1323 refusal reached `check --references` and `exec` but not a
check without -p (and check-mdl could not pin it with a .fail.mdl).

MDL-SET01 judges the object producers visible in the text: entity
parameters, create, `retrieve … first`, loop iterators over a known list,
head, cast. Association retrieves need the project and stay with
validateFlowBody, which now reports only those, so --references prints
the refusal once. Microflows and nanoflows.

Measured on 11.14.0 with the faulted build: every producer gives CE7247;
a parameter is worded "Parameter 'A' cannot be changed.", which the
message now quotes.

Part of mendixlabs#1323

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMEw8qsiJuVoaaGJawicfo
fix: store Boolean constant values as "True"/"False" (mendixlabs#1321)
A Change variable activity cannot target a parameter: measured on 11.14.0,
`set $N = 1` on an Integer or String parameter builds as CE7247
"Parameter 'N' cannot be changed." in a microflow, a nanoflow and a rule,
and check and exec passed it.

MDL-SET01 now refuses it for every parameter but a list; `set` on a list
parameter (Change list Replace), `add` to one and a member change on a
parameter all build with 0 errors and stay accepted. Rules never run
ValidateMicroflow, so plain check reports them from ValidateProgram and
exec gates them in cmd_rules_create (not validateRule, which
check --references also runs and would print it twice). MDL-SET01 is now
exec-enforced, so a script run with --no-check does not write it either.

A nanoflow test fixture that assigned to its String parameter (incidental
to the MDL044 case it covers) now sets a local copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMEw8qsiJuVoaaGJawicfo
Resolve CHANGELOG.md: keep both sides' Fixed entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QLPboEFUCLXZr6qwX2T9LF
claude and others added 2 commits October 7, 2026 16:53
@ako
ako merged commit 46a527e into mendixlabs:main Oct 7, 2026
15 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