ACCID Build Steps

Do all work in /ACCID_SOURCE/
ACCID_MANAGEMENT/accid_pre_scripts/sync_to_clean.sh
ACCID_MANAGEMENT/accid_pre_scripts/verify_build_folder.sh
Then:

Build Steps - UnifiedOlder VersionSteps Checklistbuild dmg / windows / linus

ACCID Build Process – FINAL

Prerequisites

On Windows:

  • Python 3.12 installed at: C:\Users\r-ai-\AppData\Local\Programs\Python\Python312\python.exe
  • PyInstaller (pip install pyinstaller)

On Mac (for syncing):

  • Windows PC mounted at: /Volumes/Users/Public/Documents/ACCID
  • Sync script: ~/sync_to_windows.sh

File Structure


ACCID.spec Configuration

This file is cross-platform (Mac, Windows, Linux):

# -*- mode: python ; coding: utf-8 -*-
import sys
from pathlib import Path

# Platform-specific icon
icon_file = None
if sys.platform == 'darwin':
    icon_file = 'AppIcon.icns' if Path('AppIcon.icns').exists() else None
elif sys.platform == 'win32':
    icon_file = 'AppIcon.ico' if Path('AppIcon.ico').exists() else None

a = Analysis(
    ['app.py'],
    pathex=[],
    binaries=[],
    datas=[
        ('templates', 'templates'),
        ('static', 'static'),
        ('accid_gallery_multi_project_source', 'accid_gallery_multi_project_source'),
        ('accid_html_project_source', 'accid_html_project_source'),
        ('accid_react_project_source', 'accid_react_project_source'),
        ('accid_tutorial_project_source', 'accid_tutorial_project_source'),
    ],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
    optimize=0,
)

pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='ACCID',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,  # Show console for debugging
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon=icon_file,
)

Key points:

  • console=True - Shows console window (set to False for production)
  • datas= - Bundles templates, static, and project source folders into exe
  • Platform-specific icon handling

app.py Structure

CRITICAL: Only startup code inside if __name__ == "__main__":

#!/usr/bin/env python3

# ============================================================================
# IMPORTS ONLY AT TOP
# ============================================================================
import sys
import os
import io
# ... all other imports ...

# NO PRINTS HERE
# NO PORT KILLING HERE
# NO STARTUP CODE HERE

# ============================================================================
# CONFIGURATION
# ============================================================================
PORT = int(os.getenv("PORT", "9847"))
CODE_ROOT = get_code_root()
DATA_ROOT = get_data_root()

# UTF-8 fix for Windows HTML processing (module level)
if sys.platform == 'win32' and not getattr(sys, 'frozen', False):
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
    sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')

# ============================================================================
# FASTAPI APP
# ============================================================================
app = FastAPI()
templates = Jinja2Templates(directory=str(CODE_ROOT / "templates"))
app.mount("/static", StaticFiles(directory=str(CODE_ROOT / "static")), name="static")

# ============================================================================
# ROUTES
# ============================================================================
@app.get("/")
async def home():
    # ...

# ============================================================================
# STARTUP - ONLY RUNS WHEN EXECUTED DIRECTLY
# ============================================================================
if __name__ == "__main__":
    import uvicorn
    import subprocess
    import threading
    import time
    import urllib.request

    # NO KILL FUNCTION - it kills itself on Windows

    def wait_for_server(port, timeout=10):
        start = time.time()
        while time.time() - start < timeout:
            try:
                urllib.request.urlopen(f'http://localhost:{port}/dashboard', timeout=1)
                return True
            except:
                time.sleep(0.2)
        return False

    def run_server():
        try:
            uvicorn.run(app, host="0.0.0.0", port=PORT, log_level="warning")
        except Exception as e:
            print(f"Server error: {e}")

    def run_validations():
        time.sleep(3)
        # ... validation code ...

    print()
    print("="*60)
    print("  ACCID - Automated Code Creation, Integration & Deployment")
    print("="*60)
    print()

    # NO EMOJI IN PRINTS (Windows console can't handle them)

    print("Loading projects...")
    load_existing_projects()

    print(f"Starting ACCID on http://localhost:{PORT}")

    server_thread = threading.Thread(target=run_server, daemon=True)
    server_thread.start()

    if wait_for_server(PORT):
        print("Server is ready!")

    webbrowser.open(f'http://localhost:{PORT}/')

    threading.Thread(target=run_validations, daemon=True).start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Shutting down...")
        sys.exit(0)

