Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b1b1e63
chore: establish audited phase 0 baseline
aivrar Jul 10, 2026
813f766
chore: complete phase 0 evidence and guardrails
aivrar Jul 11, 2026
5d2a12d
feat: complete audited phase 1 foundation
aivrar Jul 13, 2026
34eb6f7
feat: prepare phase 2 visual approval checkpoint
aivrar Jul 13, 2026
4f904c9
test: harden phase 2 accessibility checkpoint
aivrar Jul 13, 2026
32fa6ab
fix: refine phase 2 visual review checkpoint
aivrar Jul 13, 2026
a4c7d45
feat: harden phase 2 visual approval checkpoint
aivrar Jul 13, 2026
a469016
docs: map phase 2 post-approval rollout
aivrar Jul 13, 2026
4470c4f
feat: complete audited phase 2 rollout
aivrar Jul 13, 2026
f939076
docs: lock phase 3 implementation profile
aivrar Jul 13, 2026
641b365
feat: add verified daily derivation domain
aivrar Jul 13, 2026
552d62d
feat: complete phase 3 daily constellation
aivrar Jul 13, 2026
4c20e84
docs: map phase 4 archive implementation
aivrar Jul 13, 2026
88b3d0c
feat: complete phase 4 archive v2
aivrar Jul 13, 2026
8d1fbf0
docs: map phase 5 safe packs
aivrar Jul 13, 2026
4348dcb
feat: complete phase 5 local content packs
aivrar Jul 13, 2026
f0f0379
docs: map phase 6 proportional projects
aivrar Jul 13, 2026
c1229f3
feat: complete phase 6 creative projects
aivrar Jul 13, 2026
7c9580e
feat: complete phase 7 portable receipts
aivrar Jul 13, 2026
057aba0
feat: complete phase 8 gentle practices
aivrar Jul 13, 2026
7bf4b42
feat: complete phase 9 Symphony replay and export
aivrar Jul 13, 2026
e17c130
docs: complete phase 10 desktop integration review
aivrar Jul 13, 2026
96e3f6b
feat: complete phase 11 printable journal export
aivrar Jul 13, 2026
dc2ac7b
release: complete phase 12 Windows portable gate
aivrar Jul 14, 2026
fcafe62
fix: harden real-world Today and entropy flows
aivrar Jul 14, 2026
fed0e68
fix: show randomness sources on every result
aivrar Jul 14, 2026
450384d
improve Canvas art and auto-apply controls
aivrar Jul 14, 2026
3767506
release: prepare 0.2.0 and prune stale artifacts
aivrar Jul 14, 2026
1ab24cc
docs: align wiki with 0.2.0 release
aivrar Jul 14, 2026
790c164
fix CI platform lint and native result wait
aivrar Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
97 changes: 97 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run content:check
- run: npm run schemas:check
- run: npm run typecheck
- run: npm test
- run: npm run lint
- run: npm run test:renderer
- run: npm run build
- run: npm run quality:sizes -- --frontend-only
- run: npm run quality:licenses
- run: npm audit
- uses: actions/upload-artifact@v4
with:
name: frontend-quality-reports
path: |
artifacts/quality/size-report-frontend.json
artifacts/quality/dependency-license-census.md

