Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
7cacf3d
docs: refocus README on public architecture
turinglambdaai Sep 17, 2026
5616ecf
docs: add architecture boundaries
turinglambdaai Sep 17, 2026
39b3c0d
docs: add focused roadmap
turinglambdaai Sep 17, 2026
3a4bac3
docs: mark glaze main as public facade
turinglambdaai Sep 17, 2026
b1d2aaa
test: cover public glaze facade
turinglambdaai Sep 17, 2026
2c52e75
examples: add focused tray example
turinglambdaai Sep 17, 2026
d4f49de
examples: add focused events example
turinglambdaai Sep 17, 2026
f3edd05
examples: add events frontend
turinglambdaai Sep 17, 2026
4d59d9f
docs: organize examples by recommended learning path
turinglambdaai Sep 17, 2026
2dfe517
test: gate macOS menu e2e to macOS
turinglambdaai Sep 17, 2026
3fabee2
fix: make app shutdown idempotent and cleanup on errors
turinglambdaai Sep 17, 2026
b24169c
fix: dispatch tray operations by handle backend
turinglambdaai Sep 17, 2026
ada1599
fix: retain single-instance locks for process lifetime
turinglambdaai Sep 17, 2026
fc0f310
test: cover idempotent app shutdown
turinglambdaai Sep 17, 2026
a322189
security: confine static files and fix loopback host parsing
turinglambdaai Sep 17, 2026
f4f86b6
test: cover host guard and static path confinement
turinglambdaai Sep 17, 2026
0c70b24
fix: resolve packaged public assets without wrapper cwd
turinglambdaai Sep 17, 2026
7a950a3
fix: compile application entry directly
turinglambdaai Sep 18, 2026
8cac26e
fix: resolve packaged assets and validate server inputs
turinglambdaai Sep 18, 2026
59b5716
fix: modernize scaffold and repair build option parsing
turinglambdaai Sep 18, 2026
f531318
test: execute packaged module+ main entry
turinglambdaai Sep 18, 2026
ab5bb8f
ci: execute packaged entry on every platform
turinglambdaai Sep 18, 2026
1a29823
ci: enforce formatting and cover Racket 9.3 packaging
turinglambdaai Sep 18, 2026
50009fc
fix: harden update manifest fetching
turinglambdaai Sep 18, 2026
a52c170
security: stop leaking handler exceptions to clients
turinglambdaai Sep 18, 2026
cc2ede0
test: cover update hashing and safe 500 responses
turinglambdaai Sep 18, 2026
5209af1
fix: generate safe JavaScript API bindings
turinglambdaai Sep 18, 2026
9a945e0
test: cover safe generated API JavaScript
turinglambdaai Sep 18, 2026
ed3bb4f
fix: make CLI fail fast and protect existing projects
turinglambdaai Sep 18, 2026
a4900b8
security: enable API token by default and validate lifecycle inputs
turinglambdaai Sep 18, 2026
65b8d3f
test: cover run-app argument contracts
turinglambdaai Sep 18, 2026
21d5389
docs: document secure defaults and hardened runtime contracts
turinglambdaai Sep 18, 2026
f2c3c7a
docs: record stabilization fixes
turinglambdaai Sep 18, 2026
7085b05
feat: expose background-active webview mode
turinglambdaai Sep 18, 2026
3864006
feat: accept portable background-active webview option
turinglambdaai Sep 18, 2026
62488a8
feat: accept portable background-active webview option
turinglambdaai Sep 18, 2026
3c64dd4
feat: accept portable background-active webview option
turinglambdaai Sep 18, 2026
d4af0f7
feat: keep macOS monitoring webviews active with public APIs
turinglambdaai Sep 18, 2026
a758476
feat: pass background-active mode through run-app
turinglambdaai Sep 18, 2026
554e99e
fix: isolate build intermediates and verify notarization staple
turinglambdaai Sep 18, 2026
9beec49
fix: repair update checker syntax
turinglambdaai Sep 18, 2026
ef2d121
fix: classify listener startup races as network errors
turinglambdaai Sep 18, 2026
5889fbd
docs: document background-active webview mode
turinglambdaai Sep 18, 2026
17f12e2
fix: use real Windows folder picker and correct kdialog argv
turinglambdaai Sep 18, 2026
0c09144
fix: use correct macOS SMAppService registration API
turinglambdaai Sep 18, 2026
7d3913b
fix: harden license canonicalization and claim validation
turinglambdaai Sep 18, 2026
5096f4a
test: cover license control characters and invalid dates
turinglambdaai Sep 18, 2026
5e5a58b
fix: harden Linux deep-link registration contract
turinglambdaai Sep 18, 2026
d1a2034
security: escape Linux desktop entries and validate autolaunch inputs
turinglambdaai Sep 18, 2026
5fca17d
test: cover Linux deep-link contract and escaping
turinglambdaai Sep 18, 2026
c0ed47a
security: open browser without shell command construction
turinglambdaai Sep 18, 2026
22c9a0e
security: validate SSE event names and payloads
turinglambdaai Sep 18, 2026
86e4ae0
fix: make asset helpers robust for nested directories
turinglambdaai Sep 18, 2026
f72970c
fix: use real GDK clipboard atom and correct Linux helpers
turinglambdaai Sep 18, 2026
7cf6478
security: pass macOS notification content as argv
turinglambdaai Sep 18, 2026
d5d2aaf
fix: preserve Unicode and memory ownership in Windows clipboard
turinglambdaai Sep 18, 2026
4b944c9
fix: make installer builds fail-safe and assemble Linux AppDir
turinglambdaai Sep 18, 2026
443e630
security: escape packaging metadata and shell boundaries
turinglambdaai Sep 18, 2026
efb0d3b
fix: repair packaging helper source quoting
turinglambdaai Sep 18, 2026
a48f4a1
ci: cancel stale runs for superseded PR commits
turinglambdaai Sep 18, 2026
6442ff8
fix: fail closed for signing and bundle metadata
turinglambdaai Sep 18, 2026
1ffd840
ci: only request signing where credentials are available
turinglambdaai Sep 18, 2026
6f2bfb4
fix: repair SHA verifier parentheses
turinglambdaai Sep 18, 2026
960c701
fix: validate app names without unsupported regex escapes
turinglambdaai Sep 18, 2026
2dcf234
fix: remove stale glaze-lib CLI dependency
turinglambdaai Sep 18, 2026
1efb8d6
chore: keep runnable examples out of package setup compilation
turinglambdaai Sep 18, 2026
523e698
chore: exclude executable CI scripts from package setup
turinglambdaai Sep 18, 2026
c154a2d
security: make bootstrap single-use and protect SSE/origin boundaries
turinglambdaai Sep 18, 2026
af09637
security: use a distinct one-time browser bootstrap nonce
turinglambdaai Sep 18, 2026
39a71fe
test: lock down bootstrap, origin, and SSE authentication
turinglambdaai Sep 18, 2026
f50a377
test: cover SSE protocol input validation
turinglambdaai Sep 18, 2026
debca81
test: restore environment portably
turinglambdaai Sep 18, 2026
87cd65c
test: align generated client assertions with safe JS
turinglambdaai Sep 18, 2026
abf0f69
ci: use supported Windows installer toolchain
turinglambdaai Sep 18, 2026
7771166
fix: restore AppImage environment portably
turinglambdaai Sep 18, 2026
a1cbbac
fix: resolve Windows root-relative asset paths
turinglambdaai Sep 18, 2026
9bd8152
ci: replace unavailable formatter with compile gate
turinglambdaai Sep 18, 2026
bc71001
api: validate WebView facade arguments consistently
turinglambdaai Sep 18, 2026
69d1640
test: cover WebView facade contracts
turinglambdaai Sep 18, 2026
9595956
fix: fail loudly when browser fallback cannot launch
turinglambdaai Sep 18, 2026
2f49934
api: validate routes and response helpers early
turinglambdaai Sep 18, 2026
e0ac40f
test: cover API route and response contracts
turinglambdaai Sep 18, 2026
c06a4dc
docs: add security reporting policy
turinglambdaai Sep 18, 2026
f7fb875
docs: align contributor workflow with architecture boundaries
turinglambdaai Sep 18, 2026
d660b72
fix: make Windows dialog buffers memory-safe and parse multi-select
turinglambdaai Sep 18, 2026
b8b5da1
test: cover Windows dialog multi-string parsing and contracts
turinglambdaai Sep 18, 2026
9139a75
api: validate menu protocol before native dispatch
turinglambdaai Sep 18, 2026
406eb83
test: cover menu protocol contracts
turinglambdaai Sep 18, 2026
fb95e47
api: validate tray facade arguments consistently
turinglambdaai Sep 18, 2026
b97dbb3
test: cover tray facade contracts
turinglambdaai Sep 18, 2026
1a207e0
api: separate sys argument errors from platform failures
turinglambdaai Sep 18, 2026
6357a63
test: cover sys public argument contracts
turinglambdaai Sep 18, 2026
751b652
ci: verify installable source package archive
turinglambdaai Sep 18, 2026
6527030
docs: align Chinese README with current architecture
turinglambdaai Sep 18, 2026
dc17b3e
docs: add repeatable release checklist
turinglambdaai Sep 18, 2026
ff5fadb
fix: report Windows autolaunch removal failures
turinglambdaai Sep 18, 2026
c7fa748
pkg: separate runtime and build dependencies
turinglambdaai Sep 18, 2026
2f771da
cli: fail fast on invalid arguments and partial key generation
turinglambdaai Sep 18, 2026
f8036d7
test: cover CLI fail-fast behavior and scaffold
turinglambdaai Sep 18, 2026
2a18b7c
fix: validate and fully read update manifests
turinglambdaai Sep 18, 2026
152c8b3
test: cover update manifest and version contracts
turinglambdaai Sep 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 78 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ on:
pull_request:
branches: [main]

