Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
908025c
docs(proposal): ALTER PAGE addressing of pluggable object-list items
claude Oct 17, 2026
7929592
docs: proposal for OpenAPI import generating response entities (#1234)
claude Oct 21, 2026
9663c24
fix: OpenAPI import refuses Swagger 2.0 instead of importing an empty…
claude Oct 21, 2026
dced973
fix(mcp): a microflow created over MCP keeps its flow sides and notes
ako Oct 21, 2026
5ae4e78
Merge remote-tracking branch 'origin/main' into claude/integration-co…
claude Oct 21, 2026
1b93f0d
fix(executor): a bare System enumeration in a flow signature is an en…
ako Oct 21, 2026
96a1efc
fix(mcp): ALTER MICROFLOW insert lands on Studio Pro 11.15
ako Oct 21, 2026
0e9aeed
Merge remote-tracking branch 'origin/main' into fix/mcp-create-flow-s…
ako Oct 21, 2026
08fc4f9
fix: init and init --sync-skills keep an edited bundled lint rule and…
claude Oct 21, 2026
0b21634
fix: describe consumed rest service output re-parses — Response: json…
claude Oct 21, 2026
b431c32
Merge remote-tracking branch 'origin/main' into fix/mcp-splice-addres…
ako Oct 21, 2026
7cd95cd
Merge remote-tracking branch 'origin/main' into fix/mcp-create-flow-s…
ako Oct 21, 2026
1ab8ef3
feat: alter consumed rest service — add, modify and drop operations i…
claude Oct 21, 2026
8add08f
fix: create or modify consumed rest service names the operations it r…
claude Oct 21, 2026
e68c950
fix: write a consumed REST service with Studio Pro's list markers
claude Oct 21, 2026
0d40469
Merge pull request #1551 from ako/claude/cool-keller-jtch0r
ako Oct 21, 2026
c372937
Merge pull request #1534 from ako/fix/mcp-create-flow-sides-and-notes
ako Oct 21, 2026
5730249
Merge remote-tracking branch 'origin/main' into claude/integration-co…
claude Oct 21, 2026
72b8a71
docs(skill): give the rest-client alter example its mdl 1; header
claude Oct 21, 2026
d6cda17
Merge pull request #1535 from ako/claude/integration-contract-drift-9…
ako Oct 21, 2026
14b58b2
Merge pull request #1544 from ako/fix/mcp-system-enum-param
ako Oct 21, 2026
08cf186
Merge remote-tracking branch 'origin/main' into fix/mcp-splice-addres…
ako Oct 22, 2026
30824f7
Merge pull request #1545 from ako/fix/mcp-splice-addresses-new-elements
ako Oct 22, 2026
854221a
Merge remote-tracking branch 'origin/main' into proposal/1453-alter-o…
claude Oct 22, 2026
061f640
fix: describe keeps an Accordion group's headerContent out of its body
claude Oct 22, 2026
6ce7f5c
fix: refuse a page, snippet or layout rewrite that would delete widge…
claude Oct 22, 2026
3c63ee9
fix(executor): refuse a combo box in enumeration mode on a non-enumer…
claude Oct 22, 2026
82e48a8
Merge pull request #1566 from ako/claude/cool-keller-jtch0r
ako Oct 22, 2026
814414c
Merge pull request #1564 from ako/proposal/1453-alter-object-list-ite…
ako Oct 22, 2026
40ba7f6
Merge pull request #1565 from ako/fix/1453-describe-item-slots
ako Oct 22, 2026
aa5ee0e
Merge pull request #1567 from ako/fix/combobox-boolean-ce7247
ako Oct 22, 2026
0fd235f
fix: run --ensure-db accepts a superuser login for password-protected…
claude Oct 22, 2026
b29baf8
fix: MPR v2 listings no longer open every unit file to learn its $Type
claude Oct 22, 2026
f2d8dc9
fix: create member assignments no longer decode every domain model
claude Oct 22, 2026
cf135bf
fix: run --local --watch restarts mxbuild --serve when its incrementa…
claude Oct 22, 2026
b698dd1
fix: run --local --watch recovers from mxbuild --serve's stale CE6093…
claude Oct 22, 2026
a3c21ad
fix: pluggable attribute of another page parameter — write `$Param.At…
claude Oct 22, 2026
59fad4a
fix: unit-type index learns the hash of the bytes it read
claude Oct 22, 2026
fb862b8
test: exec rollback snapshot ignores mxcli's .mxcli cache directory
claude Oct 22, 2026
a0e2a6d
fix: describe module … with all covers a large module
claude Oct 22, 2026
e2e5f7e
docs(wiki): sync cost-scales-with-the-project with the #1603/#1616/#1…
claude Oct 22, 2026
f7c3c47
chore: cite upstream issue numbers in run-local fix comments; regener…
claude Oct 22, 2026
190ad9b
fix: v1 container-filtered listing compares the container after the type
claude Oct 22, 2026
b58814d
Merge pull request #1615 from ako/claude/great-franklin-ls4zz5
ako Oct 22, 2026
8d3ecda
Merge pull request #1614 from ako/claude/jolly-newton-7tfgx1
ako Oct 22, 2026
3f71f7e
Merge pull request #1616 from ako/claude/epic-archimedes-7iz2jt
ako Oct 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/lint-rules/example_microflow.star
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
# VAL_ - Validation microflows
# SCH_ - Scheduled event microflows
#
# Customize the prefixes in lint-config.yaml rather than here (`mxcli init`
# rewrites this file):
# Customize the prefixes in lint-config.yaml rather than here (an edited copy
# of this file is kept, and no longer receives mxcli's updates to the rule):
#
# rules:
# CUSTOM002:
Expand Down
3 changes: 2 additions & 1 deletion .claude/lint-rules/orphaned_elements.star
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
# as a YAML list or comma-separated text. Replaces
# the built-in list below; unset keeps it.
#
# Edit the option, not this file: `mxcli init` rewrites the shipped rules.
# Edit the option, not this file: an edited copy is kept, and no longer
# receives mxcli's updates to the rule.

RULE_ID = "QUAL004"
RULE_NAME = "Orphaned Elements"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "cmd/mxcli", "date": "2026-10-21", "symptom": "`mxcli init .` and `mxcli init --sync-skills .` (run at every session start by the generated SessionStart hook) overwrite an edited bundled lint rule — `Refreshed 1 bundled lint rule(s) in .claude/lint-rules/ to match this mxcli: example_microflow.star` — and, when the edit is moved to my_prefixes.star, write the stock example_microflow.star back beside it so CUSTOM002 fires from the stock list again", "cause": "Bundled rules were recognised by file name only: `syncBundledLintRules` rewrote any bundled-name file whose bytes differed from the binary's, and `init`'s two WalkDir loops wrote every bundled file unconditionally; neither could tell an old stock copy from a project's edit, and a missing bundled name was always recreated", "file": "`cmd/mxcli/lint_rules_bundled.go` (`writeBundledLintRules`, the one write path for init, init --sync-skills and add-tool), `cmd/mxcli/lint_rules_shipped.txt` (sha256 of every version ever shipped, seeded from git history); tests `cmd/mxcli/lint_rules_bundled_test.go`", "insight": "'Is this file still ours?' needs the set of everything we ever shipped, not the current version: with only the current one, an unedited copy from any older mxcli is indistinguishable from an edit, and the choice is between overwriting edits and freezing every older project. The set is recoverable after the fact from git (every blob of the directory at every commit reachable from main, `git fetch --unshallow --filter=blob:none` first in a shallow clone); the v0.27.0 stock md5 in the report (cec8b599) matched one of them, which is the check that fork history covers what was released. Keep the set current with a test that the embedded version's hash is listed — it fails on the commit that changes a rule and prints the line to add. For the renamed copy, the reliable signal is the rule ID, not a manifest of names written: another file defining the bundled rule's RULE_ID is the edit moved, and it needs no state on disk, so it works for projects initialised before the fix. Normalise CRLF before hashing, or a Windows checkout of a stock rule reads as an edit. Two existing comments in shipped rules said '`mxcli init` rewrites this file' and became false with the fix — changing them is itself a new shipped version, which the currency test caught", "refs": ["mendixlabs/mxcli#1615", "ako/mxcli#1543", "ako/mxcli#952", "mendixlabs/mxcli#1509"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"cmd/mxcli","date":"2026-10-22","symptom":"`mxcli run --local --ensure-db` on a standard Windows PostgreSQL install: \"no local PostgreSQL superuser available to create the role/database (tried a direct 'psql -U postgres' connection over the cluster socket and TCP, and non-interactive 'sudo -u postgres' ...)\" — the installer always gives postgres a password, there is no sudo, and the error offered no way out","cause":"`resolveSuperuser` only knew passwordless paths (trust socket, peer auth via sudo) and had no way to accept an admin login; its error listed what was tried, not what to do","file":"`cmd/mxcli/docker/ensuredb.go` (`dbAdmin`, `resolveSuperuser`, `noSuperuserHint`, `superuser.psql`); flags in `cmd/mxcli/cmd_run.go`; refusal without --ensure-db in `runlocal.go` `applyDatabaseDefaults`","insight":"`--db-admin-user`/`--db-admin-password` are tried ALONE when given — falling back to sudo after they fail would hide that the user's own login was rejected, so their psql error is returned verbatim. The password goes through PGPASSWORD on the child env, never argv. **PGPASSWORD for postgres already worked before this fix** (the direct TCP candidate inherits the environment, and -w only forbids prompting, not reading PGPASSWORD/.pgpass) — measured with the pre-fix binary against a real PG16 cluster initdb'd with `-U postgres --auth=scram-sha-256 --pwfile`: no env → the reported error verbatim, PGPASSWORD=… → role and database created. So the defect was as much an undiscoverable escape hatch as a missing feature; the error now names it, the flags, and the two CREATE statements (with names filled in, the app password NOT echoed — this text lands in logs). A Linux scram-only cluster run by a non-root user is a faithful stand-in for the Windows shape: no trust socket mxcli knows of, no sudo route to a `postgres` OS user","refs":["mendixlabs/mxcli#1485","#1342"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"cmd/mxcli","date":"2026-10-22","symptom":"`run --local --watch` on Mendix 11.12.5: the first hot reload after a model change (one new microflow) reports \"applied: build #2 via reload in 4.3s\" but leaves deployment/web/dist holding only index.js and chunks/ — no pages/, no widgets.css — so every page fails with \"An error occurred while loading page\" until the loop restarts. A page edit in the same state FAILS instead, with \"Could not find a part of the path '…/web/pages/<Page>.js'\"","cause":"mxbuild --serve in the prebuilt shape (mxbuild writes web/dist itself): only the FIRST build in a serve process bundles completely; it leaves no web/pages, web/layouts or bundler config for its own incremental builds. Every later build replaces dist with a 683 KB monolithic index.js + one chunk (a non-page change, or NO change) or fails (a page change). mxcli's existing guards could not see it: ensureClientServed probes index.js and its static imports (both fine), and missingPageChunks needs web/pages source, which the prebuilt shape never has","file":"`cmd/mxcli/docker/serve_recovery.go` (`serveRecovery`, `readPrebuiltBundle`, `lostIn`); `mxserve.go` (`ServeServer.Restart`); `runlocal.go` (`watchAndApply` builds through it)","insight":"Settled by driving mxbuild's /build API from a 40-line harness, no watch loop: cold → 13 pages/5.6 KB index.js; second build, model UNCHANGED → 0 pages/683 KB; after rm web/dist → same; after rm web/ → Failure; fresh process → complete. The unchanged-model row is what rules out 'something in the change' and every deployment-side repair at once. A fresh process's first build reports restartRequired=true even for an unchanged model, so recovery keeps the INCREMENTAL build's answer — otherwise each change would restart the runtime and drop sessions. The wrong turn to skip: snapshot-and-restore of the old dist. The incomplete build's index.js is a different bundle (different chunk hashes), so restoring old pages/chunks next to it mixes two module graphs. This is the same defect the 11.14 hint in webclient_legacy_paths.go described as 'nothing outside the process fixes it' — true of the deployment, false of the process; that hint now only prints if the fresh process fails too. Controls: pre-fix binary on the same app → dist = chunks index.js, `mxcli playwright check` FAIL (error banner, 2 console errors, 2 failed requests); fixed → reload in ~29s, 13 pages, check OK, and a page edit (previously a hard failure) applies with the new title in the chunk","refs":["mendixlabs/mxcli#1580","#1485"],"test":"cmd/mxcli/docker/serve_recovery_test.go"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area":"cmd/mxcli","date":"2026-10-22","symptom":"`run --local --watch`: after a Sass error in a theme module is fixed, every following build fails with \"[CE6093] The theme could not be compiled\" quoting the FIRST error's line, which is no longer in the file; changing to a different error still reports the first; `touch app.mpr` does not help, `mxcli run restart` does. The app keeps serving the last good CSS","cause":"mxbuild --serve keeps its first theme compile error as process state and re-reports it as CE6093 (0.3s, no recompile) on every later build in the same process. Not mxcli, not the project: the bundled Dart Sass compiles the generated entry point cleanly at the same moment","file":"`cmd/mxcli/docker/serve_recovery.go` (`serveRecovery.themeFailed`, `observe`, `isThemeFailure`)","insight":"Isolated in one harness run against mxbuild 11.12.5's /build API: broken → 'An error occurred while compiling Theme files'; fixed, same process → CE6093 quoting the old error (twice); fresh process → Success. The trigger is 'a theme failure following a theme failure in the same process' — not 'any theme failure' (a first one is genuine and must not cost a 25s restart) and not 'CE6093' alone (it is just the later builds' spelling). A failure that survives the restart is reported from the fresh process and is current, which also fixes 'a different error still reports the first'. The serve restart is shared with #1485's recovery (same class: state in a long-lived mxbuild --serve that only a fresh process clears — see local-loop-silence 'Stale state has more than one home'). Cost the reporter's step list paid: the theme-only fix applies via runtime RESTART, because the fresh build's restartRequired is always true and there is no successful incremental build to take it from. Controls on the same app: pre-fix binary → build #3 failed [CE6093] Undefined variable, served CSS without the fix; fixed → build #3 applied, served CSS has #123456","refs":["mendixlabs/mxcli#1577","#1482"],"test":"cmd/mxcli/docker/serve_recovery_test.go"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/backend", "date": "2026-10-21", "symptom": "TestApp round trip: re-executing `describe consumed rest service Mappings.RestClient` (a Studio Pro-authored service, nothing changed) rewrote the unit: `/Operations[0]: 3 -> 2`, `/Operations[1](Request)/Headers[0]: 3 -> 2`, `/Operations[1](Request)/Parameters[0]: 3 -> 2` — law getput, surfaced the moment `Response: json` started to parse", "cause": "consumed_rest_write.go registered marker 2 for Rest$RestOperation, Rest$HeaderWithValueTemplate and Rest$OperationParameter lists (and the mandatory empty Operations/Headers/Parameters lists), copied from the legacy serializer in the parity port and never measured; Studio Pro writes 3 for those three and 2 only for QueryParameters", "file": "`mdl/backend/modelsdk/consumed_rest_write.go` (init registrations), `mdl/backend/modelsdk/consumed_rest_edit.go` (the ALTER splice keeps the stored Operations marker); test `mdl/backend/modelsdk/consumed_rest_markers_test.go`; `mdl/roundtrip/testapp_allowlist_test.go` (Mappings.RestClient struck)", "insight": "An allowlisted failure at one law can hide a failure at the next: Mappings.RestClient sat on the allowlist as 'breaks parse' since it joined the harness, so nobody ever executed its describe output, and the wrong markers had nothing to fail against. Fixing the parse is what exposed them — expect the outcome of a struck allowlist entry to move one law down, not to go green. Two independent Studio Pro measurements settle a marker cheaply when the census projects are not at hand: the stored bytes of a Studio Pro-authored fixture (TestApp, 11.14.0) and `mx convert -p` of an mxcli-written project (11.6.6), which re-serializes exactly the non-canonical units; they agreed field for field (3/3/3, QueryParameters 2, Tags 1). A comment saying a value 'mirrors the legacy serializer' is a flag that it was never measured", "refs": ["mendixlabs/mxcli#1608", "ako/mxcli#1536", "ako/mxcli#1551", "#721"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/backend", "date": "2026-10-21", "symptom": "A microflow created over --mcp (Studio Pro PED, 11.15.0-rc.4) read back with every sequence flow 1 -> 3: a CASE built with `@anchor(from: bottom, Approved: (from: right), (empty): (from: bottom, to: top))` lost all three anchors and the merge's bottom exit. A script with any `@annotation` failed the create outright: `microflow object type *microflows.Annotation is not yet supported by the MCP backend`.", "cause": "buildFlowDocContent mapped a SequenceFlow to originId/destinationId/caseValue only, so Studio Pro applied its right -> left default; the splice (flowPatchOps) already sent originConnectionSide/destinationConnectionSide. mapObjectTree had no Annotation case and ObjectCollection.AnnotationFlows was never read. The splice's note line used originId/destinationId, the SequenceFlow constructor's keys. PED's AnnotationFlow is an element type that takes origin/destination plus the required originConnectionIndex/destinationConnectionIndex, and refuses the constructor keys with `\"/origin\":\"Expected reference (string), got undefined\"`. That bug was hidden because the note was refused before its line was mapped.", "file": "mdl/backend/mcp/microflow.go (buildFlowDocContent, mapObjectTree, setPEDSides, pedAnnotationFlow, adaptMicroflowSkeleton, CreateMicroflow), mdl/backend/mcp/microflow_mutator.go (flowPatchOps), sdk/microflows/microflows.go (AnnotationFlow.SidesOrDefault)", "insight": "Compare engines, not shapes: run the same script through the modelsdk engine and over --mcp, then diff each flow's (origin, destination, sides) after resolving PED's $id(/objectCollection/objects/N) references to positions. That diff covered all 10 flows (identical after the fix, every one 1 -> 3 before) and settled the bug faster than reading either writer. Read ped_get_schema per element type: 'constructor type' and 'element type' differ in key names (originId vs origin) for what looks like the same flow list. PED's read-back omits a property at its default, so a missing connection index means 0 (Top), not absent. The pre-11.14 constructor cannot type a flow, so notes are refused there: an untyped note line would be read as a SequenceFlow. Within one update PED stores an AnnotationFlow after a SequenceFlow added later, so the splice adds its note lines last; otherwise its index-addressed sets on the new sequence flow would point at the wrong flow. Still open: ALTER insert over MCP on 11.15 fails whenever it sets line/<end>ControlVector on a flow added in the same update (`undefined is not an object (evaluating 'u.$Type')`), with or without a note.", "refs": ["ako/mxcli#1528"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/backend", "date": "2026-10-21", "symptom": "On Studio Pro 11.15.0-rc.4 every `alter microflow … { insert after … begin … end; }` over --mcp failed: `ped_update_document … undefined is not an object (evaluating 'u.$Type')`, with or without a note; a plain one-activity insert reproduced it. With that set removed, the insert landed but ped_check_errors reported `No action defined` on the new activity, and an inserted IF/ELSE came back wired to the wrong objects (the activity before it led into the else-branch log).", "cause": "flowPatchOps sent the whole insert as one update and addressed the elements it added in that same update by index: /flows/N/line/<end>ControlVector, /objectCollection/objects/N/action, …/relativeMiddlePoint, /flows/N/isErrorHandler. PED resolves a path against the document as it was before the update, so none of those reach the new element. A set below a new flow's line dereferences a line that is not there yet and fails the whole update. Any other set is accepted and lost, and so is the same property put in the constructor value (an ActionActivity's constructor takes only x/y/caption). Separately, several index-less appends to one array in one update are stored in reverse, and $id(/…/N) resolves against that final order, so with more than one new object every flow reference pointed at the wrong one.", "file": "mdl/backend/mcp/microflow_mutator.go (SaveUnit, flowPatchOps, newFlowLineOps)", "insight": "Two direct ped_update_document probes settle what an update can address, and they are cheaper than any reading of the code. First, add an element and set one of its properties in the same update, then read it back. Second, send the same set in a separate update. The difference is the whole bug. The separate-update set always landed: control vectors, action and isErrorHandler alike. So the fix is two updates. The first is all or nothing: the new elements, wired with $id(), and the stored elements moved to make room. The second fills in the new elements. A failed second update leaves an incomplete insert in Studio Pro, the same contract as CreateMicroflow's create-then-set. That is the price of 11.15, and the error says so. For ordering, give every add the array's stored length as its index; PED keeps adds at one shared index in listed order (its documented rule for inserting several elements at a position). The 1534 finding's 'an AnnotationFlow added before a SequenceFlow is stored after it' was this reversal, not something about annotation flows. A one-activity insert hides both bugs, because it adds one object and one flow, so verify with an insert of several elements (an IF/ELSE) and compare every flow's ends, sides and vectors against the same script run locally.", "refs": ["ako/mxcli#1534"]}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"area": "mdl/executor", "date": "2026-10-21", "symptom": "`create or modify consumed rest service M.S (…) { operation GetBooking (…) operation PutBooking (…) }` on a service holding PostBooking deletes PostBooking, and the only output is `Modified rest client: M.S (2 operations)`; the session log shows one CreateRestClientStmt with errors_count 0", "cause": "createRestClient builds the service's operation list from the statement alone and reports the count it wrote; nothing compared it with the stored list", "file": "`mdl/executor/cmd_rest_clients.go` (warnDroppedRestOperations, called after the write); test `mdl/executor/issue1608_consumed_rest_dropped_ops_test.go`", "insight": "Same remedy as `create or modify entity` (findings #24): a full-replace statement that drops members is doing what it says, so warn rather than refuse — but name the members, and name the incremental statement, which has to exist first (the hint was held back until `alter consumed rest service` landed, or it would have pointed at a parse error). A success line that reports the NEW count reads like confirmation; the count of what was removed is what the reader needed. The control is the same statement restating every operation: it must print no warning", "refs": ["mendixlabs/mxcli#1608", "ako/mxcli#1536"]}
Loading
Loading