How Hippopotamoose All In One is built — from top-level structure to core subsystems.
| Layer | Technology | Why |
|---|---|---|
| UI Framework | PyQt6 | Native Windows look, robust widget toolkit, QThread for non-blocking I/O |
| Language | Python 3.11+ | Rapid development, excellent library ecosystem |
| Browser Preview | PyQt6 QWebEngineView | Chromium-based, embedded in the UI |
| AI Delegation | Claude Code CLI / Gemini CLI | Spawned as child processes; handles long-running autonomous work outside the main process |
| Site Deployment | Cloudflare Pages + Wrangler CLI | Free tier, global CDN, custom domains, instant deploys |
| Site Downloads | Cyotek WebCopy | Handles auth, redirects, relative URL rewriting for offline viewing |
| Stock Photo Detection | Playwright + Chromium | Google Lens requires a real browser; Playwright automates it |
| Credential Storage | Windows Registry (winreg) | Secure OS-level storage, not exposed in filesystem |
| State Storage | Flat JSON files | Simple, portable, human-readable |
| Build/Packaging | PyInstaller + Inno Setup | Produces a self-contained Windows installer with all dependencies bundled |
main.py — Detects frozen (packaged) vs. source context, sets APP_DIR, initializes configuration, creates the QApplication with the global dark stylesheet, and shows the MainWindow.
main_window.py — A QMainWindow containing a vertical QSplitter. The top half holds a horizontal QSplitter with the Discovery Panel (left) and Swiper Panel (right). The bottom half is the Pipeline Panel. A toolbar at the top contains the Build from Scratch button, Add Existing Site button, and Settings gear.
core/)| Module | Role |
|---|---|
config.py | Frozen AppConfig dataclass. All filesystem paths derive from a single app_root. Singleton pattern — call init_config(app_root) once, then config() anywhere. |
signals.py | AppSignals singleton (QObject). Cross-module signal bus. Emits queue_updated, pipeline_added/updated/removed, data_reset. |
data_manager.py | Central state store. Owns pipeline, queue, and rejected lists in memory. Atomic write to disk. Crash-safe step recovery on startup. |
registry.py | Read/write Windows Registry under HKCU\Software\Hippopotamoose\AllInOne. Typed accessors for all keys. |
ai_launcher.py | Routes to claude_launcher or gemini_launcher based on USE_GEMINI_CLI registry flag. |
claude_launcher.py | Writes prompt to temp file, spawns PowerShell window with claude --dangerously-skip-permissions. Returns (process, ProcessMonitor). |
process_monitor.py | QThread. Calls proc.wait() and emits finished(exit_code) when the spawned process terminates. |
webcopy_queue.py | Bounded concurrency pool (max 3 concurrent WebCopy jobs). Two job types: pipeline (enqueue) and example (enqueue_example). |
webcopy_worker.py | QThread wrapping wcopy.exe. Parses stdout for progress. 5-minute hard timeout. |
deploy_worker.py | QThread running deploy-demo.ps1 hidden. 3-minute timeout. Returns demo URL on success. |
cold_call_worker.py | Silent Claude invocation to extract contact JSON from downloaded HTML files. |
backup_worker.py | QThread. Copies edited_sites/<slug> → Site Backups/<slug>/Edition N. |
discovery_worker.py | QThread. Calls Google Places API for each spiral tile. |
ui/)| Module | Role |
|---|---|
pipeline_row_widget.py | The core UI element. One row per lead. Contains step cells, action buttons, URL links, and note/folder/remove/delete controls. |
discovery_panel.py | Niche/coordinates/radius/chunks inputs. Preset management. Queue/Rejected list toggle. |
swiper_panel.py | QWebEngineView browser. Pass/Example/Copy buttons and keyboard shortcuts. Download progress display. |
settings_dialog.py | Full settings management: API keys, AI models, export/import, clear data. |
scratch_popup.py | Build from Scratch dialog. Both path A (existing folder) and path B (AI build). |
cold_call_popup.py | Scrollable contact list with per-row copy buttons. |
seo_window.py | SEO audit results in per-page card layout. |
note_popup.py | Free-text note editor per pipeline entry. |
toast.py | Non-modal auto-dismiss notification overlays, stacked bottom-right. |
The app uses PyQt6 signals to communicate between layers without tight coupling:
finished(bool, url)) on the thread they run inThe main thread runs the Qt event loop and all UI. Every blocking operation runs in a QThread worker:
AI work itself runs in separate spawned terminal windows, not in the app's process at all — this keeps the UI fully responsive during 10-minute AI builds.