# A PR can receive many small stabilization commits. Only the newest SHA is
# useful; cancel stale runs so they do not consume the cross-platform runners
# or delay feedback for the current head.
concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
test:
runs-on: ${{ matrix.os }}
Expand All @@ -27,12 +34,41 @@ jobs:
shell: bash
run: raco pkg install --auto --no-docs --link "$PWD"

- name: Compile public entrypoints
run: raco make glaze/main.rkt glaze-cli/cli.rkt scripts/package-entry-smoke.rkt

- name: Run tests
run: raco test glaze-test/

- name: Check formatting
run: raco fmt --check glaze/ glaze-cli/ glaze-test/
continue-on-error: true
source-package:
# Release hygiene: prove the filtered source archive is independently
# installable. This job intentionally does not link the checkout first.
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Racket
uses: Bogdanp/setup-racket@v1.11
with:
version: '8.12'

- name: Create source package
shell: bash
run: |
cd ..
raco pkg create --source --format zip glaze
test -s glaze.zip

- name: Install source package archive
shell: bash
run: raco pkg install --auto --no-docs ../glaze.zip

- name: Verify installed facade and CLI
shell: bash
run: |
racket -e '(require glaze) (unless (procedure? run-app) (error "missing run-app"))'
raco glaze help

webview-e2e:
# Real-window WebView end-to-end on each OS: open -> load (title
Expand Down Expand Up @@ -112,20 +148,31 @@ jobs:

