You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5524f6f
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: CHANGELOG.md
+30-3Lines changed: 30 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,17 +6,44 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
7
7
## [Unreleased]
8
8
9
+
## [0.17.0] - 2026-08-10
10
+
11
+
Headline: **A full Mendix build-and-test loop that fits on an iPad** — you can now design, build, run, observe, and debug a multi-app Mendix solution end-to-end from Claude Code on the web, on a phone or tablet, with no local IDE. Two capabilities make it possible: an **external browser preview** that reverse-tunnels a locally-running app out to a public URL from an egress-only container, and a **short agentic feedback loop** — a warm Docker-free runtime, sub-second microflow unit tests, live log/metric/trace observation, and a name-based microflow debugger — so an agent gets an answer in seconds instead of a build round-trip.
12
+
9
13
### Added
10
14
15
+
- **Build a Mendix app from Claude Code web, on an iPad or iPhone** — the app runs locally in the container and reverse-tunnels out over a single 443 connection to a static relay, so it is reachable in any browser at a public URL, verified live through the session's egress proxy. `mxcli run --hub <url>` boots the runtime with its `ApplicationRootUrl` set to the assigned URL (so the SPA and `originURI` work under the public origin) and retries forever; `mxcli tunnel-hub --domain <base>` is the **multi-tenant** relay that fronts many previews at per-subdomain hosts over one 443 with per-subdomain autocert, an availability overview **grouped by Claude Code session** (each session links back to its `claude.ai/code` conversation), and durable per-session endpoint history that survives restarts and reaping. A **SessionStart hook + bootstrap prompt** (`mxcli init`, `run --local --setup`, `docs-site/src/tools/bootstrap-prompt.md`) lets a fresh or reaped web session self-provision — cache mxbuild + runtime, ensure the local database — with no manual step, and the workflow covers **multi-app solutions**, not just a single app.
16
+
-**Hub GitHub authentication** (opt-in) — a **viewer plane** (GitHub OAuth + HMAC-signed SSO cookie, owner-checked previews, `--require-auth`) and a **registration plane** (durable hashed hub API keys presented as `X-Hub-Key`, minted from the hub's `/cli` browser page or `mxcli auth hub login --token <pat>`; `run --hub` reads `MXCLI_HUB_KEY` and degrades to local-only if registration fails). Append-only JSONL audit trail, no secrets. Absent flags leave today's open hub unchanged.
17
+
-**Docker-free microflow unit tests** (`mxcli test --local`) — tests run on mxcli's own warm runtime (no Docker daemon) on isolated ports and a `<project>_test` database, driving a **token-guarded test endpoint** — one microflow invoked per test over HTTP, so a throwing test fails only itself and results are returned rather than log-scraped. `--watch` keeps the runtime warm (~30s first run, then ~2s); `--attach` runs against an app already up under `run --local --test-endpoint` with no boot; `@cleanup` rolls back each test's writes.
18
+
-**The warm local dev loop** (`mxcli run --local [--watch] [--screenshot]`) — a Docker-free `mxbuild --serve` + standalone runtime with hot `reload_model` for behavioural changes and restart+DDL for structural ones, bundling the browser client so Mendix 11.x apps actually render. `--watch` keeps an incremental rollup bundler hot (~3–4s page re-bundle, skipped for model-only edits); `--ensure-db` provisions the local Postgres + app database; `--screenshot` captures a Playwright PNG each change, with `--screenshot-url` deep links and form-login via `--screenshot-user`/`--screenshot-password`.
19
+
-**Runtime observation — logs, metrics, and OpenTelemetry traces** — full visibility into the running app for an agent:
20
+
-**Logs** — the runtime log is tee'd to a file for inspection, and `feat(log)` drives the runtime's per-node log levels from MDL.
21
+
-**Metrics** — `run --local --metrics` registers a Prometheus Micrometer registry served at `/prometheus`; `--runtime-setting Key=Value` folds arbitrary runtime config (otlp/influx/statsd registries, span filters) into the single boot `update_configuration` call.
22
+
-**Traces** — `--trace` attaches the bundled OpenTelemetry Java agent with sensible default span filters (unfiltered per-activity tracing is ~10× slower); `--trace-otlp <endpoint>` switches to the OTLP exporter for a collector and flame charts; `--trace-service` sets the service name.
23
+
- An `analyze-runtime` skill ties logs, metrics, traces, and the catalog together.
24
+
-**Microflow/nanoflow debugger** (`mxcli debug`) — set breakpoints **by name** (activity resolved from the model), inspect paused flows and variables (`inspect --list` for list variables), and step over/into/out or continue against a `run --local` runtime; `run --local --debug` enables it at boot. Nanoflows are auto-detected, and nanoflow `LOG` output is rewritten to the runtime log's `Client_Nanoflow` node.
11
25
-**Default styling — generated apps that look designed on first boot** (`mxcli theme`, `mxcli new --theme`) — three themes ship in the binary: **signal** (the default: cool slate, one teal signal colour, 4px radius, 32px rows, IBM Plex), **ledger** (warm paper, hairline rules instead of card shadows, Source Serif over Source Sans) and **console** (dark-first, Space Grotesk over JetBrains Mono). A theme is files under `theme/` only — the model is never touched, so it hot-applies under `run --local --watch` and cannot affect a build. Atlas Core is untouched, so projects stay upgradable. Re-branding is one line (`--mxt-brand`); Atlas derives the whole colour ramp from it. Fonts are vendored (SIL OFL 1.1) rather than pulled from a CDN, so generated apps render correctly air-gapped. Generated regions are digest-fenced: a block carrying local edits is refused rather than overwritten. `mxcli theme list | show | apply | remove`; `--theme none` opts out. See `docs-site/src/tools/theme.md`.
12
26
-**Light/dark palettes and runtime theme switching** — every theme ships both palettes. `--variant auto` (the default) follows the operating system's `prefers-color-scheme`**before first paint** and honours a `theme-light` / `theme-dark` class on the root element; `--variant light|dark` bakes a single palette. Mendix ships the `:root.theme-dark` slot but nothing that applies it, so `mxcli theme switcher install` adds the JavaScript actions and a nanoflow for a toggle button — the one theme subcommand that writes to the model. Known limit: a reload falls back to the OS preference, because Mendix has no page on-load event and the usual substitute (a data view with a nanoflow data source) is not authorable on either engine yet.
27
+
-**Publish microflows and entities as OData** — `CREATE PUBLISHED REST SERVICE` gains the ability to publish a **microflow as an OData action** (with a named custom-authentication microflow), a `DESCRIBE` that round-trips it, and published-entity controls to turn `Countable`/`Skip`/`Top` on or off and to publish `Integer` as `Int64`. Generated external entities now follow the contract's `$top`/`$skip` capabilities and honour capability annotations.
28
+
-**`mxcli new` runs the first build** so a fresh clone does not go dirty the first time anyone builds it — the build settles the JS/Java action stubs MxBuild rewrites (48 tracked files in a blank 11.12 app). `mxcli theme apply` runs in the pipeline; `--skip-build` opts out.
29
+
-**New `check` heuristics** — caught at `mxcli check` before a build round-trip: `MDL053` (loop variable used outside its loop), `MDL054` (validation rules on a non-persistent entity), `MDL055` (XPath association traversal from a variable), `MDL056` (empty), a read microflow that cannot keep its OData resource's promises, a forward page reference without a project, and OData property names that are silently discarded. `MDL009` (false-positive) retired.
30
+
-**MDL language and authoring additions** — `SET` is now optional so `$Total = 5;` parses; multi-line strings and keyword widget names; `-` reads MDL from stdin (`exec`/`check`); `MENU ITEM … ICON` navigation icons; `MOVE JAVA ACTION` / `MOVE ODATA SERVICE`; `CREATE OR MODIFY MODULE ROLE`; `IF NOT EXISTS` / `IF EXISTS` on `ADD`/`DROP EVENT HANDLER`; declared JAR dependency resolution instead of silent skipping; a combobox binding an association via `Association:`; and dynamic-text parameter formatting via a `FORMAT` block.
31
+
32
+
### Changed
33
+
34
+
-**`QUAL002` sweeps every document type** (including Java actions and their parameters) and no longer reports the System module; every lint rule now excludes System, and `mxcli init` seeds a lint config that excludes it. Failed catalog queries in lint are reported rather than swallowed.
35
+
-**`mxcli new` pipeline** — now `mx create-project` → `mxcli theme apply` → `mxcli init` → first `mxbuild --target=deploy` → Linux mxcli binary, producing a ready-to-open, already-styled, already-built project.
13
36
14
37
### Fixed
15
38
16
-
-**`mxcli theme remove` with no name removed nothing** — it targeted the built-in default rather than the theme actually installed, so on a project themed with `ledger` or `console` it reported every file as unchanged and exited 0, leaving the theme in place. Both `apply` and `remove` now read the installed theme from the `mxcli:theme` markers; removing from a project with no theme is an error rather than a silent no-op. Reported from the RssReader test build.
17
-
-**Switching themes orphaned the previous theme's block in `_mxcli-atlas-map.scss`** — the file the three themes share was left with both blocks, doubling it. Harmless while the Atlas maps are identical, but it broke the documented "only one theme at a time" invariant. Reported from the RssReader test build.
18
-
-**The topbar language selector was unreadable in every dark palette** (1.13:1 measured contrast, against a WCAG AA target of 4.5). Atlas paints it from `--bg-color-secondary` with a `#fff` fallback at a specificity the theme's guard did not match. Now re-declared at matching specificity and resolved through the rail token — 17.79:1 light, 19.47:1 dark. Reported from the RssReader test build.
39
+
-**Page and widget serialization / round-trip** — a batch of fidelity fixes: an association datasource's name is now qualified (an unqualified one wrote an unloadable page); cross-module association paths and inherited attributes resolve in page bindings; a parameterized-microflow datasource binds its arguments; DataGrid2 dynamic-text columns carry their `FORMAT` block and no longer trip CE0463; `ALTER PAGE` reaches widgets inside a `customContent` column and sets an action button's caption via `CaptionTemplate`; empty/literal `DYNAMICTEXT` content and `ListView``PageSize` are honoured; `DownloadFileAction` writes on the modelsdk engine; an unresolved association `DestinationEntity` is never written.
40
+
-**Microflow / workflow correctness** — aggregates are kept whole now that `SET` is optional; the `InheritanceSplit` and its case values are written; the false branch of a conditional break/continue in a loop is wired; a dynamic query expression passes through unquoted; MDL comments are kept out of the Mendix expressions they sit in; `$workflowContext` is normalized in `DECISION` expressions; `DESCRIBE` no longer invents an `else` on a type split or an `on error rollback` clause; a standalone `annotation` (which wrote an unloadable model) is refused.
41
+
-**OData / integration** — `create-external-entities` no longer duplicates suffixed associations or renames an attribute called `name`; the modelsdk writer writes `AllowedModuleRoles`; a published service's role grants survive a modify; consumed REST operation mappings persist and read back (#843); `$metadata` is fetched with the client's own (constant-resolved) credentials.
42
+
-**Security** — a `GRANT` now covers every entity member, including both-owner associations and audit members; audit-member rights are rejected at check time (`MDL-SEC01`); a cross-module `GRANT` is reported before exec applies the script; demo users that cannot materialise are warned about.
43
+
-**`run --local` robustness** — the web client bundle is verified after boot, not before; stale ports are refused and the holding process is named; a relative project path resolves where MxBuild is called; the browser bundle is re-served after a structural `--watch` change; boot uses live-preview flags so `mxcli oql` can reach the app; the hub tunnel retries forever and re-registers on a heartbeat 404.
44
+
-**Theme** — `mxcli theme remove` with no name now reads the installed theme from the `mxcli:theme` markers instead of removing the built-in default and reporting a silent no-op; switching themes no longer orphans the previous theme's block in `_mxcli-atlas-map.scss`; the topbar language selector, filter-operator popovers, login page, and Data Grid 2 now follow the palette (the language selector went from 1.13:1 to 17.79:1 / 19.47:1 measured contrast).
19
45
-**JavaScript action sources were written to the wrong directory** — `CREATE JAVASCRIPT ACTION` wrote to `javascriptsource/<ModuleName>/actions/`, but Mendix reads a **lowercased** module directory. MxBuild found nothing there, generated a stub whose body throws `JavaScript action was not implemented`, and bundled that — so the action parsed, passed `mxcli check`, built cleanly, and threw the moment it ran. Only reproduced on a case-sensitive filesystem, which is why it went unnoticed on macOS and Windows.
46
+
-**Widget sync wrote duplicate GUIDs and corrupted the project** — reconciliation now removes stale properties and syncs attributes via `AugmentTemplate` so the widget `Type` is exact.
0 commit comments