Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .claude/skills/fix-issue/findings/cmd-mxcli.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,6 @@
{"date": "2026-10-02", "area": "cmd/mxcli", "symptom": "`run --local --watch` on Mendix 11.13: a page added while the loop runs is never bundled — the apply reports success (often 'applied via reload'), but opening the page 404s on dist/pages/<Module>.<Page>.js and the page stays blank; restarting the loop fixes it", "cause": "mxbuild's tools/node/rollup-plugin-mendix-pages.mjs (byte-identical in 11.13.0 and 11.14.0) globs web/pages only at bundler start: watchChange compares path.relative(cwd, id) against PAGES_FOLDER=\"./pages\" + \"/\", a './' prefix relative() never yields, so shouldRefreshPageFiles never flips. mxcli could not see it: ensureClientServed probes index.js and its static imports, and pages are dynamic imports", "fix": "missingPageChunks compares web/pages/**/*.js against web/dist/pages/**/*.js (shape-gated: needs web/pages and web/dist/index.js, so 11.14 prebuilt and classic are no-ops); under --watch watchAndApply restarts the WebClientWatcher (a fresh rollup run re-globs) and reports one line; ensureClientServed does a one-shot BuildWebClient for the same condition. RunLocal stops whichever watcher is current at exit", "insight": "A stand-alone rollup watch repro (pages/A.js, then add pages/B.js) isolates it in seconds: the 'change pages/B.js create' event fires but the next bundle still emits only A; a fresh watcher, or the plugin with PAGES_FOLDER=\"pages\", emits both. Restart rather than one-shot: the stale watcher would also never rebuild the new page when it is edited later. A structural change (navigation) clears web/dist and the old index.js fallback re-bundles everything, masking the bug; a page-only add applied via reload is the reproducing case. E2E 11.13: pre-change binary 404 on the new chunk; fixed binary 200 + page text, and a follow-up edit of the same page re-bundled incrementally with no restart (control)", "file": "cmd/mxcli/docker/webclient_pages.go (missingPageChunks, recoverMissingPages); cmd/mxcli/docker/runlocal.go (watchAndApply, ensureClientServed, RunLocal watcher defer)", "test": "cmd/mxcli/docker/webclient_pages_test.go"}
{"date": "2026-10-02", "area": "cmd/mxcli", "symptom": "A `.test.mdl` starting with `mdl 1;` loses its first test: `mxcli test --list` finds 41 of 42 with no message; `mxcli check` on it reads the bodies as mdl 0 (MDL-V1-SLASH / MDL-V1-LIMIT1 warnings fire under a file that says mdl 1); the generated runner scripts end every flow with `/`, which mdl 1 refuses; and `fmt --upgrade --header` adds no header to a test file", "cause": "Nothing in the test format read the header. It was body text in the first `/`-chunk, so that chunk's `/** @test */` was no longer a LEADING doc comment (scanDocComments) and parseMDLTests skipped it silently; CheckSource rendered only the bodies (dropping the header line) and put `END; /` on separators; GenerateTestRunner/GenerateTestFlows always wrote `/` and `create or replace`", "fix": "takeLanguageHeader reads the header with langver.HeaderSpan (the grammar's own rule: first token after trivia) and blanks it in place so lines/columns hold; TestCase carries Version + HeaderLine (markdown: per mdl-test block); CheckSource renders the header on its line and closes wrappers with `END;` (no `/`, any version); the generators write the header, `create or modify` and no `/` under mdl 1; parseTestFiles refuses a suite mixing versions (one suite = one script = one header); UpgradeSource honours AddHeader and writes the header at file top / inside each mdl-test block; UpgradeSource maps the upgraded rendering back with a line diff (difflib opcodes, every changed region must be body lines) instead of an index walk, because the MDL-V1-ESCAPE rewrite of `\\n` writes a real line break and adds a line; writeBodyLines no longer indents a body line that starts inside a string literal", "insight": "A header is not just a flag to pass along — in a format that is NOT parsed as one script, every consumer that splits the text has to take it out first, or it becomes content in whichever chunk it lands in. The silent drop came from the same 'leading doc comment' rule as #927; a per-test Version also forced the question 'what is a suite's version', which only refusal answers safely. The runtime run was what found the last defect: unit tests and `mx check` were green while an upgraded test asserting length 3 saw 5 — the generators indented the continuation line of a multi-line string literal, so the indent became part of the value. Compare an mdl 0 file, its fmt --upgrade output, and a headerless control in the running app (both runners)", "issue": "ako/mxcli#847", "file": "cmd/mxcli/testrunner/parser.go (takeLanguageHeader, suiteLanguageVersion); check_source.go; generator.go; generator_endpoint.go; upgrade_source.go; mdl/langver/langver.go (HeaderSpan)", "test": "cmd/mxcli/testrunner/language_header_test.go; e2e: mxcli test --local on a fresh 11.13.0 app, endpoint and --legacy-runner"}
{"date": "2026-10-02", "area": "cmd/mxcli/check", "symptom": "`mxcli check x.test.mdl -p app.mpr` reports `module not found: MxTest` once per test and exits 1 on a file `mxcli test` runs green — a test file can never pass check, and a real missing reference in a body is hidden behind it", "cause": "CheckSource wraps each test body in a `MxTest.Check_*` microflow (the runner's module), and the reference pass resolved that module against the project; the runner creates MxTest as the first statement of every generated script and drops it afterwards, so the project never has it", "fix": "testrunner.WithRunnerModule appends `create module if not exists MxTest` to the program used for the reference and project-conflict pass of a test file (appended so `statement N` still numbers the tests; definitions are collected program-wide; `if not exists` keeps a user's own MxTest from reading as a conflict)", "insight": "Seed the module the way the runner does, rather than exempting the file: the control (a body with a real missing entity) must still fail, and before the fix it showed only the MxTest error — the false positive was also masking true ones", "issue": "ako/mxcli#677", "file": "cmd/mxcli/testrunner/check_source.go (WithRunnerModule); cmd/mxcli/cmd_check.go", "test": "cmd/mxcli/check_test_file_refs_test.go"}
{"date": "2026-10-03", "area": "cmd/mxcli/check", "symptom": "`mxcli check -p` prints MDL067 (bare commit now WITH events) for a create-or-modify flow already stored with events, which `exec -p` no longer prints", "cause": "cmd_check ran ValidateProgram without the DropSettledCommitNotes filter exec_preflight applies; the project was only connected later, for the reference tier", "fix": "check connects to the project before the semantic report when -p is given, applies DropSettledCommitNotes and StoredTaskClaimViolations, and reuses that connection for the reference tier", "insight": "Two gates over one rule set drift whenever a post-filter lives in only one of them; grep for every caller of ValidateProgram when adding a filter. Control: a flow stored without events still notes", "issue": "ako/mxcli#943", "file": "cmd/mxcli/cmd_check.go", "test": "cmd/mxcli/check_stored_semantics_test.go"}
{"date": "2026-10-03", "area": "cmd/mxcli/test", "symptom": "every `mxcli test` run prints 2x MDL-DEPR001 and 2x MDL-V1-SLASH about a script the user never wrote", "cause": "GenerateEndpointMDL emitted a headerless mdl 0 script with `create or replace` and `/` terminators; the test-flow generators had already moved to the version-aware writeScriptHeader/createFlow/writeFlowEnd", "fix": "GenerateEndpointMDL writes mdl 1 through the same helpers (header, create or modify, `;` only); endpoint script is independent of the suite's version", "insight": "A generated script is checked like a user's one; pin it with a test that parses it and asserts ValidateProgram returns nothing. Verified end to end with `mxcli test --local` on a fresh 11.13 app", "issue": "ako/mxcli#943", "file": "cmd/mxcli/testrunner/endpoint.go", "test": "cmd/mxcli/testrunner/endpoint_clean_test.go"}
{"date": "2026-10-03", "area": "cmd/mxcli/theme", "symptom": "`theme create acme --from design.css` with `--mxt-font: \"Inter\", system-ui, sans-serif` prints nothing about Inter; the theme ships no woff2 and no @font-face for it and renders in the fallback font wherever Inter is not installed", "cause": "planFonts only decided which VENDORED families to drop; a seeded family outside the vendored set was never looked at, so the silent outcome was the default", "fix": "unvendoredSeededFamilies takes the primary (first) family of each seeded font stack, skips generic families and var() and the families the base partial loads, and CreateResult.UnvendoredFonts carries them to cmd_theme.go, which prints a note per family naming mxcli-fonts/ and the partial", "insight": "Only the first family of a stack is the design's choice; flagging the fallbacks (Helvetica, Arial) would make the note noise. The controls are a vendored family (IBM Plex Mono) and a generic stack, which must stay silent", "issue": "ako/mxcli#944", "file": "cmd/mxcli/theme/create_seeded.go (unvendoredSeededFamilies, planFonts); cmd/mxcli/cmd_theme.go", "test": "cmd/mxcli/theme/create_seeded_test.go (TestCreate_NamesSeededFontsItDoesNotVendor)"}
Loading
Loading