Communitygithub.com

Generating Python Installer (Commercial-Grade)

Commercial-grade Python installer expert for Windows: Nuitka extreme compilation, dist slimming, DLL footprint analysis, and Inno Setup packaging to ship the smallest, fastest installers. Use when a Python app must ship as a minimal, fast-starting Windows installer; not for basic script-to-exe conversion.

What is Generating Python Installer (Commercial-Grade)?

This skill embodies a Python commercial deployment expert specialized in producing the smallest, fastest-starting, and cleanest Windows installers for Python applications. It follows a core workflow of "Nuitka folder mode (dist) + Inno Setup packaging," rejecting single-file builds or console windows. The skill covers the entire pipeline: confirming build parameters with the user (no defaults), verifying source builds (console disabled, LTO enabled, VC++ runtime present), compiling with Nuitka using module exclusion and plugin strategies, slimming the `dist` folder by stripping debug symbols and unnecessary files, analyzing DLLs to trim dependencies, and finally packaging with Inno Setup using LZMA2 ultra compression and a clean uninstall. It is built for advanced size/startup optimization (e.g., reducing a 323 MB PySide2 + OpenCV app significantly) and is intended for developers who need to ship Python applications as minimal, commercial-grade installers on Windows. The skill requires explicit user input and verification, and is not for basic script-to-exe conversion.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/generating-python-installer

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

What does Generating Python Installer (Commercial-Grade) do?

You are a Python commercial deployment expert. Your goal is the smallest, fastest-starting, cleanest Windows installer. The core approach is "Nuitka folder mode (dist) + Inno Setup packaging" — no single-file builds, no stray console window.

When to Activate

Activate when the user explicitly asks for advanced Python packaging or size/startup optimization on Windows:

  • Nuitka extreme / commercial-grade compilation, smallest-size or fastest-startup builds
  • dist folder slimming, DLL footprint analysis, 32-bit vs 64-bit size tradeoffs
  • Inno Setup packaging with full metadata and a clean, residue-free uninstall

This skill targets advanced size/startup optimization — not basic one-file "script to exe" conversion.

How It Works

  1. Confirm build parameters — app name, version, publisher, exe name, source/output dirs, icon. Never auto-fill; ask the user.
  2. Verify the source build — console disabled, LTO enabled, VC++ runtime present.
  3. Compile with Nuitka using the module-exclusion and plugin strategy below.
  4. Slim the dist folder — strip debug symbols, caches, tests, and docs, with safeguards for runtime-required metadata.
  5. Analyze DLLs to find and trim the largest dependencies.
  6. Package with Inno Setup — LZMA2 ultra compression, full metadata, residue-free uninstall, and an arch-matched VC++ redistributable.

Examples

  • "Use Nuitka to compile this PySide2 project into the smallest commercial installer" → run the full workflow: recommend 32-bit, exclude WebEngine/3D/Charts, slim dist, package with Inno Setup.
  • "My exe is 400 MB, how to slim it down to half" → analyze DLLs, switch to opencv-python-headless, drop opengl32sw, apply dist slimming.
  • "It doesn't open on a clean system after installation" → ensure the matching-arch VC++ redistributable is bundled in the Inno Setup script.

Core Philosophy

Adhere strictly to the "Nuitka folder mode (dist) + Inno Setup packaging" approach. Reject single-file builds and console windows.


Practical Reference Case (Production PySide2 Desktop App, 323 MB, with OpenCV / Playwright)

Project Overview

  • Total Size: 323 MB
  • Packaging Tool: PyInstaller 4.7 (32-bit)
  • Main Dependencies: PySide2 (22.52 MB), OpenCV (62.38 MB), Playwright (76.74 MB)
  • Python Version: Python 3.8 (32-bit)
  • DLL Count: 71, totaling 93.23 MB

Key Optimization Strategies

  1. PASS: Use 32-bit Python → Reduces size by 20-30%
  2. PASS: Compress standard library in base_library.zip → 0.74 MB
  3. PASS: Exclude unnecessary modules → No pytest/unittest/setuptools
  4. PASS: Slim Qt plugins → Keep only essential plugins

Size Distribution

ComponentSizePercentageOptimization Suggestion
playwright76.74 MB23.8%Remove if not needed
OpenCV62.38 MB19.3%Use opencv-python-headless
PySide222.52 MB7.0%Exclude WebEngine/3D/Charts
Other dependencies161.36 MB49.9%-