Critical rules:

  • ❌ NO module-level prints (they run on import)
  • ❌ NO emoji in backend code (Windows encoding issues)
  • ❌ NO kill_existing_accid() on Windows (kills itself)
  • ✅ ALL startup code inside if __name__ == "__main__":
  • ✅ UTF-8 wrapper at module level for HTML processing

Build Process

Step 1: Sync from Mac to Windows

On Mac:

~/sync_to_windows.sh

Sync script contents:

#!/bin/bash
rsync -avz --delete --size-only \
  --exclude '.venv' \
  --exclude '__pycache__' \
  --exclude '*.pyc' \
  --exclude '.DS_Store' \
  /Volumes/SpiffyMagic/ACCID_MANAGEMENT/ACCID_SOURCE/ \
  /Volumes/Users/Public/Documents/ACCID/
echo "Synced to Windows PC"

Step 2: Build on Windows

On Windows:

cd C:\Users\Public\Documents\ACCID
build_for_windows.bat

What happens:

  1. Removes old .venv
  2. Creates fresh Python 3.12 venv
  3. Installs dependencies from requirements.txt
  4. Runs pyinstaller ACCID.spec --clean --noconfirm
  5. Creates dist\ACCID.exe

Step 3: Test

DON'T test from dist/ folder!

Copy to desktop and test:

copy dist\ACCID.exe C:\Users\r-ai-\Desktop\ACCID.exe

Then double-click ACCID.exe from desktop.

What should happen:

  1. ✅ Console window opens
  2. ✅ Prints "ACCID - Automated..." header
  3. ✅ Loads projects
  4. ✅ Starts server on port 9847
  5. ✅ Opens browser to localhost:9847
  6. ✅ Site loads and works
  7. ✅ Can create new projects

How PyInstaller Works

Bundle Creation

pyinstaller ACCID.spec
  ↓
Creates dist\ACCID.exe containing:
  - Compiled Python code
  - All dependencies
  - templates/
  - static/
  - accid_*_project_source/ folders

Runtime Extraction

User double-clicks ACCID.exe
  ↓
Windows extracts to: C:\Users\USERNAME\AppData\Local\Temp\_MEIxxxxxx\
  ↓
Extracted contents:
  _MEIxxxxxx/
  ├── ACCID.exe (actual binary)
  ├── templates/
  ├── static/
  ├── accid_html_project_source/
  ├── accid_react_project_source/
  └── ... (all bundled files)
  ↓
CODE_ROOT = sys._MEIPASS (points to _MEIxxxxxx/)
  ↓
Templates loaded from: _MEIxxxxxx/templates/
Static files from: _MEIxxxxxx/static/
Project templates from: _MEIxxxxxx/accid_*_project_source/

User Data Storage

Separate from bundled files:

DATA_ROOT = C:\Users\USERNAME\AppData\Local\ACCID\
  ↓
Contains:
  ├── data/
  │   └── projects/
  ├── change_tracking/
  └── keys/

User projects, settings, and data go here - NOT in the exe.


Common Issues & Solutions

Issue: Emoji crash

UnicodeEncodeError: 'charmap' codec can't encode character

Solution: Remove all emoji from print statements in app.py


Issue: Templates not found

Template not found: C:\...\Temp\_MEIxxxxxx\templates

Solution: Add to ACCID.spec datas:

datas=[
    ('templates', 'templates'),
    # ...
],

Issue: Project creation fails - "Template not found"

Template not found: accid_html_project_source

Solution: Add project templates to ACCID.spec datas:

datas=[
    # ...
    ('accid_html_project_source', 'accid_html_project_source'),
],

Issue: Exe kills itself on startup

SUCCESS: The process "ACCID.exe" with PID xxxx has been terminated.

Solution: Comment out kill_existing_accid() function and its call on Windows


Issue: Testing from dist/ folder gives different results

Solution: Always copy to desktop and test from there - mimics real user behavior


Issue: rsync copies everything every time

Solution: Use --size-only flag:

rsync -avz --delete --size-only ...

