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
24 changes: 22 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
- name: Run strict test suite
env:
MXRB_COVERAGE: "1"
MXRB_LINE_COVERAGE_MIN: "98"
MXRB_BRANCH_COVERAGE_MIN: "95"
MXRB_LINE_COVERAGE_MIN: "100"
MXRB_BRANCH_COVERAGE_MIN: "100"
MXRB_ACCEPTANCE_MPRS: /tmp/mxcli-sudoku/Sudoku/Sudoku.mpr
run: bundle exec rspec

Expand All @@ -59,7 +59,27 @@ jobs:
ruby-version: "4.0"
bundler-cache: true

- name: Restore pinned ONNX model cache
uses: actions/cache@v4
with:
path: ~/.cache/informers
key: informers-${{ runner.os }}-1.3.0-all-MiniLM-L6-v2-1110a243fdf4706b3f48f1d95db1a4f5529b4d41

- name: Warm pinned ONNX model cache
run: |
for attempt in 1 2 3 4 5; do
if bundle exec ruby -Ilib -e 'require "mxrb"; Mxrb::Semantic::OnnxEmbedder.new.dimension'; then
exit 0
fi
if [ "$attempt" = 5 ]; then
exit 1
fi
sleep $((attempt * 10))
done

- name: Run real ONNX semantic-search smoke test
env:
INFORMERS_OFFLINE: "1"
run: bundle exec rspec spec/semantic_search_spec.rb

sqlite-vec:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,13 +154,13 @@ and persisted state through entity/XPath count assertions.

```sh
bundle exec rspec
MXRB_COVERAGE=1 bundle exec rspec
MXRB_COVERAGE=1 MXRB_LINE_COVERAGE_MIN=100 MXRB_BRANCH_COVERAGE_MIN=100 bundle exec rspec
bundle exec ruby script/branch_report.rb
bundle exec rubocop
```

The enforced suite currently has 100% line and branch coverage. The branch
report lists any regression by source file and line.
CI and the local coverage helper enforce 100% line and 100% branch coverage.
The branch report lists any regression by source file and line.

Architecture and deeper writing guidance are available in
[the English documentation](docs/en-US/README.md). The complete documentation
Expand Down
105 changes: 102 additions & 3 deletions bin/mxrb
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,50 @@ when "widgets"
puts "[mxrb] Synchronized widget schemas with #{result.mx_path}"
puts "[mxrb] Generated #{result.project}"

when "frontend"
frontend_usage = <<~USAGE
Usage: mxrb frontend migrate FILE.mpr [--apply] [--json]

Preview frontend widget, layout-row, and design-property migrations.
The MPR is changed only when --apply is provided and the plan is safe.
USAGE
action = ARGV.shift
if action.nil? || %w[-h --help help].include?(action)
puts frontend_usage
exit(action.nil? ? 1 : 0)
end
abort "Unknown frontend action #{action.inspect}; use migrate" unless action == "migrate"
if %w[-h --help].include?(ARGV.first)
puts frontend_usage
exit 0
end
path = ARGV.shift or abort "Usage: mxrb frontend migrate FILE.mpr [--apply] [--json]"
apply = !ARGV.delete("--apply").nil?
json = !ARGV.delete("--json").nil?
abort "Unknown arguments: #{ARGV.join(' ')}" unless ARGV.empty?
plan = Mxrb::Frontend::Migrator.plan(path)
plan.apply! if apply && plan.safe?
payload = {
version: plan.version, changes: plan.changes.size, widgets: plan.widgets,
layout_rows: plan.layout_rows, design_properties: plan.design_properties,
issues: plan.issues.map(&:to_h), safe: plan.safe?, applied: plan.applied?
}
if json
puts JSON.pretty_generate(payload)
else
puts "Version : #{payload[:version]}"
puts "Changes : #{payload[:changes]}"
puts "Widgets : #{payload[:widgets]}"
puts "Layout rows : #{payload[:layout_rows]}"
puts "Design properties : #{payload[:design_properties]}"
puts "Safe : #{payload[:safe]}"
puts "Applied : #{payload[:applied]}"
plan.issues.each do |issue|
puts "[#{issue.kind.to_s.upcase}] #{issue.unit_id}#{issue.path}: #{issue.message}"
end
end
exit 1 unless plan.safe?