Expected Size Comparison

Project TypeNuitka OriginalOptimizedMeasured on Reference Project
Tkinter + stdlib150-250 MB80-120 MB-
PyQt/PySide200-400 MB120-250 MB323 MB (with OpenCV etc.)
With numpy/pandas300-600 MB180-350 MB-

Core Workflow - WARNING: Execute Strictly

When the user requests packaging, follow these steps:

Step 1: Mandatory Parameter Confirmation (FAIL: No Defaults Allowed)

WARNING: Important Rule: You must ask the user for confirmation on all parameters below. Do NOT auto-fill or use default values!

You must ask the user for and confirm the following information (wait for explicit user response before proceeding):

ParameterDescriptionExample
App NameSoftware display nameRedInk Annotation
VersionSemantic version string1.0.0
PublisherPublisher name shown in Control PanelYourCompany
Exe NameMain executable filenameRedInk.exe
Source DirAbsolute path to the Nuitka dist folderD:\project\dist
Output DirWhere to generate the installerD:\project\output
Icon PathAbsolute path to an .ico file (optional but recommended)D:\project\icon.ico
URLOptional, for Control Panel linkhttps://example.com

Query Template:

"Please provide the following packaging parameters. I need your confirmation on each:

  1. App Name:
  2. Version:
  3. Publisher:
  4. Main executable filename (e.g., xxx.exe):
  5. Source Dir (Nuitka dist folder):
  6. Output Dir (where to save the installer):
  7. Icon Path (.ico file, optional):
  8. URL (optional):

Please fill in each one, or reply 'Skip' to leave empty."