Distribution

What Users Get

ACCID_Windows_v1.0.zip
└── ACCID.exe
└── README.txt (optional)

What Users Do

  1. Extract ZIP
  2. Double-click ACCID.exe
  3. Browser opens to localhost:9847
  4. Create projects

No Python installation required. No dependencies. Just works.


Troubleshooting

Check if server is running:

netstat -ano | findstr :9847

Kill stuck process:

taskkill /F /PID <PID>

View extracted files:

cd %TEMP%
dir _MEI*

Check Python version:

C:\Users\r-ai-\AppData\Local\Programs\Python\Python312\python.exe --version

Critical Don'ts

❌ Don't bundle user data folders (data/, keys/, change_tracking/)

❌ Don't use emoji in backend code

❌ Don't put startup code at module level

❌ Don't kill by process name on Windows (kills itself)

❌ Don't test from dist/ folder (paths differ)

❌ Don't sync .venv folders across platforms


Success Checklist

Before distribution, verify:

  • [ ] Exe builds without errors
  • [ ] Console shows startup messages
  • [ ] Browser opens automatically
  • [ ] Home page loads
  • [ ] Can view existing projects
  • [ ] Can create new HTML project
  • [ ] Can create new React project
  • [ ] Can create new Gallery project
  • [ ] Static files load (CSS/images)
  • [ ] Port 9847 is accessible
  • [ ] Exe has correct icon

This process is identical for Mac and Linux - just use their respective build scripts with the same ACCID.spec.

Build_for_dmg

#!/bin/bash
# ACCID Mac Build for DMG Distribution (one-file -> .app -> notarized DMG)
set -euo pipefail

APP_NAME="ACCID.app"
APP_BUNDLE_ID="accid.cloud"
APP_IDENTITY='Developer ID Application: Shawn Palmer (2SN54V9RU9)'

# set these in your env, or leave defaults here
: "${APPLE_ID:=apple@shawneee.com}"
: "${TEAM_ID:=2SN54V9RU9}"
: "${NOTARY_PWD:=oyvc-rpho-smkj-ekpb}"   # app-specific password (or use a notarytool keychain profile instead)

echo "🍎 ACCID mac build"

# fresh env
rm -rf .venv dist build "${APP_NAME}"
find . -name ".DS_Store" -delete
find . -name "._*" -delete

python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

echo "🔨 PyInstaller (using ACCID.spec, one-file)"
pyinstaller ACCID.spec --clean --noconfirm

# sanity: did we get the one-file binary?
[ -f dist/ACCID ] || { echo "❌ no dist/ACCID"; exit 1; }

echo "📦 making ${APP_NAME} bundle"
mkdir -p "$APP_NAME/Contents/MacOS" "$APP_NAME/Contents/Resources"

# put the one-file binary inside bundle as the real runtime (avoid copying xattrs)
cp -X dist/ACCID "$APP_NAME/Contents/MacOS/ACCID_bin"

# simple launcher that hands off to the runtime
cat > "$APP_NAME/Contents/MacOS/ACCID" <<'EOF'
#!/bin/zsh
LOG="/tmp/accid_launcher.log"
exec 2>"$LOG"
set -euo pipefail
DIR="$(cd -- "$(dirname -- "$0")" && pwd)"
exec "$DIR/ACCID_bin" "$@"
EOF
chmod +x "$APP_NAME/Contents/MacOS/ACCID"

# Info.plist — IMPORTANT: set floor to 11.0 (your wheels are macosx_11_0_arm64)
cat > "$APP_NAME/Contents/Info.plist" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>CFBundleExecutable</key><string>ACCID</string>
  <key>CFBundleName</key><string>ACCID</string>
  <key>CFBundleDisplayName</key><string>ACCID</string>
  <key>CFBundleIdentifier</key><string>${APP_BUNDLE_ID}</string>
  <key>CFBundleVersion</key><string>1.0.0</string>
  <key>CFBundleShortVersionString</key><string>1.0.0</string>
  <key>CFBundlePackageType</key><string>APPL</string>
  <key>LSMinimumSystemVersion</key><string>11.0</string>
  <key>NSHighResolutionCapable</key><true/>
  <key>CFBundleIconFile</key><string>AppIcon.icns</string>