when "export"
source = ARGV.shift or abort "Usage: mxrb export <file.mpr> <ruby-project-dir>"
output = ARGV.shift or abort "Usage: mxrb export <file.mpr> <ruby-project-dir>"
Expand Down Expand Up @@ -1037,7 +1081,7 @@ when "team-server"

when "marketplace"
marketplace_usage = <<~USAGE
Usage: mxrb marketplace <login|search|show|versions|pull|import|audit|list|verify> ...
Usage: mxrb marketplace <login|search|show|versions|pull|dependencies|update|remove|import|audit|list|verify> ...

marketplace login --pat-file FILE [--no-verify]
Recommended: store only a path and read the PAT from FILE or a Ruby .env.
Expand All @@ -1052,15 +1096,21 @@ when "marketplace"
marketplace import FILE.mpk --mpr FILE.mpr
Import an official Mendix module package directly with Ruby/SQLite/BSON.
marketplace pull NAME[@VERSION] --mpr FILE.mpr [--mendix-version VERSION]
Download from the official Marketplace and import directly into the MPR.
Download official Module, Service, or Widget content and install it transactionally.
marketplace pull github:ORG/REPO --mpr FILE.mpr
Use a public GitHub release instead of the official Marketplace.
marketplace update NAME[@VERSION] [--mpr FILE.mpr] [--apply]
Preview a reference-safe official update; mutate only with --apply.
marketplace remove NAME [--mpr FILE.mpr] [--apply]
Preview reference-safe removal; mutate only with --apply.
marketplace dependencies NAME [--mpr FILE.mpr] [--apply|--apply-resolved]
Resolve module references and WidgetIds; verify every downloaded MPK identity.
marketplace audit [--target DIR] [--mendix-version VERSION]
Check locked official components for updates and known vulnerabilities.
marketplace list|verify [--target DIR]
Inspect or verify .mxrb/marketplace.lock.json and cached packages.

Module import does not invoke mx, mxcli, Studio Pro, or the Model SDK.
Module/widget installation does not invoke mx, mxcli, Studio Pro, or the Model SDK.
USAGE
marketplace_login_usage = <<~USAGE
Usage:
Expand Down Expand Up @@ -1103,6 +1153,19 @@ when "marketplace"
end
mpr = option.call('--mpr')
target = option.call('--target') || (mpr ? File.dirname(File.expand_path(mpr)) : Dir.pwd)
plan_state = lambda do |plan|
next 'partial applied' if plan.applied? && !plan.safe?
next 'applied' if plan.applied?

