From eb5e1feb820673cc69d98cabd0607e7efd8ada6a Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Apr 2026 04:14:47 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20Gemini=20consult=20=E2=80=94=20ModpackC?= =?UTF-8?q?hecker=20UX=20overhaul,=2010=20questions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most detailed consult ever. Covers: - Seeding problem (all servers falsely show up_to_date) - Messy CurseForge version strings - Console widget UX redesign - Non-modpack server detection - Proactive notifications - Version history architecture - Multi-panel cloud opportunity - Monetization angles --- ...i-modpackchecker-ux-overhaul-2026-04-12.md | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 docs/consultations/gemini-modpackchecker-ux-overhaul-2026-04-12.md diff --git a/docs/consultations/gemini-modpackchecker-ux-overhaul-2026-04-12.md b/docs/consultations/gemini-modpackchecker-ux-overhaul-2026-04-12.md new file mode 100644 index 0000000..5fb2727 --- /dev/null +++ b/docs/consultations/gemini-modpackchecker-ux-overhaul-2026-04-12.md @@ -0,0 +1,290 @@ +# Gemini Consultation: ModpackChecker UX Overhaul — Console Widget, Version Detection & Future Architecture + +**Date:** April 12–13, 2026 (late night session) +**From:** Michael (The Wizard) + Claude (Chronicler #84 — The Meridian) +**To:** Gemini (Architectural Partner) +**Re:** ModpackChecker v1.0.0 is live but the UX isn't what we hoped — we need your wildest ideas for v1.1.0+ + +--- + +## Hey Gemini! 👋 + +Long night. We shipped ModpackChecker v1.0.0 to the live Pterodactyl panel tonight after an epic debugging marathon. The good news: it's installed, the background cron detects all 22 servers via the `modpack_installations` table, and the dashboard badges are compiling. The less good news: when Michael clicked the console widget button, it worked — but it didn't feel right. We want your help designing what "right" actually looks like, and we're explicitly asking for wild ideas. Nothing is off the table. + +We're 46 hours from soft launch on April 15, so some of this is v1.1.0+ thinking. But if something is quick to implement, we'll do it tonight. + +--- + +## The Product + +**ModpackChecker** is a commercial Blueprint extension for Pterodactyl Panel 1.12.2. It monitors Minecraft modpack servers for updates across 4 platforms: CurseForge, Modrinth, FTB, and Technic. It's being sold on BuiltByBit at $14.99 (Standard) and $24.99 (Professional). + +**The vision:** Panel admins with 10-50 Minecraft servers should never have to manually check if their modpacks are out of date. It should just... tell them. Automatically. Beautifully. + +**Our customers:** Minecraft hosting providers, server network owners, and serious hobbyists who run multiple servers. Michael is our first real customer — he runs 22 servers on his own Firefrost Gaming panel. + +--- + +## Current Architecture + +### Detection Pipeline (Background Cron) +`php artisan modpackchecker:check` runs on a cron schedule (daily or every 6/12 hours for Pro). Detection priority: + +1. **`modpack_installations` table** — Pterodactyl's own install records (provider + modpack_id). Works for ~60-70% of servers that were installed via the panel's modpack installer. +2. **Egg variables** — `MODPACK_PLATFORM` + `MODPACK_ID` in server startup variables. Works if the admin configured them manually. +3. **File detection** — `DaemonFileRepository` reads `manifest.json` (CurseForge) or `modrinth.index.json` (Modrinth) from `/home/container/`. In practice this rarely works because the modpack installer extracts files and discards the manifest. + +### Version Tracking +- **First run:** Seeds `current_version = latest_version` (assumes freshly installed = current) +- **Subsequent runs:** If CurseForge/Modrinth returns a newer `latest_version` than the stored `current_version`, status becomes `update_available` +- **Problem:** The seeding assumption is often wrong. Michael KNOWS some of his servers are behind, but since we seeded them as current tonight, they all show "up to date." + +### Database Schema (`modpackchecker_servers`) +```sql +server_uuid VARCHAR +platform VARCHAR (curseforge, modrinth, ftb, technic) +modpack_id VARCHAR +modpack_name VARCHAR +current_version VARCHAR (what we think the server is running) +latest_version VARCHAR (latest from the platform API) +status VARCHAR (up_to_date, update_available, unconfigured, error) +detection_method VARCHAR (installer, egg, file, manual) +is_user_overridden BOOLEAN +last_checked TIMESTAMP +error_message TEXT +``` + +### The Console Widget (Current State) +A React TSX component injected into Pterodactyl's server console page. Currently shows: +- **Idle:** "Click to check" +- **Loading:** "Checking..." +- **Success:** Shows `latest_version` string (e.g., "All the Mods 10-6.6") +- **Update available:** Orange background +- **Error:** Red text with error code + +**What it doesn't show:** Current version, comparison, when it was last checked, whether the cron has run yet, or any context about what the version string means. + +### The Dashboard Badge (Current State) +A small colored dot injected next to the server name on the panel dashboard: +- 🟠 Orange = update available +- 🟢 Green = up to date +- No dot = unconfigured or not yet checked + +**Works when yarn build compiles.** Currently blocked by Blueprint beta CSS module issue on some Node versions (v1.1.0 fix planned with `--openssl-legacy-provider`). + +--- + +## What "Worked But Not The Way We Hoped" Means + +When Michael clicked the console widget button on a server tonight, it showed him the latest version string — something like "All the Mods 10-6.6". That's technically correct. But here's what felt wrong: + +1. **It just shows a version string with no context.** "All the Mods 10-6.6" — is that good? Is that the latest? Is HIS server on that version? There's no comparison shown. + +2. **All 22 servers show "up to date" even though Michael knows some aren't.** This is the seeding problem: we set current_version = latest_version on first run, so everything looks current until CurseForge releases a newer version. + +3. **The UX requires clicking.** You have to click the widget button to trigger a live API check. Michael expected it to proactively show him the status without having to click. + +4. **Version strings from CurseForge are messy.** CurseForge's `displayName` field returns things like: + - "All the Mods 10-6.6" + - "Society - Capital Hill - 0.20.0" + - "All the Mons-0.18.0-beta" + - "Homestead-1.2.0.zip" + These are human-readable titles, not clean semantic versions. Comparing "ATM10-6.5" to "ATM10-6.6" is easy, but "Homestead-1.2.0.zip" vs "Homestead-1.3.0.zip" requires parsing. + +5. **The console widget is in the wrong place.** It's in the server console "right column" alongside CPU/memory/disk stats. But version checking isn't something you want while actively managing a running server. It feels misplaced. + +--- + +## Full Current Code + +### ModpackVersionCard.tsx (Console Widget) +```tsx +import React, { useState } from 'react'; +import { ServerContext } from '@/state/server'; +import http from '@/api/http'; +import { faCube } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import classNames from 'classnames'; + +interface VersionData { + success: boolean; + platform?: string; + modpack_id?: string; + modpack_name?: string; + current_version?: string; + latest_version?: string; + status?: string; + message?: string; + error?: string; +} + +const ModpackVersionCard: React.FC = () => { + const uuid = ServerContext.useStoreState((state) => state.server.data?.uuid); + const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle'); + const [data, setData] = useState(null); + + const checkForUpdates = async () => { + if (!uuid) return; + setStatus('loading'); + try { + const response = await http.post(`/api/client/extensions/modpackchecker/servers/${uuid}/check`); + setData(response.data); + setStatus(response.data.success ? 'success' : 'error'); + } catch (error: any) { + if (error.response?.status === 429) { + setData({ success: false, error: 'rate_limited' }); + } else if (error.response?.status === 404) { + setData({ success: false, error: 'not_found' }); + } else { + setData({ success: false, error: 'api_error' }); + } + setStatus('error'); + } + }; + + const getBgColor = () => { + if (status === 'success' && data?.status === 'update_available') return 'bg-orange-500'; + if (status === 'success' && data?.success) return 'bg-cyan-500'; + return 'bg-gray-700'; + }; + + return ( +
+ {/* ... renders latest_version string only ... */} +
+ ); +}; +``` + +### manualCheck() in ModpackAPIController.php +```php +public function manualCheck(Request $request, Server $server): JsonResponse +{ + // Rate limiting: 2/min per server + // Detection: egg vars → modpack_installations → file detection → cached DB + // Returns: success, platform, modpack_id, modpack_name, + // current_version (from DB cache), latest_version (from API), update_available +} +``` + +### CheckModpackUpdates.php (Cron) — Key Logic +```php +// Version seeding on first detection: +if (!$existing) { + // First time seeing this server — seed current = latest + $currentVersion = $versionData['version']; +} else { + // Preserve existing current_version + $currentVersion = $existing->current_version ?? $versionData['version']; +} + +$updateAvailable = $currentVersion !== $versionData['version']; +$status = $updateAvailable ? 'update_available' : 'up_to_date'; +``` + +--- + +## The Core Problems We Want to Solve + +### Problem 1: The Seeding Assumption +**"First run = current"** is almost always wrong for panels that have been running modpack servers for months before installing ModpackChecker. We need a way to know what version is ACTUALLY running on the server, not just assume it's the latest. + +### Problem 2: Messy Version Strings +CurseForge returns display names like "All the Mods 10-6.6" not semantic versions like "6.6.0". Comparing these is unreliable and the strings look ugly in the UI. + +### Problem 3: The Widget UX +The console widget shows a version string only after clicking. It should show more context — current vs latest, when last checked, the platform — proactively, not reactively. + +### Problem 4: "Not Configured" Servers +3 of 22 servers have no detection data at all (FoundryVTT, Hytale, Vanilla — obviously not modpack servers). But ModpackChecker doesn't know that. These just sit in `unconfigured` status forever and pollute the view. + +### Problem 5: Update Notifications +An update badge is good. But how does the admin KNOW they got an update? There's no notification — they have to visit the panel and see the orange dot. For a 22-server panel, that requires scanning the whole dashboard. + +--- + +## Specific Questions + +1. **Seeding problem — how do we know the actual current version?** + We have Wings access to the server filesystem. For CurseForge packs installed via the modpack installer, is there any file left behind that contains the installed version? We checked `manifest.json` — it's not there post-install. Is there a `minecraftinstance.json`? A `packinfo` file? Anything in the `config/` folder? What about reading from the server's startup command arguments? + +2. **Alternative version sources — what are we missing?** + We've tried: egg variables, manifest.json, modrinth.index.json, modpack_installations table. What other sources exist on a running Minecraft server that could tell us the installed modpack version? Think: server logs on startup, JVM arguments, mod metadata files, world data, Forge/NeoForge version files. Wild ideas welcome. + +3. **Semantic version extraction — best approach?** + Given messy version strings like "All the Mods 10-6.6", "Society - Capital Hill - 0.20.0", "Homestead-1.2.0.zip" — what's the most reliable regex or parsing strategy to extract a clean comparable version number? Should we normalize to semver? Store both the raw display name AND an extracted version number? + +4. **Widget redesign — what should it actually show?** + The current widget shows a version string on click. What would an ideal modpack status widget look like in the Pterodactyl server console? Should it: + - Load the cached DB status automatically (no click required)? + - Show current vs latest side by side? + - Show the platform logo/icon? + - Show time since last check? + - Have a "Force Check Now" button that bypasses cache? + We're redesigning this for v1.1.0 — no constraints, what's the ideal UX? + +5. **"Not a modpack" detection — how do we handle non-modpack servers?** + FoundryVTT and Hytale servers will never have modpack data. Right now they just show "unconfigured" forever. Should we: + - Show nothing for unconfigured servers (hide the widget entirely)? + - Let the admin mark a server as "not a modpack server" to dismiss it? + - Auto-detect server type from the egg name and skip non-Minecraft eggs? + - Something else? + +6. **Proactive notifications — what's the right channel?** + When an update is detected, how should we notify the admin? Options: + - Discord webhook (already planned for Pro tier) + - Email via Pterodactyl's mail config? + - In-panel notification (Pterodactyl has a notification system)? + - An "Update Digest" email showing all pending updates once a week? + - SMS via Twilio for critical servers? + What would you actually USE as a busy server admin? + +7. **The "known outdated" problem — how do we help admins with servers they know are behind?** + Michael knows several servers are running old versions. Right now the only way to fix the false "up to date" status is to manually edit `current_version` in the DB. For a BuiltByBit product, that's unacceptable. What's the right UX for an admin to say "this server is running version X"? + - Input field in the admin extension page? + - A "Recalibrate" button that triggers a fresh comparison? + - Accept a version number in the console widget directly? + +8. **Long-term architecture — should we store version history?** + Right now we only store current + latest. Should we log every detected version change? Benefits: admins could see "this pack was updated 3 times since I last looked." Costs: more DB storage, more complex queries. Is a `modpackchecker_version_history` table worth building? + +9. **Multi-panel support — wild idea or real opportunity?** + ModpackChecker currently only works on the panel it's installed on. But many hosting providers run multiple Pterodactyl panels. Could there be a "ModpackChecker Cloud" service — a central dashboard that aggregates update status from multiple panels? Is this a real product opportunity or scope creep? + +10. **Monetization angle — are there API opportunities we're missing?** + We're currently selling detection + monitoring. Are there adjacent features that would justify higher tiers or a subscription model? + - Automatic update execution (trigger a server update with one click)? + - Changelogs pulled from CurseForge/Modrinth and displayed in-panel? + - "Smart update" that checks if the new version breaks any custom configs? + - Integration with backup systems to auto-backup before updating? + +--- + +## Context That Might Help + +- **Pterodactyl Panel 1.12.2** — this is the specific version we target. Blueprint beta-2026-01 for extension framework. +- **Wings daemon** — gives us sandboxed filesystem access to `/home/container/` via `DaemonFileRepository`. Network calls to Wings are expensive — Gemini previously told us never do this on page load, only in background cron. +- **CurseForge API** — uses `x-api-key` header. Returns `displayName` (messy) and `dateModified`. No clean semver. +- **Modrinth API** — cleaner data, uses project slugs, returns semantic versions. +- **FTB API** — `https://api.modpacks.ch/public/modpack/{id}` — returns clean version numbers. +- **Technic API** — `https://api.technicpack.net/modpack/{slug}` — returns build numbers. +- **`modpack_installations` table** — this is actually from a DIFFERENT Blueprint extension ("Modpack Installer") that Michael already has installed. We're reading its data. We don't own this table. It could change between Pterodactyl versions or installer extension updates. +- **22 servers** — Michael's panel. About 19 are CurseForge, 0 currently Modrinth, 0 FTB (they show as CurseForge because FTB packs are also on CurseForge), 0 Technic. +- **BuiltByBit market** — our target customers are Minecraft hosting companies. The average customer probably has 10-100 servers. Some large hosts have 500+. +- **We cannot require egg changes** — this was Gemini's own guidance from the April 6 hybrid detection consultation. Egg changes require customer cooperation and break plug-and-play. +- **No real-time data** — the background cron is the only way to get data. The console widget triggers a live API call but only to the platform (CurseForge/Modrinth), not to the server itself. + +--- + +## What We're Hoping For + +Gemini, we want your best thinking on this. Not just incremental improvements — if you see a fundamentally different architecture that would make this product 10x better, tell us. Michael has been working on this for 6+ hours tonight and he's frustrated that it "worked but not the way he hoped." We want to end this session with a clear v1.1.0 vision that we're genuinely excited to build. + +Wild ideas are explicitly welcome. If you think we're solving the wrong problem entirely, tell us that too. + +--- + +Thanks Gemini! This one's a meaty one and we appreciate you. 🔥❄️ + +— Michael (The Wizard) + Claude (Chronicler #84 — The Meridian) +**Firefrost Gaming | Fire + Frost + Foundation = Where Love Builds Legacy** 💙🔥❄️