</dict></plist>
EOF

# icon if present (avoid copying xattrs)
[ -f AppIcon.icns ] && cp -X AppIcon.icns "$APP_NAME/Contents/Resources/AppIcon.icns"

# --- scrub Finder junk/xattrs BEFORE codesigning (codesign fails if present) ---
find "$APP_NAME" -name ".DS_Store" -delete
xattr -rc "$APP_NAME"

# ---- critical entitlement so the one-file loader can load extracted Python ----
cat > entitlements.plist <<'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>com.apple.security.cs.disable-library-validation</key><true/>
</dict></plist>
PLIST

echo "🔏 signing loader (ACCID_bin) with hardened runtime + entitlement"
codesign --force --options runtime --timestamp \
  --entitlements entitlements.plist \
  --sign "$APP_IDENTITY" \
  "$APP_NAME/Contents/MacOS/ACCID_bin"

echo "🔏 signing bundle (deep, same entitlements)"
codesign --force --deep --options runtime --timestamp \
  --entitlements entitlements.plist \
  --sign "$APP_IDENTITY" \
  "$APP_NAME"

echo "🧪 verify local signatures"
codesign --verify --deep --strict --verbose=2 "$APP_NAME"
spctl --assess --type execute -vv "$APP_NAME" || true

# ---- notarize + staple the APP (so it stays trusted even outside the DMG) ----
echo "📝 notarizing the .app"
ditto -c -k --keepParent "$APP_NAME" ACCID.zip
xcrun notarytool submit ACCID.zip \
  --apple-id "$APPLE_ID" \
  --team-id "$TEAM_ID" \
  --password "$NOTARY_PWD" \
  --wait
xcrun stapler staple "$APP_NAME"
xcrun stapler validate "$APP_NAME"

# ---- create DMG, sign, notarize, staple ----
echo "💿 creating DMG"
hdiutil create -volname "ACCID" -srcfolder "$APP_NAME" -ov -format UDZO ACCID.dmg

echo "🔏 signing DMG"
codesign --force --timestamp --sign "$APP_IDENTITY" ACCID.dmg

echo "📝 notarizing DMG"
xcrun notarytool submit ACCID.dmg \
  --apple-id "$APPLE_ID" \
  --team-id "$TEAM_ID" \
  --password "$NOTARY_PWD" \
  --wait
xcrun stapler staple ACCID.dmg
xcrun stapler validate ACCID.dmg

echo "✅ done. ship ACCID.dmg. users drag ACCID.app to /Applications and run."
echo "   (do NOT run xattr -cr after signing; not needed and can invalidate signatures)"

Build_for_windows

r-ai-zr c:/Users/Public/Documents/ACCID

@echo off
REM ACCID Windows Build for Distribution
REM Location: ACCID_SOURCE/build_for_windows.bat
REM
REM This uses ACCID.spec which bundles templates/static INTO the executable
REM Creates a self-contained .exe

echo Building ACCID for Windows Distribution
echo ==========================================

REM Clean old builds
echo Cleaning old builds...
if exist "dist\" rmdir /s /q dist
if exist "build\" rmdir /s /q build

REM Remove old venv if exists
if exist ".venv\" (
    rmdir /s /q .venv
    echo Removing old venv
)

REM remove .DS_store mac junk
del /s /q /a .DS_Store 2>nul
del /s /q /a ._* 2>nul

REM Create new venv
"C:\Users\r-ai-\AppData\Local\Programs\Python\Python312\python.exe" -m venv .venv
call .venv\Scripts\activate.bat

REM Install dependencies
pip install -r requirements.txt

REM Build with PyInstaller using ACCID.spec
echo Running PyInstaller with ACCID.spec...
echo    (This bundles templates/ and static/ into the executable)
pyinstaller ACCID.spec --clean --noconfirm

REM Verify build
if not exist "dist\ACCID.exe" (
    echo Build failed - executable not found!
    pause
    exit /b 1
)

echo.
echo ========================================
echo BUILD COMPLETE!
echo ========================================
echo.
echo Self-contained executable: dist\ACCID.exe
echo.
echo TO TEST:
echo    dist\ACCID.exe
echo.
echo TO DISTRIBUTE:
echo    1. Test locally first
echo    2. Create ZIP: Compress dist\ACCID.exe
echo    3. Optional: Use Inno Setup or similar for installer
echo.
pause

