Overview
OddPack is an internal packaging tool for building and validating Intune Win32 app packages. The core flow is inspectable and repeatable: source upload, package preparation, worker validation, recipe reuse, and optional Intune publishing.
Single-page dark UI served by oddpack_controller.py. Home, package flow, process view, published apps, Intune auth, users, and admin issue panel.
Python HTTP controller. Owns uploads, job state, Intune Graph calls, worker orchestration, recipe catalog, issue storage, and diagnostics.
Windows VMs on ESXi. Jobs copy sources over SSH, run IntuneWinAppUtil, install, detect, uninstall, detect-gone, then clean or revert.
Architecture
Browser → https://oddpack.2tb.no → Nginx Proxy Manager → OddPack controller :8804
│
├─ state/oddpack_controller/jobs
├─ recipes/oddpack/verified
├─ Intune Graph / beta mobileApps
├─ Discord issue notification
└─ ESXi + Windows workers HLA-ODDPACK01/02Public uploads bypass Cloudflare proxy because Cloudflare Free limits request upload size. TLS is handled with Let's Encrypt on Nginx Proxy Manager.
Main job flow
MSI, EXE, Winget, Web shortcut, Driver ZIP, or Printer.
Local deterministic scanner identifies MSI/EXE/ZIP patterns and suggests install commands without touching a worker.
OddPack prepares source folder, wrappers, commands, and runs IntuneWinAppUtil on a worker.
Install → detect installed → uninstall → detect gone. Validation inventory includes HKCU and HKLM uninstall roots.
Successful packages can become verified good-to-go recipes.
User can publish new app or update/supersede only after green validation.
Packaging modes
Auto-detected. Uses MSI product metadata where possible. Best at registry/product-code detection.
Preflight recognizes NSIS, Inno, InstallShield, WiX Burn, Squirrel, Advanced Installer, MSI bootstrapper, and app hints like VLC/7-Zip. HKCU per-user apps like Bitwarden are supported.
Creates a wrapper around a winget package id/command and validates the result like a normal app.
Creates public desktop .url. Discovers manifest/favicon/apple-touch icons, converts PNG icons to ICO for Windows shortcut reliability, and supports fallback icon upload.
Deterministic ZIP/INF flow. Extracts safely, finds INF, generates pnputil install/uninstall scripts, detects by Published Name + Original Name, and uses clean snapshot rather than warm reuse.
Deterministic TCP/IP printer mapping. Defaults to Microsoft PCL6 Class Driver, creates Standard TCP/IP port, adds printer, validates name/port/driver, and removes unused port on uninstall.
Intune publish + supersedence
OddPack publishes Win32 apps through Microsoft Graph /deviceAppManagement/mobileApps. The endpoint name is Microsoft’s generic Intune app model; Win32 apps are #microsoft.graph.win32LobApp.
- Publish creates the app and uploads content, but does not change assignments.
- Update flow lets the user choose or paste an existing Intune app object GUID.
- Supersedence uses
POST /deviceAppManagement/mobileApps/<newAppId>/updateRelationships. - If listing/creating suddenly returns Forbidden/401, first logout/login Intune in OddPack before RBAC archaeology.
AI TRY diagnostics
AI TRY is a diagnostics workflow for failed packages. It clones a failed job, uses local job metadata and validation output, then creates a separate repair attempt for testing. AI TRY jobs are kept out of the published-app catalog and do not expose Intune publish actions.
Good-to-go recipes
Green validations can be promoted into reusable recipes: install command, detection, uninstall, detect-gone behavior, notes, and provenance. Verified catalog recipes win over stale saved EXE recipes so known-good logic is not overwritten by old guesses.
Issue reporting
Failed jobs expose a small report form for normal packagers: message + optional screenshot + Send issue. Admin/Super Admin users get an Issues panel with validation JSON, log tail, screenshot, and “Copy for Ms.Claw”. Discord notification goes to the OddPack channel.
Security and scope
This site documents architecture, services, package flows, operational runbooks, and design decisions.
Credentials, tokens, private keys, and tenant-sensitive values stay in local configuration and secret stores.
OddPack has local application login and separate time-limited Intune authentication for publishing operations.
Ops runbook
Controller
systemctl --user status msclaw-oddpack-controller.service systemctl --user restart msclaw-oddpack-controller.service python3 -m py_compile /home/joachim/.openclaw/workspace/tools/oddpack_controller.py
Docs
systemctl --user status msclaw-oddpack-docs.service systemctl --user restart msclaw-oddpack-docs.service curl -I http://127.0.0.1:8814/
Validation gate after code edits
python3 -m py_compile tools/oddpack_controller.py # extract inline JS to /tmp/oddpack-script.js node --check /tmp/oddpack-script.js systemctl --user restart msclaw-oddpack-controller.service
Important files and paths
tools/oddpack_controller.py— main OddPack app.tools/oddpack_docs.py— this read-only docs site.state/oddpack_controller/jobs/<id>/job.json— job state.recipes/oddpack/verified/<app>/recipe.json— verified recipes.state/oddpack_controller/issues/<issue>/issue.json— issue reports.secrets/...— local runtime credentials/configuration, intentionally outside the public documentation.
