@@ -19,6 +19,12 @@ while [ "$check_dir" != "/" ]; do
1919done
2020[ -z " $DEVSTACK_DIR " ] && DEVSTACK_DIR=" $PWD "
2121
22+ # If we can't find devstack, do a local-only validation
23+ NOT_IN_DEVSTACK=false
24+ if [ ! -f " $DEVSTACK_DIR /VERSION" ] || [ ! -f " $DEVSTACK_DIR /lpb.stack.env" ]; then
25+ NOT_IN_DEVSTACK=true
26+ fi
27+
2228ERRORS=0
2329CURRENT_VERSION=$( cat " $DEVSTACK_DIR /VERSION" 2> /dev/null || echo " NOT FOUND" )
2430
@@ -38,14 +44,20 @@ error() { echo " ❌ $*"; ERRORS=$((ERRORS + 1)); }
3844
3945# 1. Validate VERSION file format (devstack only)
4046echo " === Stack Version ==="
41- if echo " $CURRENT_VERSION " | grep -qE ' ^0\.[0-9]+\.[0-9]+-lpb$ ' ; then
42- info " VERSION= $CURRENT_VERSION (valid )"
47+ if [ " $NOT_IN_DEVSTACK " = true ] ; then
48+ info " (running outside devstack — skipping version check )"
4349else
44- error " VERSION='$CURRENT_VERSION ' does not match 0.x.y-lpb format"
50+ if echo " $CURRENT_VERSION " | grep -qE ' ^0\.[0-9]+\.[0-9]+-lpb$' ; then
51+ info " VERSION=$CURRENT_VERSION (valid)"
52+ else
53+ error " VERSION='$CURRENT_VERSION ' does not match 0.x.y-lpb format"
54+ fi
4555fi
4656echo " "
4757echo " === Environment Sync ==="
48- if [ -f " $DEVSTACK_DIR /lpb.stack.env" ]; then
58+ if [ " $NOT_IN_DEVSTACK " = true ]; then
59+ info " (skipped — not in devstack)"
60+ elif [ -f " $DEVSTACK_DIR /lpb.stack.env" ]; then
4961 PI_REF=$( grep ' ^LPB_PI_REF=' " $DEVSTACK_DIR /lpb.stack.env" | cut -d= -f2)
5062 if [ " $PI_REF " != " $CURRENT_VERSION " ]; then
5163 error " lpb.stack.env: LPB_PI_REF=$PI_REF (expected $CURRENT_VERSION )"
5870# 3. Validate settings.json pins
5971echo " "
6072echo " === Extension Pins ==="
61- if [ -f " $SETTINGS_JSON " ]; then
73+ if [ " $NOT_IN_DEVSTACK " = true ]; then
74+ info " (skipped — not in devstack)"
75+ elif [ -f " $SETTINGS_JSON " ]; then
6276 for repo in lemonade-pi-plugin lpb-memory pi-subagents; do
6377 if python3 -c "
6478import json, sys
88102# 4. Check repo cleanliness
89103echo " "
90104echo " === Clean State ==="
91- check_unstaged () {
92- local repo_path=" $1 "
93- local repo_name=" $2 "
94- [ -d " $repo_path " ] || return 0
95- local dirty
96- dirty=$( cd " $repo_path " && git diff --name-only 2> /dev/null | grep -vE ' ^$' | grep -vE ' VERSION|lpb\.stack\.env|lpb\.conf\.env|\.githooks/' | grep -c . || true)
97- [ " $dirty " -gt 0 ] && error " $repo_name : $dirty unstaged change(s)" || info " $repo_name : clean"
98- }
105+ if [ " $NOT_IN_DEVSTACK " = true ]; then
106+ info " (skipped — not in devstack)"
107+ else
108+ check_unstaged () {
109+ local repo_path=" $1 "
110+ local repo_name=" $2 "
111+ [ -d " $repo_path " ] || return 0
112+ local dirty
113+ dirty=$( cd " $repo_path " && git diff --name-only 2> /dev/null | grep -vE ' ^$' | grep -vE ' VERSION|lpb\.stack\.env|lpb\.conf\.env|\.githooks/' | grep -c . || true)
114+ [ " $dirty " -gt 0 ] && error " $repo_name : $dirty unstaged change(s)" || info " $repo_name : clean"
115+ }
99116
100- for repo in " ${REPOS[@]} " ; do
101- check_unstaged " $repo " " $( basename " $repo " ) "
102- done
117+ for repo in " ${REPOS[@]} " ; do
118+ check_unstaged " $repo " " $( basename " $repo " ) "
119+ done
103120
104- check_unstaged " $DEVSTACK_DIR " " devstack"
121+ check_unstaged " $DEVSTACK_DIR " " devstack"
122+ fi
105123
106124# Result
107125echo " "
0 commit comments