build_for_linux.sh

#!/bin/bash
# ACCID Linux Build for Distribution
# Location: ACCID_SOURCE/build_for_linux.sh
#
# This uses ACCID.spec which bundles templates/static INTO the executable
# Creates a self-contained binary

set -e

echo "🐧 Building ACCID for Linux Distribution"
echo "=========================================="

# If old venv - remove
if [ -d ".venv" ]; then
    rm -rf .venv
    echo "📦 Removing Venv"
fi

# Clean old builds
echo "🧹 Cleaning old builds..."
rm -rf dist/ build/
find . -name ".DS_Store" -delete
find . -name "._*" -delete

# Create new venv
python3.12 -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Build with PyInstaller using ACCID.spec
echo "🔨 Running PyInstaller with ACCID.spec..."
echo "   (This bundles templates/ and static/ into the executable)"
pyinstaller ACCID.spec --clean --noconfirm

# Verify build
if [ ! -f "dist/ACCID" ]; then
    echo "❌ Build failed - executable not found!"
    exit 1
fi

# Make executable
chmod +x dist/ACCID

echo ""
echo "✅ BUILD COMPLETE!"
echo "===================="
echo ""
echo "📦 Self-contained executable: dist/ACCID"
echo ""
echo "🧪 TO TEST:"
echo "   ./dist/ACCID"
echo ""
echo "📦 TO DISTRIBUTE:"
echo "   1. Test locally first"
echo "   2. Create archive: tar -czf ACCID_Linux.tar.gz -C dist ACCID"
echo "   3. Optional: Create .deb or .rpm package"
echo ""

ACCID Build System - Unified Approach

All platforms now use the same simple build system.

Prerequisites

  1. Clean ACCID folder with:

    • app.py (with sys._MEIPASS path fix)
    • requirements.txt (with pyinstaller>=6.15.0)
    • ACCID.spec
    • templates/
    • static/
    • AppIcon.icns (Mac)
    • AppIcon.ico (Windows)
    • AppIcon.png (Linux)

How It Works

Each platform:

  1. Creates fresh venv
  2. Installs dependencies from requirements.txt
  3. Calls PyInstaller with ACCID.spec
  4. Creates onefile executable (everything bundled)
  5. Outputs to dist/

No wrapper scripts, no build_executable.py, no confusion.

Build Commands

Mac

cd /path/to/ACCID
./build_for_dmg.sh

Output: ACCID.app (self-contained Mac application)

Windows

cd C:\path\to\ACCID
build_for_windows.bat

Output: dist\ACCID.exe (self-contained Windows executable)

Linux

cd /path/to/ACCID
./build_for_linux.sh

Output: dist/ACCID (self-contained Linux binary)

What Gets Bundled

  • Python runtime
  • All dependencies from requirements.txt
  • templates/ folder
  • static/ folder
  • Platform-specific icon

Users get a single executable that "just works" - no Python installation needed.

Testing

Mac

open ACCID.app
# OR
./ACCID.app/Contents/MacOS/ACCID

Windows

dist\ACCID.exe

Linux

./dist/ACCID

All should:

  1. Start server on port 9847
  2. Auto-open browser to localhost:9847
  3. Create data in ~/Library/Application Support/ACCID (Mac) or equivalent

Distribution

Mac

  1. Sign: codesign --deep --force --sign "Developer ID Application: Your Name" ACCID.app
  2. Create DMG: hdiutil create -volname ACCID -srcfolder ACCID.app -ov -format UDZO ACCID.dmg
  3. Notarize & staple

EXTRA MAC STEPS

  1. /Volumes/SpiffyMagic/ACCID_MANAGEMENT/accid_pre_scripts/4a_sign_scripts_also_dmg_mac.sh

  2. Sign the .app: Only sign the final cleaned .app bundle.

  3. Build your DMG: Package only the .app and any minimal docs/readme.\

    1. # Create a DMG
      hdiutil create -volname "ACCID" -srcfolder _Mac_User_START_HERE.app -ov -format UDZO ACCID_Mac.dmg
      
      # Sign the DMG too
      codesign --sign "Developer ID Application: Your Name" ACCID_Mac.dmg
      
      # Notarize the DMG
      xcrun notarytool submit ACCID_Mac.dmg ...
      
      # Staple to DMG
      xcrun stapler staple ACCID_Mac.dmg
      
  4. Notarize/Distribute.

  • Mac users get DMG/APP
  • Windows users get ZIP/Installer
  • Linux users get tar.gz (or optional .deb/.rpm)

