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:
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 toFalsefor 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:
- Removes old .venv
- Creates fresh Python 3.12 venv
- Installs dependencies from requirements.txt
- Runs
pyinstaller ACCID.spec --clean --noconfirm - 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:
- ✅ Console window opens
- ✅ Prints "ACCID - Automated..." header
- ✅ Loads projects
- ✅ Starts server on port 9847
- ✅ Opens browser to localhost:9847
- ✅ Site loads and works
- ✅ 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
- Extract ZIP
- Double-click ACCID.exe
- Browser opens to localhost:9847
- 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
-
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:
- Creates fresh venv
- Installs dependencies from requirements.txt
- Calls PyInstaller with ACCID.spec
- Creates onefile executable (everything bundled)
- 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:
- Start server on port 9847
- Auto-open browser to localhost:9847
- Create data in ~/Library/Application Support/ACCID (Mac) or equivalent
Distribution
Mac
- Sign:
codesign --deep --force --sign "Developer ID Application: Your Name" ACCID.app - Create DMG:
hdiutil create -volname ACCID -srcfolder ACCID.app -ov -format UDZO ACCID.dmg - Notarize & staple
EXTRA MAC STEPS
-
/Volumes/SpiffyMagic/ACCID_MANAGEMENT/accid_pre_scripts/4a_sign_scripts_also_dmg_mac.sh
-
Sign the
.app: Only sign the final cleaned.appbundle. -
Build your DMG: Package only the
.appand any minimal docs/readme.\-
# 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
-
-
Notarize/Distribute.
- Mac users get DMG/APP
- Windows users get ZIP/Installer
- Linux users get tar.gz (or optional .deb/.rpm)
Windows
- Create ZIP: Compress dist\ACCID.exe
- Optional: Create installer with Inno Setup
Linux
- Create archive:
tar -czf ACCID_Linux.tar.gz -C dist ACCID - 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.binariesanda.datasin 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._MEIPASSpath 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"
- Check if Python version changed (we use 3.14+)
- Check if PyInstaller version changed (we use 6.16.0+)
- Check /tmp/accid_launcher.log (Mac) for errors
"Silent failure on double-click"
- Run from terminal to see errors
- Check paths in app.py (sys._MEIPASS)
- Verify ACCID.spec has console=False
"Import errors"
- Check requirements.txt is complete
- 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 ""
