Uses bun for development and Tauri for desktop app builds.
- Install Bun:
curl -fsSL https://bun.sh/install | bash- Install Rust and its dependencies:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh- Install system dependencies:
# Install Xcode Command Line Tools
xcode-select --install
# Install additional dependencies via Homebrew
brew install openssl@3sudo apt update
sudo apt install libwebkit2gtk-4.1-dev \
build-essential \
curl \
wget \
file \
libssl-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev- Add required Rust targets for universal macOS builds:
rustup target add aarch64-apple-darwin x86_64-apple-darwin- Clone the repository and run the setup script:
./setup-hooks.shThis will configure git to use the project's pre-commit hooks, which run bun run build before each commit.
This project uses just for common development tasks:
# List all available commands
just
# Install dependencies
just install
# Start development server
just dev
# Build the project
just build
# Format code
just format
# Run tests
just test
# Get current version
just get-version- Install dependencies:
bun install- Start the development server:
# For web development only
bun run dev
# For desktop app development
bun tauri devExpects a VITE_OPEN_SECRET_API_URL environment variable to be set. For local
OpenSecret development, copy frontend/.env.example to frontend/.env.local
and point it at the local API:
VITE_OPEN_SECRET_API_URL=http://127.0.0.1:3000The public OpenSecret client id defaults to Maple's project id
ba5a14b5-d915-47b1-b7b1-afda52bc5fc6, so VITE_CLIENT_ID is only needed to
override the default. (See .env.example)
Use the just commands for desktop builds:
# Release build
just desktop-build
# Debug build
just desktop-build-debug
# If you encounter CC-related errors in a Nix shell, use the -no-cc variants:
just desktop-build-no-cc
just desktop-build-debug-no-ccOr use bun tauri build directly:
# Standard build
bun tauri build
# For universal macOS build (Apple Silicon + Intel)
bun tauri build --target universal-apple-darwinLinux builds bundle libonnxruntime.so for local TTS (Supertonic). Before building on Linux, you must download the ONNX Runtime shared library:
cd frontend/src-tauri
./scripts/provide-linux-onnxruntime.shThis downloads the pinned ONNX Runtime release, verifies its SHA-256 checksum, and extracts it to frontend/src-tauri/onnxruntime-linux/ (which is gitignored). The script is idempotent — it skips the download if the library already exists.
Note: CI workflows call this script automatically. You only need to run it manually for local builds.
If you're running the built Maple binary in a headless environment (e.g., CI, virtual display with Xvfb), WebKit may fail to render content. Set these environment variables before launching:
export WEBKIT_DISABLE_COMPOSITING_MODE=1
export WEBKIT_DISABLE_DMABUF_RENDERER=1
DISPLAY=:0 ./frontend/src-tauri/target/debug/mapleThese are set automatically when using nix develop (via flake.nix).
If you need a new set of icons:
bun run tauri icon [path/to/png]
- Generate a new signing key:
cargo tauri signer generateThis will create the tauri public and private key.
- Add the public key to
src-tauri/tauri.conf.jsonin theupdater.pubkeyfield - Add the private key to GitHub Actions secrets:
- Go to repository Settings → Secrets and variables → Actions
- Create a new secret named
TAURI_SIGNING_PRIVATE_KEY - Create another secret named
TAURI_SIGNING_PRIVATE_KEY_PASSWORDif your key has a password - Paste the private key from the tauri command.
For proper macOS builds and notarization, you need to set up the following GitHub secrets:
-
APPLE_CERTIFICATE- Base64-encoded p12 certificatebase64 -i YourCertificate.p12 | pbcopy # Copies to clipboard
-
APPLE_CERTIFICATE_PASSWORD- Password for the certificate -
KEYCHAIN_PASSWORD- Password for the temporary keychain (can be any secure password) -
APPLE_ID- Your Apple Developer account email -
APPLE_PASSWORD- Your Apple Developer account password or app-specific password -
APPLE_TEAM_ID- Your Apple Developer team ID
Windows release builds use Microsoft Azure Artifact Signing through GitHub Actions OIDC. No Azure client secret is required.
Add these GitHub Actions secrets:
| GitHub secret | Source |
|---|---|
AZURE_CLIENT_ID |
Microsoft Entra app registration "Application (client) ID". |
AZURE_TENANT_ID |
Microsoft Entra "Directory (tenant) ID". |
AZURE_SUBSCRIPTION_ID |
Azure subscription ID that contains the Artifact Signing account. |
AZURE_ARTIFACT_SIGNING_ENDPOINT |
Artifact Signing account endpoint. |
AZURE_ARTIFACT_SIGNING_ACCOUNT_NAME |
Artifact Signing account name. |
AZURE_ARTIFACT_SIGNING_CERTIFICATE_PROFILE_NAME |
Certificate profile name under the Artifact Signing account. |
AZURE_ARTIFACT_SIGNING_EXPECTED_SUBJECT |
Expected signer certificate Subject DN for that certificate profile. |
The Entra application must also have a federated credential for this GitHub environment:
repo:OpenSecretCloud/Maple:environment:windows-signing
In the Azure portal, add it under Microsoft Entra ID -> App registrations -> the CI application -> Certificates & secrets -> Federated credentials. Use:
- Organization:
OpenSecretCloud - Repository:
Maple - Entity type:
Environment - Environment name:
windows-signing - Audience:
api://AzureADTokenExchange
If the portal asks for raw values instead of GitHub-specific fields, use:
- Issuer:
https://token.actions.githubusercontent.com - Subject:
repo:OpenSecretCloud/Maple:environment:windows-signing - Audience:
api://AzureADTokenExchange
Assign the same Entra application/service principal the Artifact Signing Certificate Profile Signer role on the Artifact Signing account, resource
group, or subscription. The role assignment is what authorizes the OIDC-auth'd
GitHub runner to sign with the certificate profile.
The expected signer subject should match the X.509 signer certificate subject
reported by Get-AuthenticodeSignature. It is usually visible on the Artifact
Signing certificate profile as the Subject DN derived from the completed identity
validation, for example CN=Example Corp, O=Example Corp, L=City, S=State, C=US.
Do not pin the leaf certificate thumbprint for this check; Artifact Signing
manages certificate lifecycle and can issue rotated certificates for the same
profile identity.
The Windows release job builds maple.exe first, Authenticode-signs it, bundles
the NSIS installer from that signed executable, Authenticode-signs the installer,
then creates the Tauri updater .sig for the final signed installer bytes. This
ordering is required because Authenticode signing changes the file being signed;
the Tauri updater signature must be generated after the final Windows installer
signature is applied.
Windows release verification currently checks the final signed installer bytes, the final Tauri updater signature, and the pinned runtime DLL proofs. It does not yet try to canonicalize Authenticode-signed Windows binaries back to an unsigned baseline.
Use the provided just commands to manage version updates:
# Bump patch version (e.g., 1.0.0 → 1.0.1)
just bump-patch
# Bump minor version (e.g., 1.0.0 → 1.1.0)
just bump-minor
# Bump major version (e.g., 1.0.0 → 2.0.0)
just bump-major
# Set a specific version
just update-version 1.2.3
# Create a release with automatic git tag
just release 1.2.3These commands automatically update all necessary files:
frontend/package.jsonfrontend/src-tauri/tauri.conf.jsonfrontend/src-tauri/Cargo.tomlfrontend/src-tauri/gen/apple/project.ymlfrontend/src-tauri/gen/apple/maple_iOS/Info.plistCargo.lock(via cargo check)
Android versionCode is internal and increments by one for each Play Store upload.
Use just update-android-counter for another internal/test build with the same visible version.
- Use one of the version commands above to update the version
- Create a new release in GitHub:
- Go to Releases → Draft a new release
- Create a new tag (e.g.,
v0.1.0) - Set a release title and description
- Publish the release
The GitHub Actions workflow will automatically:
- Build the app for all platforms
- Sign the builds
- Upload the artifacts to the release
- Create and upload
latest.jsonfor auto-updates
If there's a new version of the enclave pushed to staging or prod, append the new PCR0 value to the pcr0Values or pcr0DevValues arrays in frontend/src/app.tsx.
Run in emulator:
dotenv -e .env.local -- bun run tauri ios dev 'iPhone 16 Pro'Run on a connected phone:
dotenv -e .env.local -- bun run tauri ios buildTo prevent committing automatic changes to the XCode project file during local development:
# Tell Git to ignore changes to the file
git update-index --assume-unchanged frontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxproj
# When you need to commit changes to this file, use:
git update-index --no-assume-unchanged frontend/src-tauri/gen/apple/maple.xcodeproj/project.pbxproj