Repository navigation
Sync ako/mxcli: filemanager widget, no auto-created module roles, describe round-trip fixes - #1503
Merged
Merged
Conversation
…ndixlabs#1404) Reported: "describe emits `MxObject: \"Entity\"` with no declaration, and exec writes entity `.Entity`" — mx check CE1613 "The selected entity '.Entity' no longer exists." at Java action parameter 'MxObject', while `check` passed. Seen on GenAICommons.ChunkCollection_AddKnowledgeBaseChunk. MDL declared a type parameter only through an `entity <T>` parameter, so one bound by the caller's object had no spelling. - Grammar: `create java action Module.Name<T, U>(…)` declares type parameters in order; `entity <T>` parameters still declare theirs. - describe prints the header only when the entity selectors would not reproduce the stored list in its order, so actions that already round-tripped describe unchanged. An entity selector bound to no type parameter (`entity <>`, which does not parse) or a dangling reference is commented out under `-- NOT re-executable:`, as for JavaScript actions. - exec refuses, and check reports as MDL-JA01, an unqualified type that is neither a declared type parameter nor Microflow/Nanoflow, instead of writing the entity `.Name`. mx check 11.6.6 on the bug-test script: 0 errors; describe -> exec -> describe is identical and the re-exec is "Unchanged". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…s#1416) Reported: `check -p` and `exec` refuse an enum split that `describe microflow` produced and Studio Pro 9.24.2 wrote (the FSM template's 28-value NativeModelCheck_Process): "enum split has 29 branches; at most 16 branches are supported". `check` without -p passed, so the two modes disagreed. Which side was wrong: the limit, not the describer. The 16 was len(splitCaseOrderAnchors), the 4x4 origin/destination anchor-pair table that once stored each case's order. A split of four or more cases no longer uses it: the order is stored as origin side + canvas depth (enumSplitOriginAnchors) and read back by orderedEnumSplitFlows, neither of which has a limit. Mendix has none either: a 29-branch split written by exec into a blank 11.6.6 app checks at 0 errors under mxbuild, and Studio Pro authors such splits. The cap guarded nothing, so it is removed from the builder and from the -p body validator (with the now-unused helpers). Round trip on a PedApp copy: exec the bug-test, describe -> check -p passes -> exec reports "Unchanged microflow" -> re-describe identical, all 28 cases in written order. Tests (replacing the two that pinned the refusal): - TestEnumSplitBuilderAcceptsMoreThanSixteenBranches: builds 28 cases + (empty), describes them back in order. - TestValidateMicroflowBody_EnumSplitAcceptsMoreThanSixteenBranches. Control: with the cap restored both fail with the reported text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…1401) Reported: "describe entity (and describe module ... with all) prints an index with an empty column list" — `index ( desc);` — which check refuses with "index on unknown attribute 'desc'", so every statement referencing the entity failed (Siemens FSM template, ten entities). The stored index is real, not dangling: Studio Pro stores a segment on the changedDate / createdDate system member as IndexedAttribute.Type = ChangedDate / CreatedDate with no attribute behind AttributePointer. The semantic IndexAttribute had no Type, so the reader dropped it, the describer resolved the column by attribute ID only, the create and alter paths could not name the column, and indexToGen hard-coded Type Normal — any rewrite of such an entity turned the index into an attribute segment pointing at nothing. IndexAttribute now carries Type through read and write; describe prints the member as the entity declares it (`index (ChangedDate desc)`), and create / alter add index / drop-index matching / reconcileDroppedIndexes accept it while the entity stores that member. A segment resolving to neither is described as a `-- index skipped` comment on its own line, so the statement still parses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…labs#1404) The skill's basic-syntax block used placeholder types (`param1: type`, `returns ReturnType`). With MDL-JA01 those are undeclared type parameters, so check-skill-mdl-semantics.sh failed the block. Use real primitive types instead, so the example is one a reader can run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…s#1406) describe printed a Studio Pro text-template parameter as stored and check refused it: ContentParams: ({1} = $currentObject/CollectionIdentifierLabel) ✗ … ContentParams parameter {1} is written as "$currentObject/CollectionIdentifierLabel" — … Write "CollectionIdentifierLabel". … [MDL-WIDGET24] Which side was wrong: the writer. Studio Pro stores that parameter as Forms$ClientTemplateParameter.Expression (introduced 9.0.1), and describe prints the expression verbatim, so the only spelling that re-creates the same model is the expression itself. The writer instead read `$var/Attr` as an attribute binding and kept the prefix in the attribute name (CE1613, #1046), and MDL-WIDGET24 was added to refuse the spelling rather than fix the write. Rewriting describe to a bare `Attr` would have changed an Expression into an AttributeRef (a different model, and wrong for a `$Param/Attr` outside the context object). isTemplateExpression now treats a variable-rooted member path as an expression. `$currentObject/Assoc/Attr` stays an association binding, as #1046 measured it building clean. MDL-WIDGET24 is removed: it has nothing left to prevent. Measured on 11.6.6 (blank app): `{1} = $currentObject/Name` and `{1} = $EntA/Name` on dynamic text and a button caption exec and build at 0 errors; describe -> check -p --references passes -> exec reports "Unchanged page". Over a Decimal attribute the expression is CE0117 (a template expression must be a String) — the old no-project check can no longer warn about that case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Reported: "Describe of a doc comment loses a markdown `*` bullet" — a documentation line starting with `* ` came out of describe without the ` * ` gutter, and replaying it stripped the bullet marker: "Silent drift of documentation text", one marker per describe/exec cycle. Eleven describers printed documentation with "/**\n * %s\n */\n", which gutters the first line only, and the entity attribute used the inline `/** %s */`. The parser strips one leading `*` per line, as javadoc does, so an unguttered bullet line lost its marker. They now call outputJavadocIndented; the attribute keeps the inline form only for one line that does not itself start with `*`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: Java action type parameters are expressible and round-trip (mendixlabs#1404)
mendixlabs#1405) Reported: describe emits catalog order, and check refused the output of two mutually recursive microflows: "microflow ModA.MF_A references microflow ModA.MF_B before it is created (statement 3), and the project does not have it" — no order of the two statements passes, so mutual recursion could not round-trip without a hand-written stub. A call is stored by name, so it can be written before its callee; the hazard was a later statement failing and leaving it dangling, which the #1408 journal removes. So: - A run under the journal (plain `mxcli exec`) resolves a CALL MICROFLOW / CALL NANOFLOW against every flow the script declares (Executor.SetForwardFlowCalls; enterScriptFlows fills scriptFlows from the whole program, saved and restored for nested scripts). - --continue-on-error, the REPL and -c cannot roll back and still refuse it, saying so and giving the remedy: create the callee first, or a stub then `create or modify`. With -p the pre-flight refuses before anything is written; otherwise the statement fails with the same hint. - check accepts it: it cannot know how the script will run, so it takes the plain-exec rule, and exec refuses in the modes that cannot roll back. MDL-ORDER01 skips flow-call targets; validateForwardDefRefs applies the run's mode. `mxcli diff` predicts exec's mode. - Only flow-call targets: a page button's flow, IN QUEUE, parameter types, grants and the rest keep the ordering rule. Case 5 of 955-forward-definition-order.fail.mdl moves to 1405-forward-flow-calls.mdl. Measured on Mendix 11.6.6 (expr-checker copy): A<->B microflows and nanoflows in either order, exec then mx check 0 errors; describe -> exec -> describe identical. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: describe and write an index on a system date member (mendixlabs#1401)
…pping root (mendixlabs#1407) Three describe outputs that `mxcli check` could not parse: format (decimalPrecision: -1) -> extraneous input '-' DecimalPrecision: -1 (text box) -> "DecimalPrecision must be a non-negative integer" [MDL-WIDGET18] + [MDL-WIDGET42] root (Wrapper) (import mapping) -> extraneous input '(' Which side was wrong, per part: - DecimalPrecision -1: the grammar and check. -1 is the value Studio Pro stores for "no fixed precision", so describe printing it is correct. propertyValueV3 gains a signed number (`MINUS NUMBER_LITERAL`), so -1 is a plain value rather than falling through to the generic expression alternative (which is what MDL-WIDGET42 then refused), and both validators accept -1 (still refusing anything below it). Measured on 11.6.6: a page with both spellings execs and builds at 0 errors, and describe -> check -p --references -> exec reports "Unchanged page". The existing input_formatting test asserted -1 is refused; it now uses -2. - root (Wrapper): the describer. "(Wrapper)" is the generated item of an array of primitives, a marker like "(Object)"/"(Array)" that is never a member name. schemaRootClause now drops it too; the writer already steps from an array into its Wrapper (arrayItemOf), so a mapping over a root primitive array described with no root clause is rebuilt at "(Array)|(Wrapper)" again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: gutter every line of a described doc comment (mendixlabs#1428)
…1403) Reported: "Describe emits a `show page` argument taken from the page's own parameter, which check refuses (MDL-PAGEARG01)". `describe page` of a GenAI Showcase wizard page prints `show page M.Next(Task = $Task)` on a button outside any data container; `check` refuses it, so the page cannot be re-created (12 occurrences in the 2026-10-12 round-trip runs). Which side was wrong: the check and the writer, not the describer. Studio Pro stores this button as an EXPLICIT Forms$PageParameterMapping {Argument "", Variable: Forms$PageVariable{PageParameter: Task}} — the parameter bound by name, which needs no context object (ako/TestApp WorkflowCommons TaskAssignmentHelper_UserTask_Reassign; Snip_UserTask_Detail for the SnippetParameter twin). DESCRIBE reads that mapping correctly. mxcli only knew the empty, inferred mapping (#296), so it concluded no argument can be stored outside a data widget (#1029) and refused the spelling. Now a show page argument naming an entity parameter of the page or snippet being built is accepted wherever it sits and written as Studio Pro writes it (9.7+, where PageSettings has ParameterMappings; older projects still refuse). The context object stays inferred, so existing pages write exactly as before. gen's NewPageParameterMapping stamps $Type Forms$FormCallArgument (LayoutCallArgument) — mxbuild cannot load a page carrying it — so the writer sets Forms$PageParameterMapping explicitly. Measured on mxbuild 11.6.6, blank app, the new bug-test (page and snippet): fixed -> The app contains: 0 errors. mapping forced back to empty -> 2x CE1571 "No argument has been selected for parameter 'Item'", at btnOpen/btnNext describe -> check -p -> exec of both documents: "already in sync". Roundtrip harness: two ako/TestApp allowlist entries struck (TaskAssignmentHelper_UserTask_Reassign, _Retarget no longer break exec). Snip_UserTask_Detail now passes exec too and exposes unrelated getput drift (conditional-visibility ModuleRoles, a date picker ReadOnlyStyle, a data view source mapping marker), so its entry moves from exec to getput rather than being struck. 1029-showpage-arg-without-context.fail.mdl now uses $currentObject, which nothing at the page root binds; its old $SomeRef is exactly this issue's shape. Skills and `mxcli syntax` updated. Tests: - TestValidateShowPageArguments_DocumentParameterIsBoundByName (check) - TestBuildShowPage_DocumentParameterArgumentIsAnExplicitMapping (exec) - TestClientActionToGen_ShowPageWritesNamedParameterMapping (BSON) Control: with the builder/writer reverted and the check-time exemption removed, all three fail (MDL-PAGEARG01 "there is no context object at all"; "0 mappings written, want 1"). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…mit (mendixlabs#1415) describe page on the FSM template's NativeModelCheck.NativeShadowModel_Overview emitted `DataSource: selection grid1` for a data view listening to a legacy Forms$DataGrid that describe only writes as a "NOT re-executable" comment. check -p and exec refused the page: widget 'dataView1': selection DataSource references 'grid1' but no widget with that name exists on this page Which side was wrong: the describer. check is right that a selection data view needs its source on the page; describe produced a reference to a widget it had itself dropped. The data view cannot be written without its source, so it is now commented out with the grid, under a "NOT re-executable" line naming the source it lost — the rest of the page stays re-executable, and what re-running drops stays visible. describeWidgetBody (page and snippet bodies) records which widgets come out only as comments. A widget whose selection source is among them is rendered and emitted line by line as a comment, and everything inside it counts as dropped too, so a second data view selecting from a list nested in the first is commented as well. A dependent can precede its source in document order, so a pass that emitted a selection of a widget it later dropped is rendered again; a body without that case is rendered once. Tested on PedApp with a list view retyped in the BSON to Forms$DataGrid (same-length string, byte replace): describe -> check -p --references passes -> exec succeeds; before the fix both refused with the message above. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: resolve forward microflow/nanoflow calls in a run that rolls back (mendixlabs#1405)
…endixlabs#1468) ALTER PAGE INSERT/REPLACE of a Data grid 2 column took its entity context from EnclosingEntityForChildren, a BSON-only walk. A microflow or nanoflow data source stores no entity in the page, so the column's Attribute stayed unqualified and was written with no AttributeRef: mxbuild failed with "An attribute is required when column sorting is enabled" (plus CE0402 on the cell's ContentParams) on flow-sourced grids only. Both column paths now use alterEntityContext, which falls back to the flow's return entity as every other ALTER PAGE widget path already did. Verified on Mendix 11.14.0: the bug-test script gives 6 errors with the fix reverted and 0 with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BYe3AxRKaJVBMhzGQ95soJ
) A new page, microflow or nanoflow in a module with no module roles created <Module>.User ("Auto-created default role for mxcli document access") and granted the document to it: a security role nobody chose, open to every user role later mapped to it. A new document now starts with no allowed roles in every module, and MOVE maps roles to same-named target roles without creating any. Exec, check --references (grant resolver) and MDL-SEC21 each simulated the default; all three are removed so check keeps predicting exec. Roles an earlier mxcli created are left in place and `create module role M.User` still adopts them. Example scripts that granted to <Module>.User without creating it now create the role. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZuJHmm9r3UfYh19LS6QAj
fix: create accepts an enum split of more than 16 branches (mendixlabs#1416)
…ndixlabs#1473) A Change object activity that mixes a reference-set Add or Remove member with other members had no MDL spelling: `add … to $Obj/Assoc` (#1288) covers only a sole member, so describe printed the Add as `=` with -- WARNING: Test.A_B (Add) stored as Add/Remove, not a set assignment; re-executing this line replaces the set — split it into `add`/`remove … $X/<Assoc>` statements and re-executing it turned the append into a set assignment. - grammar/visitor: CHANGE members take `=`, `+=` (Add) or `-=` (Remove) via a changeMemberAssignment rule; CREATE keeps `=` only, so `create … (Assoc += $X)` is a parse error rather than a silent Set - builder: each member's Type comes from its operator; the CE0033 reference-set check moves into addChangeObjectAction, and `add … to` / `remove … from` now route through it unchanged - describe: members print with their operator, and the WARNING is gone; a sole Add/Remove still prints as `add … to` / `remove … from` Verified on 11.12.4: the mixed Set/Add/Remove activity passes mx check with 0 errors; with the guard stubbed, `+=` on a Reference gives CE0033. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NSY78DBhLeC1eAX3oC5LkV
fix: show page may pass the page's own parameter by name (mendixlabs#1403)
…ndixlabs#151) MDL could not create a file manager, which file-upload pages (e.g. Excel import) need. `pluggablewidget 'Forms$FileManager'` had no definition, the bare `filemanager` was refused as MDL-WIDGET25, and describe printed a stored one as a NOT re-executable comment, so describe -> exec dropped it. filemanager fileManager1 (Label: 'File', Type: Upload, MaxFileSize: 10, AllowedExtensions: '.xlsx', ShowFileInBrowser: false) - grammar: FILEMANAGER token (enumerated widget type, still usable as a name) - builder: buildFileManagerV3; omitted properties take the Model SDK's defaults (mendixmodelsdk 4.116.0: Both, 5 MB, any file, false) - writer: widgetToGen case + the InputWidget null slots live on Mendix 10/11 - describe: prints a re-executable line, non-default properties only - sdk/pages: ShowButton -> ShowFileInBrowser (the metamodel's name), + Label Verified on Mendix 11.14.0: exec + `mxcli docker check` gives 0 errors; control — the same widget in a non-FileDocument data view gives CE6810, so mx does inspect it. describe -> exec reports "Unchanged page". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BrnskoDgU7F6hnHjkrQywD
…ameters (mendixlabs#1417) Reported: describe of a published REST service drops the service-level authentication parameter list (the Siemens FSM template declares a `Token` query parameter that makes its `$Token` authentication microflow valid), and re-executing the output fails MDL-REST04 "authentication microflows can only take an HttpRequest and an HttpResponse". Rest$PublishedRestService.Parameters (Mendix 7.17+) is now part of the model: read with each element's $ID, written from the model (no longer carried as an unauthored key), and stated in MDL after the authentication microflow: Authentication: (basic, microflow Shop.Authenticate ( $Token: header 'X-Api-Token', $Tenant: query, $Lang: query 'lang' description 'UI language, defaults to en')) An unlisted parameter other than the request/response is a query parameter under its own name; the type is always the microflow parameter's. MDL-REST04 (exec and check --references) refuses an unknown $Param, the request or the response, a kind other than query/header, and a duplicate. Unstated authentication keeps the stored list merged over the microflow's (mergeOperationParameters); each parameter keeps the stored $ID of the element with the same MicroflowParameter binding. describe prints the list only when it differs from the default, so existing output is unchanged. Studio Pro reference: FSM template (marketplace 204718) NativeRestAPI.DocumentShare stores one query parameter `jwt` bound to $Token, with the operation parameters' five properties. Verified on 11.6.6: mx check 0 errors; the same script with Parameters not written gives CE0336 on both services; describe -> exec on a fresh copy -> identical describe; re-exec reports the documents unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
…-up) The #1404 change added two lines to the java-actions skill without regenerating its section index, so 'make skill-index --check' reports it stale on main and every 'make build' rewrites it in place. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: store a $var/Attr template parameter as an expression (mendixlabs#1406)
…#1399) Reported: "describe page/snippet prints a nanoflow data source or action without its argument mapping", so round-trip checks fail with CE1571 on a missing parameter such as NativeInstanceItem (Mendix 9.24.2 FSM template). The mapping is empty in the source too: Mendix fills it from the enclosing repeater. That repeater's datasource is Studio Pro 9's pluggable "Database" source, CustomWidgets$CustomWidgetDatabaseSource (constraint rows, an IndirectEntityRef path, a sort bar), which describe did not know. The generic pluggable reader then dropped the unsupported result outright, so the repeaters printed no DataSource and the nested widgets lost their context. Read: the source describes as the existing `database from` spelling - `database from $Param/Assoc/Entity` for a path (the List View form), its constraint rows as the XPath they mean. On 9.x the start parameter is on the WidgetValue, not the source (sourceVariable is 10.0+). An unsupported pluggable datasource is now kept, so its comment shows. Write: on a 9.x project a pluggable widget accepts `database from $ctx/…` and writes a CustomWidgetDatabaseSource with Studio Pro's five keys, its WHERE parsed back into rows (anything a row cannot hold is refused), the parameter on the WidgetValue. Mendix 10 converts every such source into an XPath source (mx convert 10.12.19), so 10+ keeps refusing the form as before. FSM template, Snippet_NativeInstanceForm: describe -> check (0 CE1571, was 8) -> exec on a fresh copy -> mx check 9.24.30: 0 errors -> re-describe identical. An edited repeater rebuilt by the writer is byte-equal in its datasource to Studio Pro's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Reported: "Describe of a merge/decision cannot be re-created (#923): WARNING lines, layout drift". `describe microflow OpenAIConnector.EmbeddingsRequestMapping_POST` prints a decision with empty branches and a `merge shared1;` nothing joins; `mxcli check` refuses it with MDL-FLOW02 "Every merge needs at least one incoming path". Cause: the decision "api key type?" is a Microflows$RuleSplitCondition whose rule (Rule_Configuration_KeyTypeToUse) returns an enumeration; its flows carry Bearer_Token / API_key / (empty). The describer recognised an enumeration split only as an expression `$var`, so this one fell through to the boolean `if` emitter, which found no true/false flows. Which side was wrong: both — MDL had no spelling for it (`case` took a variable or attribute path only), and the describer could not have printed one. Syntax: `case` now takes a rule call, spelled exactly as an `if` on a rule spells it: case OpenAIConnector.Rule_Configuration_KeyTypeToUse(Configuration = $Configuration) when Bearer_Token then ... when API_key then ... when (empty) then ... end case; - grammar: enumSplitSource | functionCall; EnumSplitStmt.Condition. - builder: the split condition goes through buildSplitCondition, so it is a RuleSplitCondition (an expression naming a rule is CE0117). - describer: `case <rule call>` when a rule split's flows carry enum cases. - coverage: where the rule's return enumeration resolves (exec, and check -p for a new flow), a missing value is refused as the CE0079 mxbuild reports, and a value the enumeration lacks is refused; `case` on a Boolean rule is refused (write `if`). Unknown rule/enumeration: not judged. Second symptom (layout drift on re-describe): real, but not "@Curve becoming @caption 'empty'". After drop + create from DESCRIBE, three @Curve lines and one @anchor(from: top) were lost — general, not rule-specific (reproduced on a plain `case $Color` and on an `if`): - the if / case / split type builders applied a statement's annotations with applyAnnotations, which never records @Curve for applyFlowCurves; they now use applyPendingAnnotations, as the if-branch loop already did; - an if's `@anchor(from:)` is the exit side of its closing merge (#767); when that merge is declared on its own (`merge shared1;`) the rebuilt if has no merge to put it on. The merge declaration now carries `@anchor(from: X)`. Proven on marketplace module 220472 (Mendix 11.12.5): describe -> check -p: passes -> exec on a copy: "Unchanged microflow"; drop + create from the describe -> re-describe: identical; the rebuilt split stores RuleSplitCondition + RuleCallParameterMapping + 3 enum cases. mx check of the module project (it lacks GenAICommons/Atlas): 650 errors before and after, the identical error set, none in this microflow. Blank 11.12.5 app + bug-test 1414-case-on-enumeration-rule.mdl: 0 errors; describe -> check -p -> exec "Unchanged". Coverage control: the same script without the API_key branch, built with the check disabled -> mxbuild 1x CE0079 "The 'API_key' condition value should be configured…"; with it, check -p and exec refuse it. Roundtrip harness (PedApp, TestApp): passes, no allowlist entry changes state. Tests: TestCaseOnRuleCall_ParsesBuildsAndDescribesBack, TestCaseOnRuleCall_CoverageAgainstTheReturnEnumeration, TestSplitCurvesSurviveDescribeExecDescribe, TestMergeDeclarationCarriesItsExitSide. Control: visitor not setting Condition -> "Condition is nil; the rule call was dropped"; describer without the rule branch -> prints `if Mod.KeyTypeToUse(...) then end if;`; split builders on applyAnnotations -> "@Curve(...) lost after exec"; merge declaration without the exit side -> no "@anchor(from: top)". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix: comment out a data view whose selection source describe cannot emit (mendixlabs#1415)
…ixlabs#1474) TestNanoflow_GrantRevoke and TestNanoflow_GrantIdempotent granted to RoundtripTest.User, which only existed because creating the nanoflow auto-created it. Create it explicitly, as a script now has to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZuJHmm9r3UfYh19LS6QAj
fix: let check take back DecimalPrecision -1 and a primitive-array mapping root (mendixlabs#1407)
…44 (mendixlabs#151) It was reported as MDL-WIDGET34, the input-binding rule, which TestRuleIDHasOneOwner and TestWidgetRuleIDsAreNotReused refuse: one ID raised from two files. The messages and checks differ, so it takes the next free number on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BrnskoDgU7F6hnHjkrQywD
fix: "statement 1 was rolled back", not "were" (mendixlabs#1408 follow-up)
) Reported: "describe layout prints an empty body for a layout that wraps another layout; the output is refused with `declares no placeholders at all`" (ConversationalUI.Layout_MasterBase on Atlas_Core.Atlas_Default). Such a layout stores its tree in Content.LayoutCall, a Forms$LayoutCall to the outer layout whose Forms$FormCallArgument entries hold the placeholders. Content.Widgets is []. This was measured on the Studio Pro-authored Conversational UI 7.3.1 package. No local fixture had a nested layout. - gen bound WebLayoutContent's call to "FormCall", which is a page's key. It now uses "LayoutCall" (storage-name override, read and write). - pages.Layout carries LayoutCall. layoutToGen writes it with the page code's layoutCallToGen, and refuses it on a native layout. checkLayoutPlaceholders counts placeholders inside the arguments. - MDL: `Layout: Module.Outer` in the create layout header. The body is a page body: `placeholder X { ... }` fills the outer X, and bare widgets fill Main. The argument builder is shared with pages. - MDL081/MDL083 count the argument blocks. Exec refuses an argument the outer layout does not declare. --references checks that the outer layout exists. - describe layout and diff-local print `Layout:` and one block per argument. The rewrite goes through UpdateRawUnit/canon.Reconcile. A rewrite of the Studio Pro-authored layout keeps all seven stored $IDs. An identical rerun of an mxcli-authored one is elided. Verified on mx 11.6.6: - the describe output exec'd on a fresh project checks with 0 errors, and re-describing it gives identical output; - a new layout on Atlas_Default plus a page that uses it checks with 0 errors and builds a PAD; - control: a page binding an undeclared placeholder of the nested layout fails with CE1613. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
fix(pages): bind the Image widget to an uploaded image with `Image: $currentObject` (mendixlabs#1476)
feat: describe and write layouts built on another layout (mendixlabs#1411)
fix(backend): carry index GUID when declared index ID misses (mendixlabs#1470)
fix(executor): resolve excluded-twin names to the live document everywhere (mendixlabs#1469)
fix(pagemutator): accept set Image / DefaultImage on legacy image viewers (mendixlabs#1464)
Fix entity overlap in domain models by measuring box height
fix(pages): write one EntityRefStep per hop for multi-hop association sources (mendixlabs#1467)
fix(pages): write a tab page's Visible:, refuse what it cannot store (mendixlabs#1465)
Re-executing the unchanged `describe layout` of a Studio Pro-authored layout reported "Replaced" and rewrote the unit: layoutToGen writes the canvas as the constant 1280 x 800, and none of PedApp's 22 Atlas layouts stores that (1198, 1204, 1000, 800, 550, 500 x 600). UpdateLayout now carries the stored CanvasWidth/CanvasHeight, read at either BSON integer width, as pages (#541) and snippets (#705) already do. A new layout still gets 1280 x 800. Found while proving mendixlabs#1411. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W3x8Fyvir8kLyPgJs1BDmF
Brings in mendixlabs#1478 (search finds documentation and log messages). Conflict in CHANGELOG.md [Unreleased] resolved by keeping both the Changed (mendixlabs#1474) and Fixed (mendixlabs#1477) entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U6JPskrhXuCjJVz4JRtcdX
fix(visitor): strip quoted identifiers that leaked into stored expressions and XPath
fix: keep a layout's stored canvas size on rewrite
…endixlabs#151) main took MDL-WIDGET44 for the tab page property rule (mendixlabs#1465) while this branch was open; TestRuleIDHasOneOwner would refuse the merge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BrnskoDgU7F6hnHjkrQywD
Sync mendixlabs/mxcli main into ako/mxcli
Unmodified starting point for mirroring mendixlabs/mxcli issues into the fork and triaging them; adapted for mxcli in the next commit so the diff shows what changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01945Pfw7pcoAjvd2HNQJWyK
Skill: fill in the config (label-only), limit triage to mirrors so the fork's own tracker is left alone, ground "spirit" in CLAUDE.md, the ADRs and docs/11-proposals, use docs-wiki/bug-patterns as cluster vocabulary, and define urgent by the invariants that lose data or break opening a project (GUID re-mint, $ID renumbering, wrong $Type, dropped properties). mirror.py: - refuse any non-GET to the upstream repo in code; the routine's session holds upstream credentials, so the prompt alone is not a guard - stop re-posting the "upstream closed, work in progress" comment on every run once a mirror is labelled upstream-closed - title mirrors [up#N] instead of [#N], which names a different fork issue Checked against a fake gh serving fixtures (create, refresh, closed, deleted, busy, rerun, guard); not yet run against live upstream. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01945Pfw7pcoAjvd2HNQJWyK
feat(pages): FILEMANAGER widget for the classic file manager (mendixlabs#151)
Add issue-triage skill for mirroring and classifying upstream issues
A cloud session checks each repo out at /home/user/<name>, so it cannot attach both ako/mxcli and mendixlabs/mxcli, and unauthenticated calls to api.github.com are refused from it. The routine therefore cannot read upstream and write the fork in one run. mirror.py needs no model, so it moves to an hourly workflow on the fork, where github.token reads the public upstream and writes fork issues. That token also keeps ai-issue-review.yml from firing once per new mirror, which a personal token would do. The job only runs in ako/mxcli, since this file travels upstream with fork PRs; a manual run defaults to --dry-run. The skill now only triages: it checks the workflow's last run and reports when mirroring has stalled, and never calls upstream. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01945Pfw7pcoAjvd2HNQJWyK
Mirror upstream issues from GitHub Actions, not the triage routine
2 of 4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs
ako/mxcli:mainintomendixlabs/mxcli:main: 42 commits since #1478, landed in the fork through PRs ako#1176–ako#1213. Most fix reported describe → exec round-trip failures on Studio Pro-authored apps and templates.Behaviour changes
<Module>.Userand grant itself to it: a security role nobody chose. New documents now start with no allowed roles, and MOVE maps roles to same-named targets without creating any. Scripts that relied on the implicit role must create it.New MDL
filemanagerwidget for the classicForms$FileManager(Support FILEMANAGER classic widget in MDL page creation #151): create, describe, ALTER SET its own properties, and refuse it outside aSystem.FileDocumentcontext (MDL-WIDGET45, CE6810). Verified in the running app with a Playwright upload test (size and extension limits).+=/-=inside CHANGE for reference-set Add/Remove members alongside other members (MDL change object add/remove not supported #1473).create java action M.Name<T, U>(…)declares type parameters that no entity selector names (Java action type parameters are not expressible: describe emitsMxObject: "Entity"with no declaration, and exec writes entity.Entity(CE1613) #1404).$Tokenmicroflow is then refused (MDL-REST04) #1417).Image: $currentObjectbinds the pluggable Image widget to an uploaded image (No MDL form binds the Image widget to an image object; dynamicimage fails CE0582 in React apps #1476), andset (Image: …)works on legacy image viewers (alter page … set (Image: …)is refused on a static image ("not a property of this built-in widget") #1464).layout --only-overlapping, and new entities are placed clear of tall ones (Domain model: entities with many attributes overlap the one below,mxcli layoutassumes a centred position, and there is no repair that keeps hand-placed entities #1479).describe → exec round-trips
changedDate/createdDate) (Describe entity emitsindex ( desc);with no column #1401).*bullet #1428).$var/Attrtext-template parameter is stored as an expression (ContentParams parameters are described as$obj/Attrpaths, which check refuses #1406).DecimalPrecision: -1and a primitive-array mapping root parse (Three describe outputs check cannot parse: import-mappingroot (Wrapper), dynamic-textformat (decimalPrecision: -1), text boxDecimalPrecision: -1#1407).show pagemay pass the page's own parameter by name (Describe emits ashow pageargument taken from the page's own parameter, which check refuses (MDL-PAGEARG01) #1403). A data view over an unsupported selection source is commented out instead of emitted broken (Describe emits a selection data source naming a widget it did not emit #1415).declares no placeholders at all#1411), and a layout's stored canvas size is kept on rewrite.Visible:is written, and what a tab page cannot store is refused (Tab pageCaptionParamsandVisible:pass check and exec, then are silently not written #1465).Attributeon grids with a microflow or nanoflow data source (alter page replace) #1468).Identity and safety
create or modify entityon a Studio Pro-authored entity with an index is refused at exec (index GUID not carried over);checkdoes not predict it #1470).drop pagecould delete the live page.Other
.mpkpackages with a data-descriptor CRC quirk are read, as Studio Pro andunzipdo (False 'zip: checksum error' for a valid widget package (PopupMenu.mpk) #1488).