Building and releasing
Locally
npm install npm run typecheck # types npm run test:unit # the fast suite — no model, no ffmpeg npm run build # compile main, preload and renderer npm run dist # build an installer into release/
npm run dist produces release/Capra-<version>-setup.exe on Windows and an AppImage on Linux. About 110 MB, most of which is Electron.
The test suites
| Suite | What it needs | Runs in CI |
|---|---|---|
npm run test:unit | nothing | yes |
npm run test:integration | a local model server, ffmpeg, a sample video | no |
The integration suite skips itself when there is no model server, which on CI is always — so running it there would report a pass having executed nothing. That is worse than not running it.
Two of the unit tests are worth knowing about because they fail for reasons that look like unrelated breakage:
sources.test.tsscans every source file for invisible characters. A backspace or
a stray control character in a regex will fail it, and that is the point: they are invisible in an editor and produce nonsense at runtime.
ipc-contract.test.tscompares the declared IPC channels against the registered
handlers, and against what the renderer actually calls. A channel with no handler, a handler nobody calls, an event nothing emits — all fail here rather than at runtime.
CI
.github/workflows/ci.yml runs typecheck and the unit suite on every push and pull request. One runner: there are no native npm dependencies, persistence is node:sqlite from Electron's own runtime, and running an identical suite on three operating systems says nothing that one run does not.
Releases
.github/workflows/release.yml builds installers for Windows and Linux on a tag (v*), and on demand from the Actions tab. A tag drafts a GitHub release with the artifacts attached; a manual run just leaves them to download.
git tag v0.2.0 git push origin v0.2.0
Why there is no macOS build
An unsigned, unnotarised .dmg is refused on arrival by every recent macOS. Signing needs a paid Apple developer certificate this project does not have, and shipping one anyway would mean handing somebody a file their own operating system tells them is broken.
The target is left in electron-builder.yml, so npm run dist on a Mac produces a working local build. It simply is not published.
What is not bundled
FFmpeg. It is large, its licensing varies by build, and most people working with video already have one they trust. Capra finds it on PATH and says so plainly when it cannot. To pin a build, drop it in resources/ffmpeg before packaging — anything there wins over PATH.
Fonts are bundled, and are not optional: PDF's built-in Courier is WinAnsi and cannot encode ı, ş, ğ, ż or ő, so without Courier Prime every PDF export of a non-English screenplay would throw.