Copyright e-dream, inc
2025.05 renamed e-dream to infinidream
2023.07 forked to work with new server and repository, renamed from Electric Sheep to e-dream
2015.05 moved from code.google.com repo
2011.01.30 based on revision 1546 on sf.net
infinidream: visuals for your vibe. a platform for generative visuals. this repository has the native client. See the backend for the server that it connects to.
Originally known as Electric Sheep.
this repository uses git LFS, be sure to run
brew install git-lfs
git lfs install
Also, if you are doing releases you will need: brew install gh brew install bugsnag/tap/bugsnag-cli
The general C++ dependencies are handled by vcpkg. Run these commands to build them:
git submodule update --init
./vcpkg/bootstrap-vcpkg.sh
./vcpkg/vcpkg install
on Mac, open client_generic/MacBuild/infinidream.xcodeproj
Use the "File>Packages>Update to Latest" menu to load the Mac specific dependencies.
There are four targets: app, screensaver, staging app, and staging screensaver. The staging targets have their own directory /Users/Shared/infinidream.ai-stage that can coexist with the normal one /Users/Shared/infinidream.ai
- Xcode 14.0 or later
- macOS 12.4 or later
The just run the app in xcode with the debugger and without making the embedded screensaver:
cd client_generic/MacBuild mkdir -p Resources/infinidream.saver
Then in xcode just use command-R.
cd client_generic/MacBuild
./build.py [options]-r: Build in Release mode (default: Debug)-s: Build stage version (default: production)-n: Enable notarization (requires-r)-v VERSION: Set version string (e.g.,0.12.0) for zip naming and GitHub release-g: Create GitHub release with tag (requires-v)
Auto-discovers Developer ID certificate and Team ID from keychain.
Override via environment variables:
DEVELOPER_ID_CERT="Developer ID Application: Your Name (TEAM123)" \
TEAM_ID="TEAM123" \
KEYCHAIN_PROFILE="your-profile" \
./build.py -rDefault keychain profile: infinidream-notarization
# Debug build (default)
./build.py
# Release build
./build.py -r
# Stage debug build
./build.py -s
# Release with notarization
./build.py -r -n
# Release with notarization and version (creates infinidream-0.12.0.zip)
./build.py -r -n -v 0.12.0
# Full release with appcast and GitHub release
./build.py -r -n -v 0.12.0 -g- Screensaver:
build/DerivedData/Build/Products/{Debug|Release}/infinidream.saver - Application:
build/{Debug|Release}/AppExport/infinidream.app
The app bundle contains the embedded screensaver at infinidream.app/Contents/Resources/infinidream.saver.
cd client_generic/MacBuild
./build.py -r -n -v X.Y.Z -gThis:
- Builds and notarizes the app
- Creates git tag
X.Y.Z(overwrites if exists) - Creates GitHub prerelease
vX.Y.Zwith auto-generated notes - Uploads
infinidream-X.Y.Z.zipto the release
open build/Release/AppExport/infinidream.appEdit the release notes on GitHub if needed: https://github.com/e-dream-ai/client/releases
Preview what will be published:
./release.py -v X.Y.Z --dry-runWhen ready, publish for real:
./release.py -v X.Y.Z # production (alpha)
./release.py -v X.Y.Z -s # stageThis:
- Fetches release notes from GitHub
- Generates appcast.xml (with linked issue references)
- Publishes appcast.xml to the landing-page repo
- Marks the GitHub release as latest (removes prerelease label)
Update APP_VERSION in the frontend repository:
src/components/pages/install/install.page.tsx
Push and Cloudflare will deploy in a few minutes.
- App checks appcast URL on launch:
- Production app:
https://infinidream.ai/appcast.xml - Stage app:
https://infinidream.ai/stage/appcast.xml
- Production app:
- Compares
sparkle:versionin appcast with app'sCFBundleVersion - If newer version found, shows update dialog
- User clicks "Update Now" → downloads zip from GitHub → installs → relaunches
Download Sparkle tools from https://github.com/sparkle-project/Sparkle/releases
Extract and copy to client_generic/MacBuild/bin/:
generate_appcast- generates appcast.xml with signaturessign_update- signs update archivesgenerate_keys- generates EdDSA key pair (one-time use)
Sparkle uses EdDSA (Ed25519) signatures to verify updates are authentic.
Public key is in Info.plist:
<key>SUPublicEDKey</key>
<string>pkDT5qmpWtyaZxw5X6Ca7DPHueEfBEKrxkrKzSN/qS0=</string>Private key is stored in macOS Keychain under the name Sparkle EdDSA Key.
To generate a new key pair (only if needed):
cd client_generic/MacBuild
./bin/generate_keysThis will:
- Create a new EdDSA key pair
- Store the private key in Keychain
- Print the public key to add to
Info.plist
Important: If you generate new keys, you must update SUPublicEDKey in:
App-Info.plistApp-Stage-Info.plistScreensaver-Info.plist
Existing users won't be able to update if the public key changes, so only regenerate keys if the private key is lost.
On stage, running with xcode, test with playlists Keyframe Test and Basic Playlist.
Then do it again but after rm -rf /Users/Shared/infinidream.ai-stage/content/
to test while streaming.
Then do a basic test after rm -rf /Users/Shared/infinidream.ai-stage/
to test sign-in flow.
After building, test on alpha with Wanderlust and Pink Floyd and Wankel Rotary Engine.
With fully downloaded playlists, go through all navigation acommands: next, prev, forward, backward, faster, slower, pause, both from keyboard and with remote control. Remote only interactions: switching playlists, playing from filmstrip.
Then do it again but after rm -rf /Users/Shared/infinidream.ai/content/
to test while streaming.
Then do a basic test after rm -rf /Users/Shared/infinidream.ai/
to test sign-in flow.
Then disable the screensaver, then uninstall the screen saver, then run the app and make sure it installs and selects the screen saver.
Upload the symbols to bugsnag, on a terminal:
- if first time install the upload tool
brew install bugsnag/tap/bugsnag-dsym-upload - Go to https://app.bugsnag.com/settings/e-dream-dot-ai/projects/client-macos/missing-dsyms and copy the first missing UUID corresponding to the tag
- run
mdfind YOUR_UUID_HERE. This will output a path to the dsympath/to/dsyms/MyApp.dSYM - run
bugsnag-dsym-upload path/to/dsyms(note that it's the path TO the dsyms)