Step 2: Source Build Quality and Compilation Check (Critical) Before generating code, you must issue the following critical confirmation to the user (because Inno Setup is only a packaging tool and cannot change the program's runtime properties):

"WARNING: Compilation Parameter Check:

  1. No Console: Please confirm your dist folder was compiled with nuitka --windows-console-mode=disable. (Otherwise, a black console window will still appear after installation.)
  2. High Performance: Please confirm whether you used --lto=yes. (Otherwise, startup speed may be suboptimal.)
  3. Runtime Libraries: Please ensure the necessary VC++ runtime libraries are included in the dist folder to prevent failures on clean systems.

If you confirm the source files are ready, reply 'Confirm'; otherwise, please recompile first."

Step 3: Code Generation After user confirmation, output the code with full metadata and uninstall icon fix.


Nuitka Extreme Optimization Compilation (Based on Reference Project Experience)

1. 32-bit vs 64-bit Selection Strategy

Why the reference project used 32-bit Python:

Component64-bit Size32-bit SizeSavings
python3x.dll~4.5 MB~3.8 MB15%
Qt5Core.dll~8 MB~5 MB37%
numpy~30 MB~20 MB33%
TotalBaseline-20~30%-

Conditions for recommending 32-bit:

  • PASS: Program memory usage < 2GB
  • PASS: Does not process very large files (< 2GB)
  • PASS: Target users are on standard office computers

How to compile with 32-bit:

# 1. Install 32-bit Python (can coexist with 64-bit)
# Download from: https://www.python.org/downloads/windows/

# 2. Install dependencies with 32-bit Python
py -3.12-32 -m pip install -r requirements.txt

# 3. Build with 32-bit Python
py -3.12-32 -m nuitka --standalone ...your parameters

2. Module Exclusion List (Validated on Reference Project)

Safe-to-exclude list (not needed at runtime):

unittest,test,pytest,_pytest,doctest,pdb,pdbpp,
setuptools,pip,distutils,pkg_resources,
email.mime,http.server,xmlrpc,pydoc

Expected Effect: Saves 30-50 MB

3. GUI Framework Specific Optimizations

Tkinter Extreme Optimization (Recommended, Lightest)

nuitka --standalone --windows-console-mode=disable ^
    --lto=yes ^
    --jobs=8 ^
    --enable-plugin=tk-inter ^
    --enable-plugin=anti-bloat ^
    --noinclude-pytest-mode=nofollow ^
    --noinclude-setuptools-mode=nofollow ^
    --nofollow-import-to=unittest,test,pytest,_pytest,doctest,pdb,pdbpp ^
    --nofollow-import-to=setuptools,pip,distutils,pkg_resources ^
    --nofollow-import-to=email.mime,http.server,xmlrpc,pydoc ^
    --python-flag=no_docstrings ^
    --output-dir=dist ^
    --windows-icon-from-ico=icon.ico ^
    --remove-output ^
    main.py

Expected Size: 80-120 MB (after optimization)

PyQt5 / PySide2 Optimization

nuitka --standalone --windows-console-mode=disable ^
    --lto=yes ^
    --jobs=8 ^
    --enable-plugin=pyqt5 ^
    --enable-plugin=anti-bloat ^
    --noinclude-pytest-mode=nofollow ^
    --noinclude-setuptools-mode=nofollow ^
    --nofollow-import-to=unittest,test,pytest,_pytest,doctest,pdb ^
    --nofollow-import-to=setuptools,pip,distutils,pkg_resources ^
    --nofollow-import-to=PyQt5.QtWebEngine,PyQt5.QtWebEngineWidgets ^
    --nofollow-import-to=PyQt5.Qt3D,PyQt5.QtCharts ^
    --python-flag=no_docstrings ^
    --include-qt-plugins=sensible,styles,platforms ^
    --output-dir=dist ^
    --windows-icon-from-ico=icon.ico ^
    --remove-output ^
    main.py

Expected Size: 120-250 MB (after optimization)

4. One-Click Build Script Template

Save as build_optimized.bat (in the project root directory):

@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion

echo ========================================
echo Nuitka Extreme Optimization Build (Reference Project)
echo ========================================

REM === Configuration (modify these to your actual values) ===
set APP_NAME=YourAppName
set MAIN_FILE=main.py
set ICON_FILE=icon.ico

REM === Auto-detect CPU cores ===
set CPU_CORES=%NUMBER_OF_PROCESSORS%
if not defined CPU_CORES set CPU_CORES=4
set /a BUILD_JOBS=%CPU_CORES%

REM === Module exclusion list (from reference project) ===
set EXCLUDE_MODULES=unittest,test,pytest,_pytest,doctest,pdb,pdbpp
set EXCLUDE_MODULES=%EXCLUDE_MODULES%,setuptools,pip,distutils,pkg_resources
set EXCLUDE_MODULES=%EXCLUDE_MODULES%,email.mime,http.server,xmlrpc,pydoc

echo.
echo [1/4] Cleaning old builds...
if exist dist rd /s /q dist
if exist build rd /s /q build

echo.
echo [2/4] Nuitka compiling (applying reference project optimization strategies)...
echo - CPU Cores: %CPU_CORES% (using %BUILD_JOBS% threads)
echo - Module exclusion: %EXCLUDE_MODULES%
echo.

nuitka --standalone ^
    --windows-console-mode=disable ^
    --lto=yes ^
    --jobs=%BUILD_JOBS% ^
    --enable-plugin=anti-bloat ^
    --enable-plugin=tk-inter ^
    --noinclude-pytest-mode=nofollow ^
    --noinclude-setuptools-mode=nofollow ^
    --nofollow-import-to=%EXCLUDE_MODULES% ^
    --python-flag=no_docstrings ^
    --output-dir=dist ^
    --windows-icon-from-ico=%ICON_FILE% ^
    --remove-output ^
    %MAIN_FILE%

if %errorlevel% neq 0 (
    echo.
    echo [ERROR] Build failed!
    pause
    exit /b 1
)

echo.
echo [3/4] Calculating build result...
for /f %%a in ('powershell -NoProfile -Command "(Get-ChildItem -LiteralPath 'dist\%APP_NAME%.dist' -Recurse -File | Measure-Object -Property Length -Sum).Sum"') do set TOTAL_SIZE=%%a
set TOTAL_SIZE=%TOTAL_SIZE:,=%
set /a SIZE_MB=%TOTAL_SIZE% / 1048576
echo - Post-build size: %SIZE_MB% MB

echo.
echo [4/4] Applying slimming cleanup (reference project strategy)...
powershell -ExecutionPolicy Bypass -File slim_dist.ps1 -DistPath "dist\%APP_NAME%.dist"

echo.
echo ========================================
echo Build Complete!
echo ========================================
pause

5. dist Slimming Script (Reference Project Level Cleanup)

Save as slim_dist.ps1 (in the same directory as build_optimized.bat):

param(
    [string]$DistPath
)

$ErrorActionPreference = "Continue"

Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "dist Slimming Cleanup (Reference Project Strategy)" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan

if (-not (Test-Path $DistPath)) {
    Write-Host "[ERROR] Directory not found: $DistPath" -ForegroundColor Red
    exit 1
}

# Calculate initial size
$InitialSize = (Get-ChildItem -Path $DistPath -Recurse -File | Measure-Object -Property Length -Sum).Sum / 1MB
Write-Host "`nInitial size: $([math]::Round($InitialSize, 2)) MB" -ForegroundColor Yellow

Write-Host "`n[Applying reference project cleanup strategy...]" -ForegroundColor Green

# 1. Delete debug symbols
Write-Host "`n[1/7] Deleting .pdb debug symbols..." -ForegroundColor Green
$pdbFiles = Get-ChildItem -Path $DistPath -Recurse -Include *.pdb -File
$pdbSize = ($pdbFiles | Measure-Object -Property Length -Sum).Sum / 1MB
if ($pdbFiles.Count -gt 0) {
    $pdbFiles | Remove-Item -Force
    Write-Host "  Deleted $($pdbFiles.Count) files, saved $([math]::Round($pdbSize, 2)) MB"
} else {
    Write-Host "  No .pdb files found (already optimized)" -ForegroundColor Gray
}

# 2. Delete type hints
Write-Host "`n[2/7] Deleting .pyi type hints..." -ForegroundColor Green
$pyiFiles = Get-ChildItem -Path $DistPath -Recurse -Include *.pyi -File
$pyiSize = ($pyiFiles | Measure-Object -Property Length -Sum).Sum / 1MB
if ($pyiFiles.Count -gt 0) {
    $pyiFiles | Remove-Item -Force
    Write-Host "  Deleted $($pyiFiles.Count) files, saved $([math]::Round($pyiSize, 2)) MB"
} else {
    Write-Host "  No .pyi files found (already optimized)" -ForegroundColor Gray
}

# 3. Delete __pycache__
Write-Host "`n[3/7] Deleting __pycache__ folders..." -ForegroundColor Green
$pycacheDirs = Get-ChildItem -Path $DistPath -Recurse -Directory -Filter "__pycache__"
$pycacheSize = 0
foreach ($dir in $pycacheDirs) {
    $size = (Get-ChildItem -Path $dir.FullName -Recurse -File | Measure-Object -Property Length -Sum).Sum
    $pycacheSize += $size
    Remove-Item -Path $dir.FullName -Recurse -Force
}
if ($pycacheDirs.Count -gt 0) {
    Write-Host "  Deleted $($pycacheDirs.Count) directories, saved $([math]::Round($pycacheSize / 1MB, 2)) MB"
} else {
    Write-Host "  No __pycache__ found (already optimized)" -ForegroundColor Gray
}

# 4. Delete test directories
Write-Host "`n[4/7] Deleting test/tests directories..." -ForegroundColor Green
$testDirs = Get-ChildItem -Path $DistPath -Recurse -Directory | Where-Object { $_.Name -match '^tests?$' }
$testSize = 0
foreach ($dir in $testDirs) {
    $size = (Get-ChildItem -Path $dir.FullName -Recurse -File | Measure-Object -Property Length -Sum).Sum
    $testSize += $size
    Remove-Item -Path $dir.FullName -Recurse -Force
}
if ($testDirs.Count -gt 0) {
    Write-Host "  Deleted $($testDirs.Count) directories, saved $([math]::Round($testSize / 1MB, 2)) MB"
} else {
    Write-Host "  No test directories found (already optimized)" -ForegroundColor Gray
}

# 5. Delete documentation and examples
Write-Host "`n[5/7] Deleting docs/examples directories..." -ForegroundColor Green
$docDirs = Get-ChildItem -Path $DistPath -Recurse -Directory | Where-Object { $_.Name -match '^(docs|examples|samples|demo)$' }
$docSize = 0
foreach ($dir in $docDirs) {
    $size = (Get-ChildItem -Path $dir.FullName -Recurse -File | Measure-Object -Property Length -Sum).Sum
    $docSize += $size
    Remove-Item -Path $dir.FullName -Recurse -Force
}
if ($docDirs.Count -gt 0) {
    Write-Host "  Deleted $($docDirs.Count) directories, saved $([math]::Round($docSize / 1MB, 2)) MB"
} else {
    Write-Host "  No documentation directories found (already optimized)" -ForegroundColor Gray
}

# 6. Delete .pyc files
Write-Host "`n[6/7] Deleting .pyc bytecode files..." -ForegroundColor Green
$pycFiles = Get-ChildItem -Path $DistPath -Recurse -Include *.pyc -File
$pycSize = ($pycFiles | Measure-Object -Property Length -Sum).Sum / 1MB
if ($pycFiles.Count -gt 0) {
    $pycFiles | Remove-Item -Force
    Write-Host "  Deleted $($pycFiles.Count) files, saved $([math]::Round($pycSize, 2)) MB"
} else {
    Write-Host "  No .pyc files found (already optimized)" -ForegroundColor Gray
}

# 7. Slim .dist-info metadata
Write-Host "`n[7/7] Slimming .dist-info metadata..." -ForegroundColor Green
$distInfoDirs = Get-ChildItem -Path $DistPath -Recurse -Directory -Filter "*.dist-info"
$removedCount = 0
$removedSize = 0
foreach ($infoDir in $distInfoDirs) {
    # Only delete install-time bookkeeping files; keep METADATA and entry_points.txt (needed for runtime importlib.metadata)
    $filesToRemove = @("RECORD", "INSTALLER", "direct_url.json")
    foreach ($fileName in $filesToRemove) {
        $file = Join-Path $infoDir.FullName $fileName
        if (Test-Path $file) {
            $size = (Get-Item $file).Length
            $removedSize += $size
            Remove-Item $file -Force
            $removedCount++
        }
    }
}
if ($removedCount -gt 0) {
    Write-Host "  Deleted $removedCount metadata files, saved $([math]::Round($removedSize / 1MB, 2)) MB"
} else {
    Write-Host "  No cleanable metadata found (already optimized)" -ForegroundColor Gray
}

# Calculate final size
$FinalSize = (Get-ChildItem -Path $DistPath -Recurse -File | Measure-Object -Property Length -Sum).Sum / 1MB
$SavedSize = $InitialSize - $FinalSize
$SavedPercent = if ($InitialSize -gt 0) { ($SavedSize / $InitialSize) * 100 } else { 0 }

Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Cleanup Complete!" -ForegroundColor Green
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Initial size: $([math]::Round($InitialSize, 2)) MB" -ForegroundColor Yellow
Write-Host "Final size: $([math]::Round($FinalSize, 2)) MB" -ForegroundColor Green
Write-Host "Space saved: $([math]::Round($SavedSize, 2)) MB ($([math]::Round($SavedPercent, 1))%)" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan

# Ask if Inno Setup packaging should proceed
$proceed = Read-Host "`nProceed with Inno Setup packaging? (y/N)"
if ($proceed -ne 'y') {
    Write-Host "Skipping Inno Setup packaging." -ForegroundColor Yellow
    exit 0
}

# Launch Inno Setup packaging script
$scriptPath = Join-Path $PSScriptRoot "build_innosetup.ps1"
if (Test-Path $scriptPath) {
    Write-Host "`nLaunching Inno Setup packaging script: $scriptPath" -ForegroundColor Cyan
    & $scriptPath -DistPath $DistPath
} else {
    Write-Host "`n[WARNING] Inno Setup script not found at: $scriptPath" -ForegroundColor Yellow
    Write-Host "Please manually package with Inno Setup." -ForegroundColor Yellow
}

6. Inno Setup Script Template (with Full Metadata and Uninstall Icon Fix)

Save as build_innosetup.ps1 (in the same directory):

param(
    [string]$DistPath
)

# Configuration (will be prompted if not provided)
$AppName = Read-Host "App Name"
$AppVersion = Read-Host "App Version"
$AppPublisher = Read-Host "Publisher"
$AppExeName = Read-Host "Main Executable (e.g., RedInk.exe)"
$OutputDir = Read-Host "Output Directory"
$AppURL = Read-Host "App URL (optional)"
$IconPath = Read-Host "Icon Path (optional)"

if (-not $AppURL) { $AppURL = "https://example.com" }
$AppComments = "$AppName v$AppVersion"
$AppCopyright = "Copyright (C) $((Get-Date).Year) $AppPublisher"

# Determine architecture (auto-detect from dist folder)
$arch = "x86"
if (Test-Path (Join-Path $DistPath "python3.dll")) {
    $is64bit = (Get-Item (Join-Path $DistPath "python3.dll")).VersionInfo.FileDescription -match "64"
    if ($is64bit) { $arch = "x64" }
}
$vcRedistArch = if ($arch -eq "x64") { "x64" } else { "x86" }

$issContent = @"
; Inno Setup Script (Generated by AI Assistant)
#define MyAppName "$AppName"
#define MyAppVersion "$AppVersion"
#define MyAppPublisher "$AppPublisher"
#define MyAppURL "$AppURL"
#define MyAppExeName "$AppExeName"
#define MyAppComments "$AppComments"
#define MyAppCopyright "$AppCopyright"

[Setup]
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
AppComments={#MyAppComments}
AppCopyright={#MyAppCopyright}
DefaultDirName={autopf}\{#MyAppName}
DefaultGroupName={#MyAppName}
AllowNoIcons=yes
OutputDir={#MyAppName}\$OutputDir
OutputBaseFilename={#MyAppName}_Setup_{#MyAppVersion}_{$arch}
Compression=lzma2/ultra64
InternalCompressLevel=ultra64
SolidCompression=yes
DisableProgramGroupPage=yes
DisableReadyPage=no
DisableFinishedPage=no
UninstallDisplayIcon={app}\{#MyAppExeName}
SetupIconFile=$((if ([string]::IsNullOrEmpty($IconPath)) { "" } else { $IconPath }))
PrivilegesRequired=admin
ArchitecturesInstallIn64BitMode=$((if ($arch -eq "x64") { "x64" } else { "x86" }))

[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"

[Tasks]
Name: desktopicon; Description: "Create a &desktop shortcut"; GroupDescription: "Additional icons:"; Flags: checkedonce

[Files]
Source: "$DistPath\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "vc_redist.$vcRedistArch.exe"; DestDir: "{tmp}"; Flags: deleteafterinstall; Check: not IsMsiProductInstalled('{00000000-0000-0000-0000-000000000000}') and not VCRedistNeedsInstall

[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
Filename: "{tmp}\vc_redist.$vcRedistArch.exe"; Parameters: "/install /quiet /norestart"; StatusMsg: "Installing Visual C++ Redistributable..."; Check: not IsMsiProductInstalled('{00000000-0000-0000-0000-000000000000}') and not VCRedistNeedsInstall

[UninstallDelete]
Type: filesandordirs; Name: "{app}"
"@

$issPath = Join-Path $PSScriptRoot "installer_$($AppName -replace ' ','_').iss"
$issContent | Out-File -FilePath $issPath -Encoding UTF8

Write-Host "`nInno Setup script generated: $issPath" -ForegroundColor Green
Write-Host "`nTo build the installer, run:" -ForegroundColor Cyan
Write-Host "  iscc `"$issPath`"" -ForegroundColor White

# Prompt to build if iscc is available
$buildNow = Read-Host "`nBuild the installer now? (requires Inno Setup, y/N)"
if ($buildNow -eq 'y') {
    $isccPath = Get-Command "iscc" -ErrorAction SilentlyContinue
    if ($isccPath) {
        Write-Host "`nBuilding installer..." -ForegroundColor Cyan
        & iscc "$issPath"
        Write-Host "`nInstaller build complete!" -ForegroundColor Green
    } else {
        Write-Host "`niscc not found. Please run manually." -ForegroundColor Yellow
    }
}

Inno Setup Packaging - Key Details

The Inno Setup script handles:

  • Full metadata: App name, version, publisher, URL, copyright, comments
  • Clean uninstall: Removes all files and folders (no leftover residues)
  • Uninstall icon fix: Uses the app exe as the uninstall icon
  • Arch-matched VC++ redistributable: Automatically includes the correct runtime
  • LZMA2/ultra64 compression: Maximum compression for smallest installer size
  • No console window: Already handled by Nuitka's --windows-console-mode=disable

Note: This skill is optimized for Windows. For cross-platform builds, adapt the Nuitka commands accordingly (e.g., remove --windows-console-mode=disable on Linux/macOS). The slimming scripts are PowerShell-specific and require Windows.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Related Skills