Skip to content

Sync ako/mxcli: six describe → exec losses — read-only data views, native text style, page design properties, import mapping parameters - #1648

Merged
ako merged 16 commits into
mendixlabs:mainfrom
ako:main
Oct 25, 2026

Conversation

@ako

@ako ako commented Oct 25, 2026

Copy link
Copy Markdown
Collaborator

Syncs ako/mxcli:main into upstream: 14 commits from fork PR ako#1682.

It fixes six describe → exec losses found by round-tripping three real apps on v0.28.0. These are fork-filed issues with no upstream counterpart. Two of the 14 commits are a gofmt and its revert, which net to nothing.

describe → exec losses

  • A read-only data view stays read-only. The writer took a data view's Editability from DataView.ReadOnly, which nothing sets, and describe read no key, so Editable: Never became Always on a round trip.
    • alter page … set (Editable: …) on a data view now writes the value too.
    • In the running app (run --local plus a Playwright check), the text box is disabled after the fixed round trip and editable before the fix.
  • New: a native dynamic text's NativeTextStyle, one of Text or Heading1 to Heading6.
    • It is described, written by both backends (the MCP one hard-coded Text), accepted by alter page … set, and known to check.
    • A heading no longer comes back as text.
  • New: page-level design properties. The page header takes DesignProperties: ( … ), typed against the theme's Document and Page groups.
    • describe prints them, and alter page … set ('Key': value) at page level writes them. check -p validates them.
    • Before, a round trip emptied the list.
  • A native page's design properties are typed against the native theme. The theme registry read only web/design-properties.json, so a native option such as 'Color': 'Brand primary' came back as a custom value. It now loads the native files too, and each document picks its platform from its layout, type or stored Type.
  • New: an import mapping call's input object and commit mode can be written:
    import from mapping M.IMM($Json) (Parameter: $Obj, Commit: Yes | YesWithoutEvents | No)
    • It is written, read and described.
    • exec refuses a missing parameter on a mapping that declares one (CE0244) and an unexpected one (CE0246).
    • This was measured with mxbuild by editing one property at a time. No fixture holds an import call with a parameter, so this is the shape mxbuild accepts.
  • A Data grid 2 column's association-path template parameter. This was already fixed after v0.28.0 by the change for Pluggable widget text-template parameter cannot cross an association: mxcli writes Attribute, never EntityRef/Steps → CE1365 #1494. This adds the regression test for the column case.
  • A splice refusal names the statement as written.

Validation

  • Controls: each fix has a failing-first test at the layer the symptom lives in, a control (with the fix reverted, the test fails with the reported symptom), a bug-test script and a finding.
  • End-to-end: on a blank Mendix 11.13.0 app, the fixed round trip reports "Unchanged page" and mx check gives 0 errors.
  • Allowlist: two TestApp documents now round-trip and are struck from the allowlist.
  • Follow-ups: an upgrade-test fold for the new spelling, a test-helper rename that fixed go vet -tags integration, and two regenerated skill indexes.
  • Checks: make build, make test, make lint and make check-mdl pass.
  • Not run in Studio Pro.

Not covered

  • list design properties for <type> and the LSP's design-property diagnostics still read the web definitions only.
  • The MCP backend writes no page-level appearance, so page design properties don't reach a live Studio Pro.
  • MDL-WIDGET15 (adjacent inline dynamic texts) also fires on native pages, where it may not apply

claude and others added 16 commits October 24, 2026 22:18
A data view stores its editability as `Editability` (Mendix 10.7+), where
input widgets store `Editable`. Three layers lost it:

- the writer took a data view's Editability from DataView.ReadOnly, a field
  nothing sets, so `Editable: Never` (and a condition) was written as Always;
- describe's DataView case read neither key, so a stored Never printed as
  nothing;
- `alter page … set (Editable: …)` only knew the pre-10.7 boolean and refused
  every current data view.

Fixes #1676

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
`Forms$DynamicText.NativeTextStyle` (Text, Heading1–6; Mendix 8.0+) had no
MDL spelling: describe did not read it, the builder had nowhere to put it,
and both writers hard-coded Text, so a heading on a native page became body
text on every rewrite.

dynamictext now takes `NativeTextStyle: Heading3` (case-insensitive, stored
canonically, an unknown value refused with the list), describe prints it
when it is not Text, both backends write it, `alter page … set` accepts it,
and check no longer warns MDL-WIDGET07 that it is dropped.

Fixes #1677

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

