Run PlatformIO builds and automatically fix failures in a loop. Use when user says "fix build", "build loop", or wants automated build-fix iteration across platforms.
Automated loop: run PlatformIO builds, parse errors, fix them (directly or via Codex), re-run until clean.
/pre-build-fix-loop — build affected environments only (default)/pre-build-fix-loop --all — build all environments (esp32, esp8266, arduino-uno)/pre-build-fix-loop --env esp32 — build specific environment only/pre-build-fix-loop --with-tests — include pio test -e native in the loopUse INVOC_ID (${PPID}-${RANDOM}) for invocation-unique naming. This supports concurrent skill invocations within a session.
Get the literal value first:
INVOC_ID="${PPID}-${RANDOM}"; echo "INVOC_ID=$INVOC_ID"
Use that literal value in all subsequent file paths. The Read tool does not expand shell variables — use the numeric literal in Read paths. Fallback: if process model changes.
mktemp -dCleanup: Remove /tmp/pb-$INVOC_ID.log at the end (success or max iterations).
Default (affected only): Detect which environments need building based on changed files:
shared/lib/ touched → build all environments (shared libraries must compile everywhere)apps/<name>/ touched → build that app's environments only (from its platformio.ini)tools/dashboard/ touched → skip PlatformIO builds, run dashboard checks instead--all: Build all environments for all apps with changes.
--env <env>: Build only the specified environment.
For each app directory with changes, run from that app's directory:
cd /Users/keithmckenzie/Projects/rgbw-lighting/apps/<app-name> && pio run -e <env> > /tmp/pb-$INVOC_ID.log 2>&1; EC=$?; echo "Exit code: $EC"; head -80 /tmp/pb-$INVOC_ID.log; echo "..."; tail -80 /tmp/pb-$INVOC_ID.log
If --with-tests and tests exist:
cd /Users/keithmckenzie/Projects/rgbw-lighting/apps/<app-name> && pio test -e native > /tmp/pb-$INVOC_ID.log 2>&1; EC=$?; echo "Exit code: $EC"; head -80 /tmp/pb-$INVOC_ID.log; echo "..."; tail -80 /tmp/pb-$INVOC_ID.log
Read /tmp/pb-$INVOC_ID.log and categorize errors:
| Category | Pattern | Priority |
|---|---|---|
| Missing include | fatal error: No such file or directory | 1 (fix first) |
| Undeclared identifier | was not declared in this scope, use of undeclared identifier | 2 |
| Type error | cannot convert, no matching function, invalid conversion | 3 |
| Linker error | undefined reference to, multiple definition of | 4 |
| Warning-as-error | -Werror triggered warnings | 5 |
| Test failure | FAILED, assertion failed | 6 |
Process errors in priority order:
| Category | Error Count | Action |
|---|---|---|
| Missing include | Any | Fix directly — add #include, check lib_deps |
| Undeclared identifier | < 5 | Fix directly — add declarations, includes, forward declarations |
| Undeclared identifier | >= 5 | Route to codex-fix with FULL error output |
| Type error | < 3 | Fix directly — correct types, add casts, fix signatures |
| Type error | >= 3 | Route to codex-fix with FULL error output |
| Linker error | Any | Fix directly if obvious (missing source file, duplicate symbol). Route to codex-fix if unclear. |
| Warning-as-error | Any | Fix directly — the warning text explains the issue |
| Test failure | Any | Route to codex-fix — tests need more context than mechanical fixes |
When routing to codex-fix: Include the FULL error output in the fix brief. Frame as: "Fix the following build errors" with the raw compiler output.
Embedded-specific fix patterns:
PRIu32 not defined → add #include <inttypes.h>String class usage → replace with char[] + snprintf()#if __cplusplus >= 201703L guard or use C++11 alternative#ifdef ESP32 / #ifdef ESP8266 guardsAfter applying fixes, go back to Step 2.
Maximum 3 total iterations. Track iteration count.
Same-error detection: If the same errors persist after a fix attempt, stop early — do not burn another iteration on the same failures.
When building multiple environments:
--with-tests)This order catches issues early — ESP32 errors are usually the simplest, ESP8266/AVR reveal portability issues.
| Scenario | Action |
|---|---|
| App directory doesn't exist | Report error, skip to next app |
| platformio.ini missing | Report error, skip |
codex-fix fails | Report Codex failure. Attempt direct fix if error is understandable, otherwise ask user. |
| Same errors persist across iterations | Stop early. Report to user. |
| Environment not in platformio.ini | Report "Environment <env> not found in platformio.ini", stop |
| Build succeeds but with warnings | Report warnings but do not loop (exit 0 = success) |
Always clean up temp files when done:
rm -f /tmp/pb-$INVOC_ID.log