From 048545a3fb916bccbcc2619855bfbcec0ef2d7d4 Mon Sep 17 00:00:00 2001
From: Claude
Date: Mon, 13 Apr 2026 05:11:01 +0000
Subject: [PATCH] =?UTF-8?q?docs:=20Gemini=20consult=20=E2=80=94=20build.sh?=
=?UTF-8?q?=20fragility=20+=20deployment=20pipeline?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
7 questions covering:
- Separating file copy from yarn compile
- React component validation before production
- ErrorBoundary for injected components
- Eliminating deployment drift
- Pre-commit hooks for PHP syntax
- Pre-compiled bundle viability
- BuiltByBit industry standards
---
.../gemini-build-pipeline-2026-04-13.md | 169 ++++++++++++++++++
1 file changed, 169 insertions(+)
create mode 100644 docs/consultations/gemini-build-pipeline-2026-04-13.md
diff --git a/docs/consultations/gemini-build-pipeline-2026-04-13.md b/docs/consultations/gemini-build-pipeline-2026-04-13.md
new file mode 100644
index 0000000..0e7cc40
--- /dev/null
+++ b/docs/consultations/gemini-build-pipeline-2026-04-13.md
@@ -0,0 +1,169 @@
+# Gemini Consultation: ModpackChecker Build Pipeline Fragility
+
+**Date:** April 13, 2026 (late night)
+**From:** Michael (The Wizard) + Claude (Chronicler #84 — The Meridian)
+**To:** Gemini (Architectural Partner)
+**Re:** build.sh is causing production incidents — we need a bulletproof deployment pipeline
+
+---
+
+## Hey Gemini! 👋
+
+It's very late and we just had a production incident. We're deploying ModpackChecker v1.1.0 on a live Pterodactyl panel and the new React widget caused the server info card to disappear entirely for users. We had to emergency-revert. The root cause is our build.sh doing too many things in one shot with no safety net. We need your help designing a bulletproof deployment pipeline before we try again.
+
+---
+
+## The Product
+
+ModpackChecker is a Blueprint extension for Pterodactyl Panel 1.12.2. It has:
+- **PHP backend** — Laravel artisan commands, API controllers, services
+- **Admin Blade view** — PHP/Blade template for the admin settings page
+- **React TSX frontend** — Two components:
+ - `ModpackVersionCard.tsx` — injected into the server console page
+ - `UpdateBadge.tsx` — injected into the dashboard server list
+
+Blueprint extensions install via `blueprint -install modpackchecker`, which copies files and then calls our `build.sh`.
+
+---
+
+## The Current build.sh (Full Source)
+
+```bash
+#!/bin/bash
+# Runs during blueprint -install from Pterodactyl root
+
+# 1. Detect Node version, set NODE_OPTIONS for Node 17+
+NODE_MAJOR_VERSION=$(node -v | grep -oE '[0-9]+' | head -1)
+if [ "$NODE_MAJOR_VERSION" -ge 17 ]; then
+ export NODE_OPTIONS=--openssl-legacy-provider
+fi
+
+# 2. Copy wrapper.tsx → ModpackVersionCard.tsx
+EXT_DIR=".blueprint/extensions/modpackchecker"
+cp "$EXT_DIR/views/server/wrapper.tsx" resources/scripts/components/server/ModpackVersionCard.tsx
+
+# 3. Inject import + component into AfterInformation.tsx (only if not already there)
+AFTER_INFO="resources/scripts/blueprint/components/Server/Terminal/AfterInformation.tsx"
+if ! grep -q "ModpackVersionCard" "$AFTER_INFO"; then
+ sed -i '/\/* blueprint\/import \*\//a import ModpackVersionCard from "@/components/server/ModpackVersionCard";' "$AFTER_INFO"
+ sed -i 's|{/\* blueprint/react \*/}|{/* blueprint/react */}\n |' "$AFTER_INFO"
+fi
+
+# 4. Copy UpdateBadge.tsx + inject into ServerRow.tsx
+cp "$EXT_DIR/views/dashboard/UpdateBadge.tsx" resources/scripts/components/dashboard/UpdateBadge.tsx
+if ! grep -q "UpdateBadge" resources/scripts/components/dashboard/ServerRow.tsx; then
+ sed -i '1i import UpdateBadge from "@/components/dashboard/UpdateBadge";' resources/scripts/components/dashboard/ServerRow.tsx
+ sed -i 's|{server.name}
|{server.name}|' resources/scripts/components/dashboard/ServerRow.tsx
+fi
+
+# 5. Copy PHP files (services, controllers, commands)
+cp "$EXT_DIR/app/Services/LicenseService.php" app/Services/
+cp "$EXT_DIR/app/Services/ModpackApiService.php" app/Services/
+cp "$EXT_DIR/app/Console/Commands/CheckModpackUpdates.php" app/Console/Commands/
+cp "$EXT_DIR/app/Console/Commands/ValidateLicense.php" app/Console/Commands/
+cp "$EXT_DIR/app/Http/Controllers/ModpackAPIController.php" app/Http/Controllers/
+
+# 6. Overwrite Blueprint's auto-generated admin controller
+cp "$EXT_DIR/admin/controller.php" "app/Http/Controllers/Admin/Extensions/modpackchecker/modpackcheckerExtensionController.php"
+
+# 7. Clear caches
+php artisan optimize:clear
+
+# 8. yarn build:production (2-5 minutes)
+yarn build:production
+```
+
+---
+
+## What Happened Tonight
+
+We shipped v1.1.0 with a redesigned React widget. During deployment:
+
+1. We ran `blueprint -install modpackchecker` — SUCCESS, copied the new TSX
+2. We then manually re-ran `bash build.sh` to ensure the PHP files were copied
+3. Step 2 **overwrote** `ModpackVersionCard.tsx` with the new widget correctly
+4. `yarn build:production` compiled successfully
+5. BUT: the compiled bundle caused the server info card to disappear entirely
+
+The new widget rendered nothing (or threw a silent React error that unmounted the whole card). We emergency-reverted to the old widget by writing the old TSX directly and rebuilding yarn.
+
+**The result:** We now have v1.1.0 backend deployed (new DB columns, new endpoints, better detection) but v1.0.0 frontend widget still in production. The product is half-upgraded.
+
+---
+
+## The Problems
+
+### Problem 1: No Staging / Safety Check
+The build runs directly on the production panel. There's no way to verify the compiled output renders correctly before it goes live. The only test is "does the panel explode."
+
+### Problem 2: Build.sh Does Too Many Things
+It copies files AND injects into Pterodactyl source AND compiles frontend in one atomic step. If anything goes wrong mid-way, the panel is in an inconsistent state.
+
+### Problem 3: Multiple Deployment Paths Create Drift
+We have two deployment patterns that fight each other:
+- `blueprint -install modpackchecker` (calls build.sh automatically)
+- Manual: copy individual PHP/TSX files + run yarn build separately
+
+When we mix these, files get overwritten at different points and the final state is unpredictable.
+
+### Problem 4: The `*/6` Docblock Keeps Coming Back
+Our PHP file `CheckModpackUpdates.php` has `*/6` in a docblock comment which PHP sometimes parses as end-of-comment + stray tokens. We've patched it THREE times on the server because build.sh keeps copying from a repo file that still has it (fixed in one copy, not the other).
+
+### Problem 5: No Rollback
+When the panel broke tonight, there was no "undo" — we had to manually reconstruct the previous TSX from memory and rebuild yarn. A 90-second compile to fix something that took 10 seconds to break.
+
+### Problem 6: Blueprint's Auto-Generated Controller Gets Overwritten
+Blueprint generates its own controller at `app/Http/Controllers/Admin/Extensions/modpackchecker/`. Our build.sh overwrites it with our version (which has LicenseService DI). But `blueprint -install` runs first and generates the file BEFORE our build.sh overwrites it — so the sequence is correct, but fragile. If Blueprint ever changes when it calls build.sh, we break.
+
+---
+
+## Our Constraints
+
+1. **We're selling this on BuiltByBit** — customers install via `blueprint -install modpackchecker`. We cannot require them to do complex post-install steps.
+2. **We cannot assume SSH access** on customer panels — some customers are on managed hosting.
+3. **Pterodactyl 1.12.2 + Blueprint beta-2026-01** — these are fixed targets.
+4. **yarn build:production takes 90 seconds to 3 minutes** — on every install, every update.
+5. **Node.js version varies** — we handle this with `--openssl-legacy-provider` for Node 17+.
+6. **We have one source of truth** (`firefrost-services` git repo) but multiple deployment surfaces (Dev Panel, Live Panel, customer panels).
+
+---
+
+## Specific Questions
+
+1. **How should we structure the build pipeline to separate "copy files" from "compile frontend"?**
+ Right now it's all in build.sh. Should there be a separate `install.sh` (file operations) and `compile.sh` (yarn build), called in sequence? How do other Blueprint extensions handle this?
+
+2. **Is there a way to validate a React component compiles without breaking the production bundle?**
+ Before we run `yarn build:production` on a live panel, can we do a dry-run or type-check that would catch errors? `tsc --noEmit` perhaps? Or a simple syntax check?
+
+3. **How should we handle the "new widget breaks the panel" failure mode?**
+ Tonight the new TSX caused the server card to disappear entirely with no console error we could see. React swallowed the error silently. Should we wrap our component in an `ErrorBoundary`? What's the right defensive pattern for injected Blueprint components?
+
+4. **What's the cleanest way to handle the multiple deployment paths (blueprint -install vs manual)?**
+ We need one canonical deploy procedure that works whether the Chronicler is deploying to a customer panel OR to our own panels during development. How do we eliminate the "drift" problem?
+
+5. **The `*/6` docblock problem** — is there a pre-commit hook or linting check that would catch PHP syntax errors like this before they reach the repo? We keep fixing it manually on the server.
+
+6. **Should we ship a pre-compiled JS bundle instead of requiring yarn build on the customer's panel?**
+ Gemini previously rejected this (it would overwrite Pterodactyl's `public/assets/main.js` and break other extensions). But is there a safe way to do it — like a separate bundle entry point that doesn't conflict with the main bundle? Or inject via a `