plan.safe? ? 'safe preview' : 'blocked preview'
end
print_lifecycle_plan = lambda do |plan|
state = plan_state.call(plan)
version = plan.target_version ? " -> #{plan.target_version}" : ''
puts "[mxrb] #{plan.action} #{plan.name} #{plan.installed_version}#{version}: #{state}"
plan.changes.each { puts " change: #{_1}" }
plan.blockers.each { puts " blocker: #{_1}" }
end
begin
case action
when 'login'
Expand Down Expand Up @@ -1216,6 +1279,40 @@ when "marketplace"
puts "[mxrb] Imported #{result.package.name} into #{result.destination}"
puts "[mxrb] #{result.units} MPR units written without Studio Pro" if result.respond_to?(:units)
puts "[mxrb] SHA-256 #{result.sha256}"
when 'update'
identifier = ARGV.shift or
abort 'Usage: mxrb marketplace update <name[@version]> [--mpr FILE] [--apply]'
name, version = identifier.split('@', 2)
plan = Mxrb::OfficialMarketplace::Installer.new(target:, mpr:).update_official(
name, version:,
mendix_version: option.call('--mendix-version'),
allow_vulnerable: !ARGV.delete('--allow-vulnerable').nil?,
apply: !ARGV.delete('--apply').nil?
)
print_lifecycle_plan.call(plan)
exit 1 unless plan.safe?
when 'remove'
identifier = ARGV.shift or
abort 'Usage: mxrb marketplace remove <name> [--mpr FILE] [--apply]'
plan = Mxrb::OfficialMarketplace::Installer.new(target:, mpr:).remove(
identifier, apply: !ARGV.delete('--apply').nil?
)
print_lifecycle_plan.call(plan)
exit 1 unless plan.safe?
when 'dependencies'
identifier = ARGV.shift or
abort 'Usage: mxrb marketplace dependencies <name> [--mpr FILE] [--apply|--apply-resolved]'
apply = !ARGV.delete('--apply').nil?
apply_resolved = !ARGV.delete('--apply-resolved').nil?
abort '--apply and --apply-resolved are mutually exclusive' if apply && apply_resolved
plan = Mxrb::OfficialMarketplace::Installer.new(target:, mpr:).dependencies(
identifier, apply:, apply_resolved:
)
state = plan_state.call(plan)
puts "[mxrb] dependencies #{plan.root}: #{state}"
plan.changes.each { puts " change: #{_1}" }
plan.blockers.each { puts " blocker: #{_1}" }
exit 1 unless plan.safe?
when 'list'
packages = Mxrb::OfficialMarketplace.lock(target).fetch('packages')
packages.each { |name, entry| puts "#{name}\t#{entry['version']}\t#{entry['source']}" }
Expand Down Expand Up @@ -1402,6 +1499,8 @@ else
--output FILE Uses installed Runtime files; never calls mx/mxbuild
mda inspect|compare <file.mda> Inspect or diff MDA contents and metadata
widgets sync <definition.rb> <mpr> Synchronize pluggable widget schemas
frontend migrate <file.mpr> Preview frontend schema/layout/theme migration
[--apply] [--json] Apply only a safe plan or emit structured output
export <file.mpr> <directory> Convert an MPR to editable Ruby
validate <file.mpr> Check MPR structure, hashes and v2 contents
preflight <file.mpr> [--json] Audit native compiler/runtime compatibility
Expand Down
20 changes: 11 additions & 9 deletions docs/de-DE/compiler.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Abhängigkeiten und ein Runtime-kompatibel geordnetes BSON-`model.mdp` werden
ebenfalls erzeugt.

Der Bootstrap besitzt auditierte Seeds und Kataloge für 6.10.8, 7.5.0,
7.17.0, 9.6.1.29396 und 11.12.1. Die Familien 6.x, 7.x, 9.x und 11.x wählen
einen kompatiblen Compiler-Seed; 5.x, 8.x und 10.x schlagen ohne auditierten
7.17.0, 9.6.1.29396, 10.24.0.73019 und 11.12.1. Die Familien 6.x, 7.x, 9.x, 10.x und 11.x wählen
einen kompatiblen Compiler-Seed; 5.x und 8.x schlagen ohne auditierten
Seed geschlossen fehl. Die Familie gilt nur für das Compiler-Schema. Die
Runtime muss exakt zum Patch des MPR passen.

Expand All @@ -24,9 +24,10 @@ mise, kompiliert `javasource/**/*.java` gegen Runtime- und Projektbibliotheken
und schreibt ein deterministisches OSGi-`project.jar`. Für VetClinic wurden 183
Quelldateien zu 249 Klassen kompiliert.

`WebBundleBuilder` wählt Dojo für 6/7, Dojo mit React-Wrapper für 9 und React
für 11. Der React-Pfad erzeugt Entry-/Seitenmodule, entpackt `.mpk` und ruft
Node/Rspack der Version direkt auf. Data Grid 2 wird für den Teilumfang aus XPath-Datenquelle
`WebBundleBuilder` wählt Dojo für 6/7, Dojo mit React-Wrapper für 9, den im
Projekt gewählten klassischen oder optimierten Client für 10 und React für 11.
Der React-Pfad erzeugt Entry-/Seitenmodule, entpackt `.mpk` und ruft direkt
Node/Rollup für 10 oder Node/Rspack für 11 auf. Data Grid 2 wird für den Teilumfang aus XPath-Datenquelle
und Attributspalten kompiliert, einschließlich `operations.json`, Datenquelle
und Attributtypen. Noch nicht übersetzte Typen oder Eigenschaftskombinationen
erhalten einen DOM-Fallback in `web/mxrb-pages.json`; das VetClinic-Manifest ist
Expand Down Expand Up @@ -144,14 +145,15 @@ Seitenbundles und fuhr sauber herunter. Danach bestand der Funktionstest
## Explizite Grenzen

