You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Windows: Windows Build Tools (`npm install -g windows-build-tools`)
34
38
- a working `claude` CLI login if you want Claude support
35
39
- a working `codex` CLI login if you want Codex support
36
40
-`pyright-langserver` or `basedpyright-langserver` on your PATH if you want Python LSP support in the editor
@@ -48,6 +52,14 @@ codex login
48
52
bun install
49
53
```
50
54
55
+
`bun install` automatically runs a `postinstall` hook that patches `better-sqlite3` for Electron 41 compatibility and recompiles both `better-sqlite3` and `node-pty` against the Electron ABI. This is required because these native modules must be compiled for Electron's internal Node runtime, not the host Node version.
56
+
57
+
If you need to skip the native rebuild (e.g. in a CI environment that only runs web builds), set `SKIP_ELECTRON_REBUILD=1`:
58
+
59
+
```bash
60
+
SKIP_ELECTRON_REBUILD=1 bun install
61
+
```
62
+
51
63
## Development
52
64
53
65
```bash
@@ -78,24 +90,65 @@ bun run dev:desktop:poll
78
90
-`bun run package:linux:appimage`
79
91
-`bun run package:linux:deb`
80
92
93
+
## Running the desktop app
94
+
95
+
The primary way to build and launch Stave locally is:
96
+
97
+
```bash
98
+
bun run run:desktop:built
99
+
```
100
+
101
+
This single command:
102
+
1. Recompiles native modules (`better-sqlite3`, `node-pty`) against the Electron ABI
103
+
2. Applies the Electron 41 `better-sqlite3` C++ patch (`info.HolderV2()`)
104
+
3. Runs `electron-vite build` to produce the production bundle
105
+
4. Launches the app:
106
+
-**macOS** — packages with `electron-builder --dir` and opens `Stave.app` so the OS titlebar shows "Stave" instead of "Electron"
107
+
-**Linux / Windows** — runs `electron .` with `STAVE_RUNTIME_PROFILE=production`
108
+
81
109
## Desktop packaging
82
110
83
-
The desktop packaging scripts and `bun run run:desktop:built` now rebuild native Electron modules automatically before bundling or launching the built app. On macOS, `bun run run:desktop:built` now launches the unpacked `Stave.app` bundle so the OS shows the app as `Stave` instead of `Electron`. If your local install gets out of sync after `bun install`, run the rebuild manually:
111
+
### Why native modules need rebuilding
112
+
113
+
`better-sqlite3` and `node-pty` are C++ native modules. When you run `bun install`, they are compiled for the **host Node.js** ABI. Electron bundles its **own Node.js runtime** with a different ABI, so the modules must be recompiled for Electron specifically. Additionally, Electron 41 changed how V8 `PropertyCallbackInfo` works in getter callbacks, requiring a source-level patch to `better-sqlite3` (`info.This()` → `info.HolderV2()`) before the C++ is compiled.
114
+
115
+
All of this is handled automatically by `postinstall` and by each packaging/run script. You should not need to think about it in normal development.
116
+
117
+
### Manual rebuild
118
+
119
+
If you reinstall packages with `--ignore-scripts`, or if your native modules become out of sync for any reason, rebuild manually:
84
120
85
121
```bash
86
122
bun run rebuild:electron-deps
87
123
```
88
124
89
-
This rebuild now patches `better-sqlite3` in the Electron 41 getter contexts that need `HolderV2()`, then runs `node-gyp rebuild --runtime=electron --build-from-source` for `better-sqlite3` and `node-pty` using the current Electron version and host architecture. Electron headers are cached under `.cache/node-gyp/`in the repo so the rebuild does not depend on a writable home-directory cache.
125
+
The rebuild reads the **actual installed Electron version** from `node_modules/electron/package.json`, so the compiled ABI always matches what is on disk — regardless of semver ranges in `package.json`. Electron headers are cached under `.cache/node-gyp/`inside the repo so the rebuild does not depend on a writable home-directory cache.
90
126
91
-
Useful packaging commands:
127
+
### Packaging commands
92
128
93
129
```bash
130
+
# Build and run locally (primary workflow)
94
131
bun run run:desktop:built
132
+
133
+
# Package as unpacked directory
134
+
bun run package:desktop
135
+
136
+
# Linux targets
95
137
bun run package:linux:dir
138
+
bun run package:linux:appimage
96
139
bun run package:linux:deb
97
140
```
98
141
142
+
### Troubleshooting
143
+
144
+
| Symptom | Likely cause | Fix |
145
+
|---|---|---|
146
+
|`NODE_MODULE_VERSION` mismatch on launch | Native modules compiled for host Node, not Electron |`bun run rebuild:electron-deps`|
147
+
| App crashes or freezes on first persist | Electron 41 `HolderV2` patch not applied |`bun run rebuild:electron-deps`|
148
+
|`[persistence] upsert-workspace-sync failed` in Electron logs | Same as above, check the full error message |`bun run rebuild:electron-deps`|
149
+
|`Patch signature not found` error during rebuild |`better-sqlite3` version changed or `node_modules` corrupted |`bun install && bun run rebuild:electron-deps`|
150
+
| Build fails with `node-gyp` errors | Missing C++ toolchain | Install Xcode CLT / build-essential (see Prerequisites) |
151
+
99
152
## Docs
100
153
101
154
Stable project documentation now lives under `docs/`.
description: Release workflow for the Stave repository that bumps the patch version, generates release notes with `conventional-changelog`, and opens a pull request against `main`. Use when the user asks to cut the next patch release, ship the current changes as a versioned release, or prepare a release PR. After the PR merges, the repository's GitHub Actions workflow builds and publishes the release artifacts automatically.
4
+
---
5
+
6
+
# Stave Release
7
+
8
+
Use this skill to create a versioned release PR for the Stave repository.
9
+
10
+
Read `references/stave-release-checklist.md` for the exact sequence and repair rules.
11
+
12
+
## Workflow
13
+
14
+
1. Detect the repository root.
15
+
- Run `git rev-parse --show-toplevel` to find the repo root. Never assume a hardcoded path.
16
+
- All subsequent file reads and writes use this path as the base.
17
+
18
+
2. Inspect the release state before editing.
19
+
- Read `package.json` to load the current version.
20
+
- Run `git status --short` to confirm the working tree is clean (or note what is uncommitted).
21
+
- Run `git remote -v` and confirm `origin` exists.
22
+
- Run `git tag --list 'v*' --sort=-version:refname | head -5` to find the most recent semver tag. Incremental `conventional-changelog` generation depends on at least one prior tag.
23
+
- If no prior semver tag exists, stop and explain that a baseline `vX.Y.Z` tag is required before incremental changelog generation is safe.
24
+
25
+
3. Bump only the patch version.
26
+
- Increment `package.json` from `x.y.z` to `x.y.(z+1)`.
27
+
- Do not bump if the working tree already reflects the intended release version.
- Inspect the newly generated top section. If it is empty, heading-only, or missing meaningful bullets, automatically append a concise 3–7 bullet summary derived from the actual diff since the previous tag:
32
+
- Use `git diff --stat <prev-tag>..HEAD` and `git diff --name-only <prev-tag>..HEAD` as signals.
33
+
- Summarize user-visible or architecture-significant outcomes — not file lists.
34
+
- Update `README.md` and any other release-facing docs that changed as part of the shipped behavior so docs and changelog stay aligned.
35
+
- Review the generated notes before committing.
36
+
37
+
5. Verify before commit.
38
+
- Run `bun run typecheck` at minimum.
39
+
- Run focused tests for changed areas (`bun test` or `bun run test:ci` when scope is broad).
40
+
- Report any verification that could not run.
41
+
42
+
6. Stage and commit directly on the current branch (or in a worktree if the working tree is unclean).
43
+
- Stage: `git add -A`
44
+
- Commit with a Conventional Commit: `chore: release x.y.z`
45
+
- Do not amend a previously pushed release commit; always create a new commit.
46
+
47
+
7. Push the release branch and open a PR.
48
+
- Push to `origin`: `git push origin <branch>`
49
+
- Open a PR against `main` using `gh pr create --base main`.
50
+
- PR title: `chore: release x.y.z`
51
+
- PR body must include: a bullet summary of shipped changes, the verification commands run and their results, and the `🤖 Generated with Claude Code` footer.
52
+
-**Never push directly to `main`.** All releases land via PR.
53
+
54
+
8. Report the outcome.
55
+
- State the new version.
56
+
- State the release commit hash and message.
57
+
- State the PR URL.
58
+
- State which verification commands ran and their results.
59
+
- Note that GitHub Actions will build and publish release artifacts after the PR merges.
60
+
61
+
## Guardrails
62
+
63
+
-**Never push directly to `main`.** All releases land via PR.
64
+
- Never hardcode a repository path. Always derive it with `git rev-parse --show-toplevel`.
65
+
- Do not bump the version twice if the working tree already reflects the intended release.
66
+
- Do not create a non-Conventional commit.
67
+
- Do not hand-write release notes when `conventional-changelog` is the required path.
68
+
- Do not silently skip changelog review or release-facing doc updates when shipped behavior changed.
69
+
- Do not create a local semver tag before the PR is merged. Tag the merged `main` commit after merge.
70
+
- If verification fails, stop and surface the failure unless the user explicitly accepts releasing anyway.
0 commit comments