Skip to content

Commit 54cd032

Browse files
committed
Fix mxcli v0.29 compatibility; doctor advises the latest mxcli
On mxcli v0.29.0, which doctor --install fetches by default, four instruments misread the new output: - fix property-sets MIXED rows: doctor now classifies them as "mixed" instead of rc 4 "could not classify". - The repair exits 1 while only MIXED remains. The apply step no longer lets exec.sh --patch roll back a repair that landed. - fix hashes now verifies MPR v1 with new wording. exec.sh reads both forms, so --patch on Mendix < 10.18 is verified again. - SHOW/list modules "Protected AddOn|Solution" in Source (v0.28+): page-scope and the rehost module list keep first-party Protected modules. Also in this change: - wf-add-path-terminators.py refuses below Mendix 10.21. - module-close notes the v0.29 docker check default. - The stale v0.24 pin advice is gone. - New: the normal doctor run advises when the project mxcli is behind the latest release, respects MXCLI_VERSION pins, stays quiet offline and never fails. Golden input was captured from the real v0.28.0/v0.29.0 binaries (CAPTURE files hold the sha256s and mutation steps). Against master the new cases fail: exec-hash-verify 4, property-sets 7, mxpatch 1, page-scope-protected 3, rehost-list-modules 1, doctor-mxcli-latest 8. Field run: page-scope.sh and doctor.sh against the real v0.29.0 and v0.28.0 binaries on the captured model. Master page-scope FAULTs on the Protected model and the fix counts its page. The doctor advice read v0.29.0 from the live release redirect. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018LeNWZV2sVH62vkgfYh5u5
1 parent 2ba8158 commit 54cd032

59 files changed

Lines changed: 690 additions & 34 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Sections dated before 2026-09-19 predate the cycle and stay as they are. Named m
1919

2020
## Unreleased
2121