- alle 12 Stufen und saubere Web-Generierung sind für 6.10.8, 7.5.0, 7.17.0,
9.6.1.29396 und 11.12.1 validiert;
- ein exakter nativer Boot ist für 11.12.1 belegt. Die installierten
9.6.1.29396, 10.24.0.73019 und 11.12.1 validiert;
- ein exakter nativer Boot ist für 10.24.0.73019 und 11.12.1 belegt. Die installierten
6/7/9-Distributionen enthalten exakte Runtime-Bundles, aber keinen
PAD/Launcher; `db up` schlägt geschlossen fehl, statt den Java-21-Launcher
kompatiblen Launcher; `db up` schlägt geschlossen fehl, statt den Java-21-Launcher
aus Version 11 einzusetzen;
- Data Grid 1 ist abgedeckt, andere Dojo-Widgets bleiben explizite
Manifestbefunde;
- der Mendix-11-React-Pfad besitzt saubere Preflights und vollständige
- der optimierte Mendix-10-React/Rollup-Pfad ist durch eine neu erstellte
Anwendung belegt; der Mendix-11-React-Pfad besitzt saubere Preflights und vollständige
Rspack-Builds für LearnNow, MyFirstModule, SLATaskApp, Sudoku und VetClinic.
Diese Fixture-Matrix belegt auditierte Verträge, keine universelle Kompatibilität;
- native Web-Bundles werden erzeugt; React Native verwendet weiterhin
Expand Down
24 changes: 13 additions & 11 deletions docs/de-DE/native-runtime-quality-report.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
# Qualitätsbericht für nativen Build und Runtime

Datum: 1. August 2026.
Datum: 4. August 2026.

## Bestätigtes Ergebnis

- keine funktionale Stufe ruft `mx`, `mxbuild`, `mxcli`, Studio Pro oder Model SDK auf;
- sauberer 12-Stufen-Build und Web-Generierung bestanden mit 6.10.8 (39 Seiten), 7.5.0 (45), 7.17.0 (66), 9.6.1.29396 (90) und 11.12.1;
- sauberer 12-Stufen-Build und Web-Generierung bestanden mit 6.10.8 (39 Seiten), 7.5.0 (45), 7.17.0 (66), 9.6.1.29396 (90), 10.24.0.73019 (optimierter Client) und 11.12.1;
- die Round-trip-Matrix bestand mit sechs echten Fixtures von 5.21.4 bis 11.12.1: 1.506 Units, 1.734 Artefakte und 3.388 Referenzen;
- auditierte Compiler-Schemas/Seeds decken 6.x, 7.x, 9.x und 11.x ab. 5.x, 8.x und 10.x schlagen bei nativer Kompilierung geschlossen fehl; Runtime benötigt den exakten Patch;
- auditierte Compiler-Schemas/Seeds decken 6.x, 7.x, 9.x, 10.x und 11.x ab. 5.x und 8.x schlagen bei nativer Kompilierung geschlossen fehl; Runtime benötigt den exakten Patch;
- Data Grid 1 deckt Datenbank/XPath/Microflow, Suche, Sortierung, Paging, Auswahl und auditierte Buttons ab. Data Grid 2 deckt XPath, Attributspalten und Create ab;
- Webprofile: Dojo in 6/7, Dojo/React-Hybrid in 9 und React in 11;
- Webprofile: Dojo in 6/7, Dojo/React-Hybrid in 9, projektabhängig klassisch/optimiert in 10 und React in 11;
- Projects API inventarisierte 130 Apps. Drei echte Git-Projekte (`MyFirstModule`, `LearnNow Trainning Management`, `SLATaskApp`) bestanden validate → export → generate → validate → compare;
- `MyFirstModule` wurde ohne proprietäre Builder als exaktes 11.12.1 erzeugt. Runtime synchronisierte 655 Operationen, erstellte den aktiven Admin `mx`, lieferte React-Shell und gestaltetes Login auf `127.0.0.1:18080` und zeigte die erwarteten Tabellen;
- finale QA: 821 Beispiele, null Fehler, 100% Zeilen (12.987/12.987), 100% Branches (4.611/4.611) und RuboCop ohne Verstöße in 205 Dateien.
- eine neu erstellte 10.24.0.73019-Anwendung mit optimiertem Client bestand offizielles `mx check` und `mxbuild`, natives Modell/Java/Rollup/Portable-Paket, 460 Datenbanksynchronisierungen, Readiness-Probe und HTTP 200;
- finale QA: 1.002 Beispiele, null Fehler, 100,00% Zeilen (16.917/16.917), 100,00% Branches (6.659/6.659) und RuboCop ohne Verstöße in 238 Dateien.