rust:
strategy:
fail-fast: false
matrix:
os: [windows-latest, macos-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: src-tauri
steps:
- uses: actions/checkout@v4
- name: Install Linux system dependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
working-directory: .
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- run: cargo fmt --all -- --check
- run: cargo check --all-targets
- run: cargo clippy --all-targets -- -D warnings
- run: cargo test --all-targets
- uses: actions/setup-node@v4
if: runner.os == 'Windows'
with:
node-version: 22
cache: npm
- name: Build production frontend for the Windows release binary
if: runner.os == 'Windows'
working-directory: .
run: |
npm ci
npm run build
- name: Build and report optimized Windows executable size
if: runner.os == 'Windows'
working-directory: .
run: |
cargo build --release --locked --manifest-path src-tauri/Cargo.toml
node scripts/report-build-size.mjs --binary-only
- uses: actions/upload-artifact@v4
if: runner.os == 'Windows'
with:
name: windows-binary-size-report
path: artifacts/quality/size-report-windows-binary.json

desktop-e2e:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri
- run: npm ci
- run: npm run test:desktop:build
- run: npm run test:desktop
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ node_modules/

# Build output
dist/
artifacts/
src-tauri/target/
src-tauri/gen/schemas/

Expand All @@ -29,3 +30,6 @@ src-tauri/.cargo/
# Playwright MCP cache
.playwright-mcp/

# Reproducible local benchmark and fixture output
.tmp/

132 changes: 84 additions & 48 deletions BUILD.md
Original file line number Diff line number Diff line change
@@ -1,84 +1,120 @@
# Building Sortilune
# Building Sortilune for Windows

Sortilune is a Tauri 2.x desktop app. The release output is a **single portable .exe** on Windows; .app/.dmg on macOS; .AppImage/.deb on Linux. No installer is required to run the .exe — copy it anywhere.
Sortilune’s supported release artifact is one portable Windows executable. The release gate in this repository does not certify macOS, Linux, MSI, or NSIS outputs.

## Prerequisites

| | Windows | macOS | Linux |
|---|---|---|---|
| Rust | 1.75+ via [rustup](https://rustup.rs) | same | same |
| Node | 18+ | same | same |
| C toolchain | [Microsoft C++ Build Tools](https://aka.ms/vs/17/release/vs_BuildTools.exe) | Xcode CLT (`xcode-select --install`) | `build-essential`, `libwebkit2gtk-4.1-dev`, `librsvg2-dev`, `libssl-dev` |
| WebView | **Microsoft WebView2** (preinstalled on Windows 10 1803+ / Windows 11) | WKWebView (system) | WebKitGTK (provided by libwebkit2gtk-4.1-dev) |
- Windows 10 version 1803 or newer, or Windows 11
- Node.js 20.19+ or 22.12+
- npm matching the selected Node installation
- stable Rust with the `x86_64-pc-windows-msvc` target
- Microsoft C++ Build Tools
- Microsoft WebView2 Runtime

## Install
The exact frontend and Rust dependency graphs are locked by `package-lock.json` and `src-tauri/Cargo.lock`.

```bash
cd sortilune # the project root containing package.json
npm install
```

## Develop
## Install and develop

```bash
```powershell
git clone https://github.com/aivrar/sortilune.git
Set-Location sortilune
npm ci
npm run tauri:dev
```

The dev server boots Vite on `localhost:1420`, then launches the Tauri window. Hot reload works for the JS/CSS frontend; Rust changes require a re-run.
Vite serves the renderer on `127.0.0.1:1420` during development. Rust or Tauri-configuration changes require the desktop process to restart.

## Build
## Build the portable executable

### Single portable .exe (the goal)

```bash
```powershell
npm run tauri:build:portable
```

This invokes `tauri build --no-bundle`, which skips the .msi/.nsis bundlers and produces only the raw release binary:
This runs `tauri build --no-bundle` and produces:

```text
src-tauri\target\release\sortilune.exe
```
src-tauri/target/release/sortilune.exe
```

That .exe is **portable**: copy it to any folder, USB stick, or another Windows machine and double-click. All frontend assets are embedded inside the binary via Tauri's `generate_context!` macro.

### What it depends on at runtime
All frontend assets are embedded. The executable can be copied to another folder or Windows machine, but the destination must have WebView2 Runtime. User data remains in `%APPDATA%\com.sortilune.desktop\`, beside neither the executable nor the source tree.

- **WebView2 Runtime** — preinstalled on Windows 10 1803+ and Windows 11. If a target machine somehow lacks it, double-clicking the .exe will trigger the Tauri bootstrapper which silently fetches it. If you need fully offline distribution, set `bundle.windows.webviewInstallMode.type = "embedBootstrapper"` in `src-tauri/tauri.conf.json` and the bootstrapper will be embedded into the bundle (the standalone .exe itself remains small).
To build and stage a versioned GitHub Release asset with its SHA-256 checksum and manifest:

### With installers
```powershell
npm run release:windows
```

```bash
npm run tauri:build
The files are written to the ignored `artifacts\release\` directory, so binaries and generated reports cannot accidentally enter the source commit.

## Quality gate

Run from the repository root:

```powershell
npm ci
npm run content:check
npm run schemas:check
npm test
npm run typecheck
npm run lint
npm run test:renderer
npm run build
npm audit

Set-Location src-tauri
cargo fmt --all -- --check
cargo check --all-targets
cargo clippy --all-targets -- -D warnings
cargo test --all-targets
Set-Location ..
```

This produces, in addition to the portable .exe:
The feature-specific WebDriver suites exercise Today, Archive, Packs, Projects, receipt verification, Practices, Symphony replay/export, Journal Export, and release behavior. Run them with `npm run test:today`, `test:archive`, `test:packs`, `test:projects`, `test:receipts`, `test:practices`, `test:symphony`, `test:journal`, and `test:release`.

- `src-tauri/target/release/bundle/nsis/Sortilune_0.1.0_x64-setup.exe` — NSIS installer
- (optionally `.msi` if the `wix` target is added back in tauri.conf.json)
## Native WebView2 smoke

### Cross-platform notes
Build the test-only desktop driver and run its real Tauri/WebView2 workflow:

- **macOS**: `npm run tauri:build` produces `src-tauri/target/release/bundle/macos/Sortilune.app` and a `.dmg`. The .app is the portable form.
- **Linux**: `npm run tauri:build` produces `src-tauri/target/release/sortilune` (the portable binary) and a `.AppImage` / `.deb` if configured.
```powershell
npm run test:desktop:build
npm run test:desktop
```

## Verifying the build
The native suite opens the embedded app, navigates the rail, saves and restores a real Archive record, exercises annotations and watcher refresh, and persists/reloads a Project through native IPC. Its test-only WebDriver capability is defined in `src-tauri/tauri.wdio.conf.json` and is not present in the production executable.

```bash
# After tauri:build, confirm the portable artifact exists and runs.
src-tauri\target\release\sortilune.exe
## Production startup smoke

After the optimized build:

```powershell
$process = Start-Process .\src-tauri\target\release\sortilune.exe -PassThru
Start-Sleep -Seconds 5
if ($process.HasExited) { throw "Sortilune exited during startup smoke" }
Stop-Process -Id $process.Id
```

The window should open within ~2 seconds, show the **Sortilune** brand at top-left, eight chamber tabs in the center pill, and the theme switcher at the right. Clicking any chamber tab should swap the placeholder content. Switching themes should restyle everything in place.
For manual inspection, launch the same executable without `-PassThru` handling and verify that Today appears, the navigation rail scrolls, `Ctrl+K` opens the command palette, themes switch, Settings opens, and normal window close exits the process.

## Generated content and schemas

## Wallpaper-setting (Phase 6)
- `npm run content:check` proves committed compact deck modules match their source data.
- `npm run schemas:check` proves committed standalone validators match their schemas.
- `npm run build` regenerates both before the Vite production build.

The Canvas chamber will set the desktop wallpaper through a platform-specific Tauri command. Windows uses `SystemParametersInfo(SPI_SETDESKWALLPAPER, ...)`; macOS uses `osascript` / `NSWorkspace`; Linux uses `gsettings` for GNOME or `feh` etc. Details when Phase 6 lands.
If a check fails after an intentional source/schema change, run the matching `*:generate` command and review the generated diff before committing.

## App icon
## Size and dependency reports

Source: `src-tauri/icons/app-icon.png` (1024×1024). Generate the full icon set with:
After `npm run build` and the portable build:

```bash
npx @tauri-apps/cli icon src-tauri/icons/app-icon.png --output src-tauri/icons
```powershell
npm run quality:sizes
npm run quality:licenses
npm audit
```

The size report enforces the committed frontend and executable budgets. The license census and npm audit are review evidence; neither replaces source-level dependency-necessity review.

## Troubleshooting

See [docs/release/TROUBLESHOOTING.md](docs/release/TROUBLESHOOTING.md) for WebView2, source availability, local data, audio, printing, pack import, and build failures.
3 changes: 2 additions & 1 deletion CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ Each chamber that uses these sources displays the source name and a `verify` lin
| [tauri](https://crates.io/crates/tauri) | The desktop application framework | Apache-2.0 / MIT |
| [tauri-plugin-http](https://crates.io/crates/tauri-plugin-http) | CORS-bypassed HTTP requests from the WebView | Apache-2.0 / MIT |
| [tauri-plugin-fs](https://crates.io/crates/tauri-plugin-fs) | Filesystem access for the local archive | Apache-2.0 / MIT |
| [wallpaper](https://crates.io/crates/wallpaper) | Cross-platform desktop wallpaper setting (Canvas chamber) | Apache-2.0 / MIT |
| [wallpaper](https://crates.io/crates/wallpaper) | Windows desktop wallpaper setting (Canvas chamber) | MIT |
| [tauri-plugin-dialog](https://crates.io/crates/tauri-plugin-dialog) | Native open/save dialogs for local pack workflows | Apache-2.0 / MIT |
| [serde](https://crates.io/crates/serde) | Serialization | Apache-2.0 / MIT |
| [serde_json](https://crates.io/crates/serde_json) | JSON serialization | Apache-2.0 / MIT |

Expand Down
Loading
Loading