22+
- fix(doctor, exec, page-scope, rehost, wf-add-path-terminators, module-close): **mxcli v0.29 compatibility, and doctor advises the latest mxcli**: on v0.29.0 (which `--install` fetches by default) four instruments read new output wrong. (1) `fix property-sets` prints `MIXED` rows and exits 1: doctor reported "could not classify" (rc 4, shown as info by sync) — now result `mixed`, a WARN naming the rows and saying the repair cannot clear them; (2) the repair also exits 1 while a MIXED name remains, so `--fix-property-sets` rolled back a repair that had landed — the apply step now passes when only MIXED is left (FAILED still fails); (3) `fix hashes` now verifies MPR v1 with new text, which exec.sh read as an error, so every `--patch` on a Mendix < 10.18 project went unverified — both v1 forms are read; (4) since v0.28 `SHOW MODULES` / `list modules` write `Protected AddOn|Solution` in Source, so a first-party module set to Protected dropped out of page-scope (FAULT, 0 modules) and out of the rehost module list — the export level no longer counts as an origin. `wf-add-path-terminators.py` refuses below Mendix 10.21 (the terminator type does not exist there; written in, the project will not load), module-close notes that v0.29 `docker check` checks the stored project (a CE0463 it now reports is real), and the stale "stay on v0.24" pin advice is replaced. **New:** the normal doctor run compares the project mxcli with the latest release (redirect of the asset URL, 5 s, nothing downloaded): WARN with release link and upgrade path when behind, a note when `MXCLI_VERSION` pins it, one quiet note offline, never a FAIL; `MXTK_NO_LATEST_CHECK=1` skips it. Golden input captured from the real v0.28.0/v0.29.0 binaries on the mxpatch fixture model and mutated copies (CAPTURE files); against master the new cases fail (exec-hash-verify 4, property-sets 7, mxpatch 1, page-scope-protected 3, rehost-list-modules 1, doctor-mxcli-latest 8). Field run: page-scope and doctor against real v0.29.0/v0.28.0 binaries in a cloud session — mxcli v0.29 audit (2026-10-30)
2223
- fix(doctor, sync-project, speed-setup): **doctor says when the speed fixes never reached a project**: `bin/exec.sh`, `bin/_common.sh` or `bin/lint-gate.sh` without the 2026-10-29 speed code (marker per file) gives a Machine health warning "speed fixes not active", and the Recommended fix leads with the exact `sync-project.sh --upgrade-bin ...` command (exec.sh always with its `_common.sh`; each copy backed up) before any other advice, because every other number measures the old scripts; `sync-project.sh` names the speed fixes on a hand-edited exec.sh / _common.sh that has the exit-code fix but not the speed work; `skills/speed-setup.md` has Claude show each local edit in one line and ask before replacing. Field: an English colleague's ExpenseTracker analysis after the toolkit update still showed a full mxbuild on every change (45.5 min, 57% of all exec time) with 15 drifted scripts in bin/; reproduced here with the real pre-#587 exec.sh / _common.sh / lint-gate.sh — doctor names all three, sync names exec.sh and refreshes the two unedited ones — Maurits (mauritscgvisser)
2324
- fix(doctor, speed-setup): **doctor no longer says "None needed" next to a verdict of "5x slower"**: when process starts are fast but one bench step is 5x+ the reference and 2 s+ slower, the Recommended fix names that step (slow git status: `git config core.untrackedCache true` / `core.fsmonitor true`, no admin rights); a project inside a OneDrive / Dropbox / Google Drive / iCloud folder gets a Machine health warning and "move the project to a local folder" as the fix; low-memory advice now offers "restart the computer" before `--cleanup`; the bench's git step runs one untimed warm-up so a stale index after a copy or clone no longer reads as slow (field, ab-581/gk: 18.3 s cold, 31 ms warm); `skills/speed-setup.md` tells Claude never to say deno, mxbuild or helper process to a user. Field run: ab-581/gk on Linux, bench 14.7 s vs 10.9 s, "None needed" correctly; a project under a OneDrive path, move advice shown — Maurits (mauritscgvisser)
2425
- fix(gate-check, gate-cache): **the closeout verdict cache also keys on file CONTENT, so an overwrite that keeps an old mtime (`cp -p`, `rsync -t`, `tar x`, `unzip`, `touch -d`) can no longer replay a stale verdict**: a signed triage.md copied over a FAIL one still printed the cached Stage 0 FAIL (PR #589 review); the cache now stores one `find | sort | xargs cksum | cksum` signature of the project files (skipping .git, node_modules, .mxtk, mprcontents, deployment, *.mpr, files over 1 MB) and any difference, or a signature that cannot be computed, re-evaluates; new `tests/wave2/test-gate-cache.sh` (hit, edit/delete/waiver miss, cp -p miss, TTL 0, 'not evaluated' line); `MXTK_GATE_CACHE_TRACE=1` prints `gate-cache: hit|miss` on --closeout. Field run: ab-581/base copy (197 MB, 633 hashed files) - signature 28 ms, cache hit 1464 -> 1498 ms vs 2567-2786 ms full evaluation - PR #589 reviewer, OlafFede (#583) — OlafFede (#583)

‎bin/doctor.sh‎

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,18 @@ set -u
8383
# script and the repair inherits exec.sh's snapshot, mxbuild gate and restore.
8484
if [ "${2:-}" = "--property-sets-apply-step" ]; then
8585
{ [ -n "${3:-}" ] && [ -x "$3" ]; } || { echo "--property-sets-apply-step: no runnable mxcli given" >&2; exit 2; }
86-
exec "$3" fix property-sets -p "$1"
86+
# mxcli v0.29.0+ also exits 1 while a MIXED name remains (cmd_fix_property_sets.go: "Exits 1
87+
# when a unit could not be repaired, when a MIXED name remains"), even when every repair it made
88+
# landed. mxcli leaves MIXED units untouched, so that exit is not a failed repair: report 0 and
89+
# let the gate decide, else exec.sh --patch rolls the good repairs back. FAILED still exits 1.
90+
_psa_o="$("$3" fix property-sets -p "$1" 2>&1)"; _psa_r=$?
91+
printf '%s\n' "$_psa_o"
92+
if [ "$_psa_r" -eq 1 ] && printf '%s\n' "$_psa_o" | grep -q '^ MIXED ' \
93+
&& ! printf '%s\n' "$_psa_o" | grep -qE '^ FAILED |could not be normalized'; then
94+
echo "(exit 1 was for the MIXED name(s) above only — mxcli leaves those as they are; the repair stands)"
95+
exit 0
96+
fi
97+
exit "$_psa_r"
8798
fi
8899

89100
TOOLKIT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
@@ -201,6 +212,10 @@ probe_runs() {
201212
# What the dry-run prints and how it exits is mxcli's cmd/mxcli/cmd_fix_property_sets.go at
202213
# v0.26.0: exit 0 = nothing to do; exit 1 = a ` NEEDS ` or ` FAILED ` row per unit, OR an
203214
# error such as "project not found" (both exit 1, so the rows decide, never the code alone).
215+
# v0.29.0 adds ` MIXED ` rows (ako/mxcli#1505): a property name some elements of a type carry and
216+
# others lack — Mendix's merge engine cannot compare those revisions, and mxcli leaves them alone
217+
# (no measured value fills them). Exit 1 with only MIXED rows is result "mixed": a merge hazard
218+
# the repair cannot clear, reported, never "could not classify" (captured 2026-10-30).
204219
# Anything else is "could not classify", never clean. Support is read from `mxcli fix --help`
205220
# listing the subcommand: `mxcli fix property-sets --help` exits 0 on v0.24/v0.25 too (cobra
206221
# prints the parent's help for an unknown subcommand), so it cannot be the probe. Golden
@@ -209,7 +224,7 @@ probe_runs() {
209224
# The result is recorded in <project>/.claude/.property-sets-receipt (machine-local, like the
210225
# doctor receipt): line 1 "<date> <time> <result> <detail>", line 2 "mxcli: <--version line>".
211226
# Line 2 is what --if-stale and --quick compare: the check is owed again when mxcli changes.
212-
# Only a settled answer is recorded — clean, unproven, needs, failed, or unsupported (the support probe
227+
# Only a settled answer is recorded — clean, unproven, needs, failed, mixed, or unsupported (the support probe
213228
# ran and the subcommand is absent). An error or a timeout is never written, and --if-stale
214229
# skips the run only on a recorded clean/unproven/unsupported, so a one-off failure (locked model,
215230
# unreadable version, a probe that crashed) is re-checked on the next sync instead of being
@@ -250,19 +265,23 @@ ps_bounded() {
250265
rm -f "$_pb_f"
251266
return "$_pb_rc"
252267
}
253-
# ps_classify <exit> <output> — sets PS_RESULT (clean|needs|failed|error) and PS_DETAIL.
268+
# ps_classify <exit> <output> — sets PS_RESULT (clean|needs|failed|mixed|error) and PS_DETAIL.
254269
ps_classify() {
255270
_psc_checked="$(printf '%s\n' "$2" | grep -m1 -E '^Checked [0-9]+ unit' || true)"
256271
_psc_needs="$(printf '%s\n' "$2" | grep -c '^ NEEDS ' || true)"
257272
_psc_failed="$(printf '%s\n' "$2" | grep -c '^ FAILED ' || true)"
273+
_psc_mixed="$(printf '%s\n' "$2" | grep -c '^ MIXED ' || true)"
274+
_psc_mx=""; [ "$_psc_mixed" -gt 0 ] && _psc_mx=", $_psc_mixed MIXED property name(s) mxcli leaves alone"
258275
if [ "$1" -eq 0 ] && printf '%s\n' "$2" | grep -q 'no readable Mendix version'; then
259276
PS_RESULT=error; PS_DETAIL="mxcli read no Mendix version from the model, so nothing was checked"
260277
elif [ "$1" -eq 0 ]; then
261278
PS_RESULT=clean; PS_DETAIL="${_psc_checked:-exit 0}"
262279
elif [ "$1" -eq 1 ] && [ "$_psc_needs" -gt 0 ]; then
263-
PS_RESULT=needs; PS_DETAIL="$_psc_needs unit(s) need their property set completed, $_psc_failed cannot be normalized"
280+
PS_RESULT=needs; PS_DETAIL="$_psc_needs unit(s) need their property set completed, $_psc_failed cannot be normalized$_psc_mx"
264281
elif [ "$1" -eq 1 ] && [ "$_psc_failed" -gt 0 ]; then
265-
PS_RESULT=failed; PS_DETAIL="$_psc_failed unit(s) hold a value in a key this Mendix version does not declare"
282+
PS_RESULT=failed; PS_DETAIL="$_psc_failed unit(s) hold a value in a key this Mendix version does not declare$_psc_mx"
283+
elif [ "$1" -eq 1 ] && [ "$_psc_mixed" -gt 0 ]; then
284+
PS_RESULT=mixed; PS_DETAIL="$_psc_mixed property name(s) differ between elements of one type (MIXED) — no measured value fills them"
266285
else
267286
PS_RESULT=error
268287
PS_DETAIL="exit $1: $(printf '%s\n' "$2" | grep -v -e '^[[:space:]]*$' -e '^WARNING: This is a' | head -1)"
@@ -289,7 +308,7 @@ ps_unproven_warn() {
289308
note "the proof is Mendix's own: mx diff <base>.mpr <mine>.mpr out.json with this version's mx; exit 0 is clean."
290309
}
291310
ps_write_receipt() {
292-
case "$PS_RESULT" in clean|unproven|needs|failed|unsupported) ;; *) return 0 ;; esac
311+
case "$PS_RESULT" in clean|unproven|needs|failed|mixed|unsupported) ;; *) return 0 ;; esac
293312
[ -n "$PS_VER" ] || return 0
294313
[ -n "$PROJECT_DIR" ] && [ -d "$PROJECT_DIR" ] || return 0
295314
mkdir -p "$PROJECT_DIR/.claude" 2>/dev/null || return 0
@@ -341,14 +360,16 @@ ps_check() {
341360
else
342361
ok "property sets: $PS_DETAIL — every unit has the property names Studio Pro writes"
343362
fi ;;
344-
needs|failed)
363+
needs|failed|mixed)
345364
warn "property sets: $PS_DETAIL — Studio Pro's merge/diff can throw on these"
346-
printf '%s\n' "$PS_OUT" | grep -E '^ (NEEDS|FAILED) ' | head -10 | while IFS= read -r l; do note "$l"; done
347-
_psk_rows="$(printf '%s\n' "$PS_OUT" | grep -cE '^ (NEEDS|FAILED) ' || true)"
365+
printf '%s\n' "$PS_OUT" | grep -E '^ (NEEDS|FAILED|MIXED) ' | head -10 | while IFS= read -r l; do note "$l"; done
366+
_psk_rows="$(printf '%s\n' "$PS_OUT" | grep -cE '^ (NEEDS|FAILED|MIXED) ' || true)"
348367
[ "$_psk_rows" -gt 10 ] && note " … $((_psk_rows - 10)) more"
349368
[ "$PS_RESULT" = needs ] && note "repair (snapshot + mxbuild gate + restore): bin/doctor.sh --fix-property-sets ${PROJECT_DIR:-<project>}"
350369
[ "$(printf '%s\n' "$PS_OUT" | grep -c '^ FAILED ' || true)" -gt 0 ] && \
351-
note "FAILED units are left alone by mxcli and make the guarded repair roll back — resolve them first." ;;
370+
note "FAILED units are left alone by mxcli and make the guarded repair roll back — resolve them first."
371+
[ "$(printf '%s\n' "$PS_OUT" | grep -c '^ MIXED ' || true)" -gt 0 ] && \
372+
note "MIXED names are left alone by mxcli and --fix-property-sets cannot clear them. Report them with your Mendix version (mendixlabs/mxcli asks for exactly that); until a value is measured, a merge touching these units can throw." ;;
352373
*) warn "property sets: could not classify the check — $PS_DETAIL (not recorded; the next run re-checks)"
353374
printf '%s\n' "$PS_OUT" | grep -v '^[[:space:]]*$' | head -5 | while IFS= read -r l; do note " $l"; done ;;
354375
esac
@@ -375,7 +396,7 @@ ps_apply() {
375396
ps_check
376397
}
377398
ps_exit_code() {
378-
case "$PS_RESULT" in clean|unproven) echo 0 ;; not-run) echo 2 ;; unsupported) echo 3 ;; needs|failed) echo 1 ;; *) echo 4 ;; esac
399+
case "$PS_RESULT" in clean|unproven) echo 0 ;; not-run) echo 2 ;; unsupported) echo 3 ;; needs|failed|mixed) echo 1 ;; *) echo 4 ;; esac
379400
}
380401