## Korrekturen aus dem Verbesserungsbericht

Expand All @@ -35,8 +36,9 @@ Datum: 1. August 2026.
Teacher-Gallery blieb strukturell vorhanden;
- Nanoflow-Listen-/Objektquellen und Button-Aktionen werden in die echten
Mendix-Clientverträge und funktionsreferenzierte Instruktionsprogramme
kompiliert. Der auditierte lineare Teilumfang ist getestet; nicht unterstützte
Clientknoten schlagen geschlossen fehl statt als Microflows zu erscheinen;
kompiliert. Der auditierte Graph-Teilumfang umfasst Entscheidungen,
Fehlerpfade, verschachtelte Nanoflows, JavaScript-Aktionen und serverseitige
Microflow-Aufrufe; nicht unterstützte Clientknoten schlagen geschlossen fehl;
- echte Browserklicks bestätigten Home → Courses → Add → Save. Parametergestützte
DataView/TextBox-Formulare rendern und speichern Werte; Create übergibt die GUID
über `openForm2`, während die Commit-/Rollback-Autorisierung aus den Modulrollen
Expand All @@ -48,10 +50,10 @@ Datum: 1. August 2026.

1. Andere Dojo-Widgets als Data Grid 1 bleiben in `web/mxrb-legacy-pages.json`; sie werden nicht als gerendert gemeldet.
2. Data Grid 2 deckt den auditierten XPath/Attribut/Create-Teil ab. Gallery deckt
XPath/Microflow und den auditierten linearen Nanoflow-Teil ab. Verzweigungen,
JavaScript-Aktionen, interne Microflow-Aufrufe und unsichere Parameterabbildungen
schlagen weiterhin geschlossen fehl.
3. Installierte 6/7/9-Distributionen enthalten exakte Bundles, aber keinen kompatiblen PAD/Launcher. Der 11-Launcher benötigt Java 21 und kann 9 unter Java 11 nicht sicher starten. Legacy-`db up` schlägt geschlossen fehl; nur der exakte 11.12.1-Boot wird behauptet.
XPath/Microflow und den auditierten Nanoflow-Graph-Teil ab. Nicht unterstützte
Graphformen, fehlende Referenzen, unsichere Parameterabbildungen und nicht
übersetzte Client-Instruktionen schlagen weiterhin geschlossen fehl.
3. Installierte 6/7/9-Distributionen enthalten exakte Bundles, aber keinen kompatiblen Launcher. Der 11-Launcher benötigt Java 21 und kann 9 unter Java 11 nicht sicher starten. Legacy-`db up` schlägt geschlossen fehl; exakter Boot wird nur für 10.24.0.73019 und 11.12.1 behauptet.
4. Runtime verwendet eine lokale Trial-/Developer-Lizenz mit erwarteter Zeitlimit-Warnung.
5. Cloud Build/Deploy/Pipelines/Backups sind optionale externe Prüfungen, nie Abhängigkeiten des nativen Kerns.

Expand Down
Loading
Loading