- name: Install installer toolchain (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
# WiX Toolset v4 (build falls back to zip if missing)
dotnet tool install --global wix
echo "$HOME/.dotnet/tools" >> $GITHUB_PATH
# Glaze supports WiX v4 syntax, but GitHub's latest global `wix`
# tool is now v7 and requires an additional OSMF license flow.
# NSIS is the other supported native Windows installer backend.
choco install nsis -y --no-progress
$nsis = "C:\Program Files (x86)\NSIS"
if (Test-Path $nsis) { $nsis | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append }

- name: Verify packaged entry executes
run: racket scripts/package-entry-smoke.rkt

- name: Scaffold and build a sample app
shell: bash
run: |
raco glaze init sampleapp
cd sampleapp
# --sign - exercises the signing pipeline everywhere: macOS signs
# the bundle ad-hoc (verifiable without a cert); Windows/Linux
# degrade with a loud warning when no signing toolchain exists.
raco glaze build --name sampleapp --version 0.0.1 --out dist --installer --sign -
# Exercise signing where CI can do it without secrets. On macOS,
# ad-hoc signing is verifiable; Windows signing correctly requires a
# real certificate and is covered by argument/tool failure behavior.
if [ "$RUNNER_OS" = "macOS" ]; then
raco glaze build --name sampleapp --version 0.0.1 --out dist --installer --sign -
else
raco glaze build --name sampleapp --version 0.0.1 --out dist --installer
fi
- name: Verify macOS bundle signature
if: runner.os == 'macOS'
run: |
Expand All @@ -143,3 +190,24 @@ jobs:
sampleapp/dist/*.msi
sampleapp/dist/*.dmg
sampleapp/dist/*.AppImage

package-racket-9-3-macos:
# Regression coverage for the macOS/Racket 9.3 launcher failure reported
# in issue #1. This job executes the final packaged binary, not merely the
# build command.
runs-on: macOS-latest

steps:
- uses: actions/checkout@v4

- name: Install Racket
uses: Bogdanp/setup-racket@v1.11
with:
version: '9.3'

- name: Install Glaze package
shell: bash
run: raco pkg install --auto --no-docs --link "$PWD"

- name: Verify packaged entry executes
run: racket scripts/package-entry-smoke.rkt
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Changed
- `run-app` now enables a random API capability token by default; pass
`#:api-token #f` explicitly for an intentionally open local API.
- Update checks are non-blocking from the application lifecycle and enforce a
five-second fetch timeout, 2xx status, and a 1 MiB manifest limit.
- `raco glaze init` scaffolds the recommended `run-app` / `(require glaze)`
entry and refuses to overwrite non-empty project directories.

### Fixed
- Packaging now compiles the user's real entry module, preserving
`(module+ main ...)` execution instead of producing launchers that could
exit successfully without running the application.
- Static-file serving rejects traversal outside `public/`, including resolved
symlinks, and Host validation correctly handles bracketed IPv6 loopback.
- API handler exceptions are reported to the trusted error callback but no
longer leak arbitrary exception text in 500 responses.
- Generated JavaScript API bindings safely escape route segments and no longer
use route parameter text as raw JavaScript identifiers.
- Shutdown is idempotent, single-instance listeners are retained for process
lifetime with deterministic cross-process ports, and tray operations dispatch
from each tray handle rather than process-global fallback state.


## [0.6.0] - 2026-09-15

### Added
Expand Down
71 changes: 49 additions & 22 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,75 @@
# Contributing to Glaze

Glaze is a pre-1.0 cross-platform desktop framework. Prefer small changes that preserve application-facing APIs and keep platform details behind the public dispatchers.

## Development Setup

```bash
git clone https://github.com/turinglambdaai/glaze.git
cd glaze
raco pkg install --auto --link "$PWD"
raco pkg install --auto --no-docs --link "$PWD"
```

(The repo root is one single Racket package — this installs the library,
the `raco glaze` CLI, and the docs in one step. `"$PWD"` is needed because
`raco pkg install` requires the source path to end in the package name.
After pulling changes, refresh with `raco pkg update --link "$PWD"`.)
The repository root is one installable Racket package using `collection 'multi`; the `glaze`, `glaze-cli`, `glaze-doc`, and `glaze-test` collections are installed together.

## Before Opening a Pull Request

## Running Tests
Run the platform-independent suite and compile the public entrypoints:

```bash
raco make glaze/main.rkt glaze-cli/cli.rkt scripts/package-entry-smoke.rkt
raco test glaze-test/
```

When your change touches WebView or packaging behavior, also run the relevant verification script on the affected operating system. CI exercises native WebView behavior and package construction on Windows, macOS, and Linux, including a macOS/Racket 9.3 packaging regression test.

## Architecture Rules

Read [`docs/architecture.md`](docs/architecture.md) before moving modules or adding a new capability. In particular:

- normal applications should prefer `(require glaze)`;
- `glaze/main.rkt` is the compatibility-preserving application facade;
- platform-specific modules belong behind `webview/main.rkt`, `tray/main.rkt`, or `sys/main.rkt`;
- do not make platform backends depend on application-level orchestration;
- shared protocols should not be duplicated independently in each backend;
- avoid large directory migrations solely for aesthetics;
- new public behavior should have a platform-independent contract test when possible.

## Code Style

- Follow standard Racket conventions
- Use `raco fmt` for formatting
- Add tests for new features
- Update Scribble documentation
Follow the dominant Racket style already present in the repository. The optional [`fmt`](https://pkgs.racket-lang.org/package/fmt) package can be installed with:

```bash
raco pkg install fmt
```

Do not reformat unrelated files in a functional pull request. Formatting-only churn makes native and lifecycle changes harder to review.

## Tests and Documentation

A change is not complete when only the happy path works. Prefer small regression tests for:

- public facade exports and argument validation;
- lifecycle and cleanup behavior;
- platform-independent protocol logic;
- security boundaries such as path containment and localhost API access;
- package artifacts that actually execute, not merely build successfully.

Update Scribble/API documentation and user-facing examples when a public contract changes. Do not document features that are only planned.

## Pull Requests

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Run tests
5. Submit a PR with a clear description
Keep each PR focused enough to explain why every changed file is necessary. In the description include the problem, compatibility impact, tests run, and any platform behavior you could not verify locally.

## Package Structure
Security issues should follow [`SECURITY.md`](SECURITY.md) instead of being disclosed with exploit details in a public issue.

The repo root is a single installable package; each top-level directory is a
Racket collection:
## Package Structure

| Directory | Purpose |
|-----------|---------|
| `glaze/` | Core implementation (collection `glaze`) |
|---|---|
| `glaze/` | Framework implementation and public facade |
| `glaze-cli/` | `raco glaze` commands |
| `glaze-doc/` | Scribble documentation |
| `glaze-test/` | Tests |
| `examples/` | Runnable examples (not compiled by setup) |
| `glaze-test/` | Regression and contract tests |
| `examples/` | Runnable examples |
| `scripts/` | CI and verification scripts |
Loading
Loading