381402
# --property-sets / --fix-property-sets: only this check, then exit. Stands alone so
@@ -409,7 +430,7 @@ if [ -n "$PS_MODE" ]; then
409430
PS_VER="$(ps_version "$PMXCLI_PROBE")"
410431
if [ -n "$PS_VER" ] && ! ps_stale; then
411432
PS_RESULT="$(sed -n '1s/^[^ ]* [^ ]* \([^ ]*\).*/\1/p' "$(ps_receipt)")"
412-
# Only a settled "nothing to do here" short-circuits; needs/failed re-check every time.
433+
# Only a settled "nothing to do here" short-circuits; needs/failed/mixed re-check every time.
413434
case "$PS_RESULT" in
414435
clean|unsupported)
415436
ok "already checked for $PS_VER: $(sed -n 1p "$(ps_receipt)")"
@@ -425,6 +446,52 @@ if [ -n "$PS_MODE" ]; then
425446
exit "$(ps_exit_code)"
426447
fi
427448

449+
# mxcli_latest_advice <version line> — installed vs the latest mxcli release. Advice only: never a
450+
# FAIL, never blocks, never downloads. A pin ($MXCLI_VERSION) is respected — noted, not nagged.
451+
# Latest is read from the redirect of releases/latest/download/<asset> (one request, not followed,
452+
# 5 s cap); offline or no curl is one quiet note. MXTK_MXCLI_LATEST=vX.Y.Z supplies the
453+
# answer without the network (fixtures, air-gapped machines); MXTK_NO_LATEST_CHECK=1 skips it.
454+
# MXTK_MXCLI_FLOOR is the oldest release this toolkit's instruments are checked against.
455+
MXTK_MXCLI_FLOOR="${MXTK_MXCLI_FLOOR:-v0.28.0}"
456+
mxtk_semver_lt() { # <a> <b> — 0 when vA.B.C < vX.Y.Z; 1 otherwise or unparseable
457+
printf '%s %s\n' "${1#v}" "${2#v}" | awk '{
458+
n = split($1, a, "."); m = split($2, b, ".")
459+
if (n < 3 || m < 3) exit 1
460+
for (i = 1; i <= 3; i++) { if (a[i] + 0 < b[i] + 0) exit 0; if (a[i] + 0 > b[i] + 0) exit 1 }
461+
exit 1 }'
462+
}
463+
mxcli_latest_advice() {
464+
[ "${MXTK_NO_LATEST_CHECK:-0}" = 1 ] && return 0
465+
_ml_have="$(printf '%s\n' "$1" | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | head -1)"
466+
[ -n "$_ml_have" ] || return 0
467+
_ml_new="${MXTK_MXCLI_LATEST:-}"
468+
if [ -z "$_ml_new" ] && command -v curl >/dev/null 2>&1; then
469+
# The redirect of the asset URL --install itself uses (not followed: nothing is downloaded).
470+
# Not releases/latest: a proxy that allows release downloads can refuse that page (403,
471+
# measured in a cloud sandbox 2026-10-30, where this redirect answered v0.29.0).
472+
_ml_new="$(curl -sS --max-time 5 -o /dev/null -w '%{redirect_url}' \
473+
https://github.com/mendixlabs/mxcli/releases/latest/download/mxcli-linux-amd64 2>/dev/null \
474+
| sed -n 's|.*/releases/download/\(v[0-9][0-9.]*\)/.*|\1|p')"
475+
fi
476+
if [ -z "$_ml_new" ]; then
477+
note "latest mxcli release: not checked (offline, or no curl) — installed $_ml_have"
478+
return 0
479+
fi
480+
if ! mxtk_semver_lt "$_ml_have" "$_ml_new"; then
481+
ok "mxcli $_ml_have is the latest release"
482+
elif [ -n "${MXCLI_VERSION:-}" ]; then
483+
note "mxcli pinned by MXCLI_VERSION=$MXCLI_VERSION; latest is $_ml_new — move when the team chooses"
484+
else
485+
warn "mxcli $_ml_have is behind the latest release $_ml_new (advice only — nothing is blocked)"
486+
note "what's new: https://github.com/mendixlabs/mxcli/releases/tag/$_ml_new"
487+
note "upgrade: move the old binary aside (mv mxcli mxcli.$_ml_have), then bin/doctor.sh --install ${PROJECT_DIR:-<project>}"
488+
note "to stay on $_ml_have deliberately: set MXCLI_VERSION=$_ml_have and this becomes a note"
489+
fi
490+
mxtk_semver_lt "$_ml_have" "$MXTK_MXCLI_FLOOR" && \
491+
note "this toolkit's instruments are checked against $MXTK_MXCLI_FLOOR and later; $_ml_have output may not parse"
492+
return 0
493+
}
494+
428495
# recommended_fix — ONE block that ends both the normal run and --bench: the first option that works on THIS
429496
# machine, in this order. Read-only, cheap probes; never installs anything and never asks for IT's help.
430497
# 0. MH_STALE (machine_health): the project runs older local copies of the speed scripts -> upgrade them
@@ -1333,10 +1400,10 @@ if [ "$INSTALL" -eq 1 ]; then
13331400
# 2026-08-31): mxcli-{darwin|linux}-{amd64|arm64}, mxcli-windows-amd64.exe. Windows gets
13341401
# the .exe name so Git Bash's transparent foo -> foo.exe mapping serves the project
13351402
# convention ./mxcli unchanged. $MXCLI_VERSION pins a release tag (e.g. v0.16.0) for
1336-
# teams that standardise; default is latest. v0.25.0 froze `mdl 1`: DESCRIBE output and
1337-
# `-c` input changed shape (navigation, DynamicClasses, `show entity` refused). The
1338-
# toolkit's instruments read both shapes, so a project mid-build may stay on its version
1339-
# (MXCLI_VERSION=v0.24.0) and move when it chooses.
1403+
# teams that standardise; default is latest. The toolkit's instruments are checked against
1404+
# $MXTK_MXCLI_FLOOR (v0.28.0) through v0.29.0 (golden captures, 2026-10-30); a project
1405+
# mid-build may stay on its version (MXCLI_VERSION=<its ./mxcli --version>) and move when
1406+
# it chooses. The normal doctor run says when the installed mxcli is behind the latest.
13401407
# Git Bash on Windows ARM64 runs emulated, so `uname -m` says x86_64 there. On Windows the
13411408
# real hardware shows in the `uname -s` suffix (...-ARM64) and in PROCESSOR_ARCHITEW6432
13421409
# (set for emulated processes) / PROCESSOR_ARCHITECTURE; those win over `uname -m`.
@@ -1395,7 +1462,7 @@ if [ "$INSTALL" -eq 1 ]; then
13951462
note " $_STEP. mxcli (~90 MB) -> $PROJECT_DIR/$MXCLI_DEST"
13961463
note " the MDL CLI every session here uses; from $MXCLI_URL"
13971464
[ -z "${MXCLI_VERSION:-}" ] && note " (latest release — set MXCLI_VERSION=vX.Y.Z to pin the team's version;"
1398-
[ -z "${MXCLI_VERSION:-}" ] && note " a project already building on v0.24 can stay there: MXCLI_VERSION=v0.24.0)"
1465+
[ -z "${MXCLI_VERSION:-}" ] && note " a project mid-build can stay on its version: MXCLI_VERSION=<its ./mxcli --version>)"
13991466
fi
14001467
if [ "$NEED_TOOLCHAIN" -eq 1 ]; then
14011468
_STEP=$((_STEP + 1))
@@ -1855,6 +1922,7 @@ if [ -n "$PROJECT_DIR" ]; then
18551922
if [ "$MXCLI_EXIT" -eq 0 ]; then
18561923
ok "mxcli runs ($PROBE_HOW): $(probe_line)"
18571924
note "at: $PMXCLI_PROBE"
1925+
[ "$QUICK" != 1 ] && mxcli_latest_advice "$(probe_line)"
18581926
else
18591927
bad "mxcli exists but cannot run (exit $MXCLI_EXIT): $PMXCLI_PROBE"
18601928
printf '%s\n' "$PROBE_OUT" | grep -v '^[[:space:]]*$' | head -3 | while IFS= read -r l; do note " $l"; done