Windows

  1. Create ZIP: Compress dist\ACCID.exe
  2. Optional: Create installer with Inno Setup

Linux

  1. Create archive: tar -czf ACCID_Linux.tar.gz -C dist ACCID
  2. Optional: Create .deb or .rpm

Troubleshooting

"pyinstaller: command not found"

  • Make sure requirements.txt includes pyinstaller>=6.15.0

"Failed to load Python shared library"

  • You're using onedir instead of onefile
  • Check ACCID.spec has all a.binaries and a.datas in EXE()

"Directory '/static' does not exist"

  • app.py needs sys._MEIPASS path fix
  • Check that get_code_root() returns Path(sys._MEIPASS) when frozen

File Sizes (Approximate)

  • Mac: 179 MB (compressed onefile)
  • Windows: ~150-200 MB (onefile)
  • Linux: ~150-200 MB (onefile)

All include full Python runtime + dependencies.


Last Updated: November 2025
Status: Mac tested and working ✅
Next: Test Windows and Linux builds

ACCID Build Checklist

Use this when building fresh executables for distribution.

Pre-Build Checklist

  • Clean ACCID folder synced from ACCID_SOURCE

  • requirements.txt includes pyinstaller>=6.15.0

  • app.py has sys._MEIPASS path fix in get_code_root()

  • ACCID.spec present

  • Icons present (AppIcon.icns, AppIcon.ico, AppIcon.png)

  • templates/ and static/ folders present

Mac Build

  • Run: ./build_for_dmg.sh

  • Test: Double-click ACCID.app

  • Verify: Browser opens to localhost:9847

  • Test: Copy to /Applications and run again

  • Sign: codesign --deep --force --sign "Developer ID" ACCID.app

  • DMG: hdiutil create -volname ACCID -srcfolder ACCID.app -ov -format UDZO ACCID.dmg

  • Notarize: xcrun notarytool submit ACCID.dmg ...

  • Staple: xcrun stapler staple ACCID.dmg

Windows Build (on Windows machine)

  • Run: build_for_windows.bat

  • Test: dist\ACCID.exe

  • Verify: Browser opens to localhost:9847

  • Create ZIP: Compress dist\ACCID.exe

Linux Build (on Linux machine)

  • Run: ./build_for_linux.sh

  • Test: ./dist/ACCID

  • Verify: Browser opens to localhost:9847

  • Create archive: tar -czf ACCID_Linux.tar.gz -C dist ACCID

Distribution Checklist

  • Mac: ACCID.dmg (signed & notarized)

  • Windows: ACCID_Windows.zip

  • Linux: ACCID_Linux.tar.gz

  • All tested on clean machines

  • Version numbers updated in code

  • Release notes written

If Something Breaks

"It worked last time but not now"

  1. Check if Python version changed (we use 3.14+)
  2. Check if PyInstaller version changed (we use 6.16.0+)
  3. Check /tmp/accid_launcher.log (Mac) for errors

"Silent failure on double-click"

  1. Run from terminal to see errors
  2. Check paths in app.py (sys._MEIPASS)
  3. Verify ACCID.spec has console=False

"Import errors"

  1. Check requirements.txt is complete
  2. Add missing modules to hiddenimports in ACCID.spec

Remember: All platforms now use THE SAME onefile approach. No special cases, no wrapper scripts.

ACCID.spec - shared by all of them


# -*- mode: python ; coding: utf-8 -*-
# Universal ACCID.spec for Mac, Windows, and Linux
# Onefile mode - everything bundled into single executable

import sys
from pathlib import Path

# Platform-specific icon
icon_file = None
if sys.platform == 'darwin':
    icon_file = 'AppIcon.icns' if Path('AppIcon.icns').exists() else None
elif sys.platform == 'win32':
    icon_file = 'AppIcon.ico' if Path('AppIcon.ico').exists() else None