The theme registry read only themesource/*/web/design-properties.json, so
a native page's widgets were typed against the web definitions. Atlas Core
declares DynamicText `Color` as a web ColorPicker (swatch `Brand Primary`)
and a native Dropdown (option `Brand primary`), so describe → exec turned
the stored option into a custom colour. mx check does not flag it.

The registry now loads the native files too and a document selects by its
platform: a page by its layout, a layout by its layout type, a snippet by
its stored Type. This applies to create, alter page set, alter pages
styling, alter styling, and check -p, which also stops warning MDL-WIDGET12
on native values such as 'Smallest'.

Fixes #1679

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
The design properties stored on a page itself (Forms$Page
Appearance.DesignProperties) had no MDL spelling: describe printed none in
the header and the writer stored an empty list, so a native page lost
'Spacing top', 'Spacing bottom' and 'Background color' on every rewrite.
A page-level `alter page … set` refused them.

The page header now takes `DesignProperties: ( … )`, typed against the
theme's Document and Page groups (where Atlas Core declares them; a page
does not take Widget's — mxbuild refuses Widget's 'Small' for a page's
'Spacing left' with CE6085). Describe prints it, a page-level
`set ('Key': value)` writes it, and check -p validates it.

Fixes #1678

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
#1680 reported, on v0.28.0, that describe printed a Data grid 2
column's text-template parameter without its association step
(`{1} = Hour` for a Stormglass_Weer/Hour binding), so exec resolved the
attribute against the grid's entity: CE1613 at build.

The mendixlabs#1494 change after v0.28.0 fixed the one template-
parameter reader, but its test covers only the path helper. This test runs
the reported case on PedApp: a Studio Pro-shaped parameter (AttributeRef +
IndirectEntityRef), described, re-executed ("Unchanged page"), with the
EntityRef still in place. With the path reader disabled it fails with the
reported `{1} = Hour` line; that description, executed on 11.13.0, is the
reported CE1613.

Closes #1680

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

An import-with-mapping activity's ImportMappingCall.ParameterVariableName
(the mapping's input object) and Commit had no MDL: the writer stored ""
and YesWithoutEvents on every call, the reader read neither, and describe
printed `import from mapping M.IMM($json) all;` without the object. mxcli
could not call a mapping with an input object at all (mxbuild CE0244), and
lint CONV020 reported the passed object as never committed.

The activity takes an ADR-0013 settings list after its operand:
`import from mapping M.IMM($Json) (Parameter: $Obj, Commit: No) all;`.
It is checked in the visitor, written, read and described; exec refuses a
missing parameter on a mapping that declares one (CE0244) and a parameter
on one that does not (CE0246).

The splice refused every statement over such a flow as "no result entity,
which Mendix cannot load". An unbound result stored as a VoidType, or with
no type, loads at 0 errors on mxbuild 11.13.0; only an object or list type
naming no entity (mendixlabs#1418) is refused now.

Part of #1681

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
`create or replace microflow` splices like `create or modify`, and the
visitor folded the two into one flag, so a refusal said "create or modify
microflow M.F: this change cannot be spliced …" for a statement spelled
`create or replace`. The spelling is now recorded beside the flag for
microflows and nanoflows and the refusal prints it.

Closes #1681

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
The import-mapping settings section added for #1681 moved the
line ranges the generated index points at (scripts/skill-index.py).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
The generated index (scripts/skill-index.py) was stale on main; make build
regenerates it.

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

fmt --upgrade rewrites `create or replace microflow` to `create or modify`
and asserts the statement builds the same. The spelling flag recorded for
#1681 (only messages read it) differs by design, so it is folded
like the page, snippet and layout mode flags.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
make lint's fmt-check failed on it on main as well.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
walkBSON in the #1679 test collided with the integration-tagged
studiopro_roundtrip_test.go helper of the same name, so `go vet -tags
integration` (make lint) failed to build the package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
WorkflowCommons.WorkflowUserTaskView_View was listed for a page Appearance
that kept 1 of its 3 design properties, which page-level design properties
(#1678) now carry. Snip_Workflow_TaskDetails was never triaged into #721's
classes; it passes getput on this branch too. The allowlist may only shrink.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
The earlier "gofmt" of this file used /usr/local/go's gofmt, older than the
go1.27.3 toolchain go.mod pins, which formats the composite-literal return
the other way. Under the toolchain's gofmt (what CI's fmt-check runs) main's
version was clean and the reformatted one is not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DRueZhZoBML5iWuJTvUnjL
fix: six describe → exec losses from the JTSBootLogboek round trip (#1676–#1681)
@ako
ako merged commit 15b5b60 into mendixlabs:main Oct 25, 2026
13 checks passed
stagknee pushed a commit to stagknee/mxcli that referenced this pull request Oct 26, 2026
…p-gaps-ibgvit

Fix the describe-round-trip-gaps-pages cluster (mendixlabs#1560, mendixlabs#1563) and its follow-ups (mendixlabs#1647, mendixlabs#1648)
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