‎bin/sync-project.sh‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,8 +1699,13 @@ if [ "$WIRED" -eq 1 ] && [ -x "$SCRIPT_DIR/doctor.sh" ] \
16991699
3) echo " (the project's mxcli predates 'fix property-sets', v0.26.0 — upgrade it before a Team Server merge)" ;;
17001700
4) _ps_why="$(printf '%s\n' "$_ps_out" | sed -n 's/^ WARN property sets: //p' | head -1)"
17011701
echo " could not check property sets: ${_ps_why:-see above} — not recorded; the next sync re-checks" ;;
1702-
1) warn "property sets: Studio Pro's merge/diff can throw on this model (see above). Repair, gated:" \
1703-
"bin/doctor.sh --fix-property-sets '$PROJECT_DIR'" ;;
1702+
1) if printf '%s\n' "$_ps_out" | grep -q ' NEEDS '; then
1703+
warn "property sets: Studio Pro's merge/diff can throw on this model (see above). Repair, gated:" \
1704+
"bin/doctor.sh --fix-property-sets '$PROJECT_DIR'"
1705+
else # only FAILED / MIXED rows (mxcli v0.29+): nothing the guarded repair can clear
1706+
warn "property sets: Studio Pro's merge/diff can throw on this model (see above)." \
1707+
"--fix-property-sets cannot clear these rows; doctor's notes above say what can"
1708+
fi ;;
17041709
*) echo " property-set check exited $_ps_rc — see above" ;;
17051710
esac
17061711
fi

0 commit comments

Comments
 (0)