# Linux doesn't use icon in spec

a = Analysis(
    ['app.py'],
    pathex=[],
    binaries=[],
    datas=[
        ('templates', 'templates'),
        ('static', 'static'),
    ],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    noarchive=False,
    optimize=0,
)

pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='ACCID',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,  # GUI mode - no console window
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon=icon_file,  # Platform-specific icon
)

build_for_dmg.sh


#!/bin/bash
# ACCID Mac Build for DMG Distribution
# Location: ACCID_SOURCE/build_for_dmg.sh
#
# This uses ACCID.spec which bundles templates/static INTO the executable
# Creates a self-contained .app ready for /Applications

set -e

echo "🍎 Building ACCID for Mac DMG Distribution"
echo "==========================================="

# If old venv - remove
if [ -d ".venv" ]; then
    rm -rf .venv
    echo "📦 Removing Venv"
fi

# Clean old builds
echo "🧹 Cleaning old builds..."
rm -rf dist/ build/ ACCID.app

# Create new venv
python3 -m venv .venv
source .venv/bin/activate

# Install only reeuired build tools
pip install -r requirements.txt

# Build with PyInstaller using ACCID.spec
echo "🔨 Running PyInstaller with ACCID.spec..."
echo "   (This bundles templates/ and static/ into the executable)"
pyinstaller ACCID.spec --clean --noconfirm

# Verify build
if [ ! -f "dist/ACCID" ]; then
    echo "❌ Build failed - executable not found!"
    exit 1
fi

echo "✅ PyInstaller build complete"

APP_NAME="ACCID.app"
echo "📱 Creating ACCID.app bundle..."

mkdir -p "$APP_NAME/Contents/MacOS"
mkdir -p "$APP_NAME/Contents/Resources"

# Copy single PyInstaller executable (onefile mode)
cp dist/ACCID "$APP_NAME/Contents/MacOS/ACCID_bin"

# Write anti-quarantine launcher
cat > "$APP_NAME/Contents/MacOS/ACCID" <<'EOF'
#!/bin/zsh

# Log errors to file when double-clicked
LOG="/tmp/accid_launcher.log"
exec 2>"$LOG"

set -euo pipefail
DIR="$(cd -- "$(dirname -- "$0")" && pwd)"
APP_BUNDLE="$(cd -- "$DIR/../.." && pwd)"

echo "Starting ACCID launcher..." >> "$LOG"
echo "DIR: $DIR" >> "$LOG"
echo "APP_BUNDLE: $APP_BUNDLE" >> "$LOG"

if /usr/bin/xattr -p com.apple.quarantine "$APP_BUNDLE" >/dev/null 2>&1; then
  /usr/bin/xattr -dr com.apple.quarantine "$APP_BUNDLE" "$DIR" || true
  /usr/bin/osascript -e 'display dialog "Security flags cleared.\nPlease reopen the app." buttons {"OK"} default button 1 with title "ACCID Starter"'
  exit 0
fi

echo "Launching ACCID_bin..." >> "$LOG"

# Open browser after short delay (in background, so it doesn't block)
(sleep 3 && /usr/bin/open "http://localhost:9847") &

# Run ACCID_bin in FOREGROUND - this keeps it alive
"$DIR/ACCID_bin" "$@"
EOF

chmod +x "$APP_NAME/Contents/MacOS/ACCID"   # ONLY on your final launcher script

# Write Info.plist (with CFBundleExecutable = ACCID, NOT ACCID_Launcher)
cat > "$APP_NAME/Contents/Info.plist" << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleExecutable</key>
    <string>ACCID</string>
    <key>CFBundleName</key>
    <string>ACCID</string>
    <key>CFBundleDisplayName</key>
    <string>ACCID</string>
    <key>CFBundleIdentifier</key>
    <string>accid.cloud</string>
    <key>CFBundleVersion</key>
    <string>1.0.0</string>
    <key>CFBundleIconFile</key>
    <string>AppIcon.icns</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0.0</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>LSMinimumSystemVersion</key>
    <string>10.13</string>
    <key>NSHighResolutionCapable</key>
    <true/>
    <key>NSHumanReadableCopyright</key>
    <string>© 2025 SpiffyDesign. All rights reserved.</string>
</dict>
</plist>
EOF

echo ""
echo "Adding AppIcon.icns"
echo ""
# After creating ACCID.app, add icon
if [ -f "AppIcon.icns" ]; then
    cp AppIcon.icns "$APP_NAME/Contents/Resources/AppIcon.icns"
    echo "🎨 Icon added to $APP_NAME"
else
    echo "⚠️ AppIcon.icns not found in current directory"
fi
echo ""
echo "✅ BUILD COMPLETE!"
echo "===================="
echo ""
echo "📦 Self-contained .app created: $APP_NAME"
echo ""
echo "🧪 TO TEST:"
echo "   open ACCID.app"
echo ""
echo "   Check console output for:"
echo "   • CODE ROOT should be inside .app bundle"
echo "   • DATA ROOT should be ~/Library/Application Support/ACCID"
echo ""
echo "📦 TO DISTRIBUTE:"
echo "   1. Test locally first"
echo "   2. Copy to /Applications and test"
echo "   3. Sign: codesign --deep --force --sign 'Developer ID Application: Your Name' ACCID.app"
echo "   4. Create DMG: hdiutil create -volname ACCID -srcfolder ACCID.app -ov -format UDZO ACCID.dmg"
echo ""

build_windows.bat


@echo off
REM ACCID Windows Build for Distribution
REM Location: ACCID_SOURCE/build_for_windows.bat
REM
REM This uses ACCID.spec which bundles templates/static INTO the executable
REM Creates a self-contained .exe

echo Building ACCID for Windows Distribution
echo ==========================================

REM Clean old builds
echo Cleaning old builds...
if exist "dist\" rmdir /s /q dist
if exist "build\" rmdir /s /q build

REM Remove old venv if exists
if exist ".venv\" (
    rmdir /s /q .venv
    echo Removing old venv
)

REM Create new venv
python -m venv .venv
call .venv\Scripts\activate.bat

REM Install dependencies
pip install -r requirements.txt

REM Build with PyInstaller using ACCID.spec
echo Running PyInstaller with ACCID.spec...
echo    (This bundles templates/ and static/ into the executable)
pyinstaller ACCID.spec --clean --noconfirm

REM Verify build
if not exist "dist\ACCID.exe" (
    echo Build failed - executable not found!
    pause
    exit /b 1
)

echo.
echo ========================================
echo BUILD COMPLETE!
echo ========================================
echo.
echo Self-contained executable: dist\ACCID.exe
echo.
echo TO TEST:
echo    dist\ACCID.exe
echo.
echo TO DISTRIBUTE:
echo    1. Test locally first
echo    2. Create ZIP: Compress dist\ACCID.exe
echo    3. Optional: Use Inno Setup or similar for installer
echo.
pause

build_linux.py


#!/bin/bash
# ACCID Linux Build for Distribution
# Location: ACCID_SOURCE/build_for_linux.sh
#
# This uses ACCID.spec which bundles templates/static INTO the executable
# Creates a self-contained binary

set -e

echo "🐧 Building ACCID for Linux Distribution"
echo "=========================================="

# If old venv - remove
if [ -d ".venv" ]; then
    rm -rf .venv
    echo "📦 Removing Venv"
fi

# Clean old builds
echo "🧹 Cleaning old builds..."
rm -rf dist/ build/

# Create new venv
python3 -m venv .venv
source .venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Build with PyInstaller using ACCID.spec
echo "🔨 Running PyInstaller with ACCID.spec..."
echo "   (This bundles templates/ and static/ into the executable)"
pyinstaller ACCID.spec --clean --noconfirm

# Verify build
if [ ! -f "dist/ACCID" ]; then
    echo "❌ Build failed - executable not found!"
    exit 1
fi

# Make executable
chmod +x dist/ACCID

echo ""
echo "✅ BUILD COMPLETE!"
echo "===================="
echo ""
echo "📦 Self-contained executable: dist/ACCID"
echo ""
echo "🧪 TO TEST:"
echo "   ./dist/ACCID"
echo ""
echo "📦 TO DISTRIBUTE:"
echo "   1. Test locally first"
echo "   2. Create archive: tar -czf ACCID_Linux.tar.gz -C dist ACCID"
echo "   3. Optional: Create .deb or .rpm package"
echo ""