4 Commits
Author SHA1 Message Date
mr.zeroandClaude Opus 5 8511ccbef8 WarpEngine Client: the whole catalog, and a build that can point elsewhere
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline was successful
**The app is called WarpEngine Client.** "Store" named the thing it opens rather than the
thing you run, and the store is a catalog on a site, not a window on your machine. The
window title, the bundle, the packages and the menu entry follow; the repository already
did. The store being driven is named in the side menu, so the bar stopped repeating it as
a badge — the element stays in the page, hidden, because the window check reads it.

**Every title is listed, including the ones this machine cannot install.** They arrive
from the engine with `installable: false` and a reason, and they are drawn dimmed, with an
*unsupported platform* or *no build for this machine* badge, the engine's own sentence
underneath, and nothing to press: a disabled Install would invite a click that can never
work. They get a category of their own — *Not for this machine* — and they are kept out of
the native/hosted categories and counts, because a title with no build has no mode to be
counted under. An engine older than desktop 1.2.0 is unaffected: a missing `installable`
field reads as installable, which is what those engines mean.

**A build can be pointed at another site's registry:**

    make dist STORES_API=https://games.example.org/api/stores

BuildConfiguration reads the packaged package.json, where electron-builder's
extraMetadata writes that address, so a client for somebody else's catalog needs no source
change and nothing set on the user's machine. Precedence is runtime environment, then
build, then ours — three audiences, most specific first.

Also: the scrollbars are the window's own, because the platform's light track down the
side menu of a dark window looked like a mistake.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 19:45:54 +02:00
mr.zeroandClaude Opus 5 7026e0cc6a Publish from CI without a secret
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/tag/woodpecker Pipeline failed
Woodpecker hands every step a forge credential for cloning — an access token of the
repository's owner — and a one-off diagnostic in the check step confirmed it is there.
scripts/ci-upload.sh now uses it when no `gitea_token` secret is set, so publishing a
release needs nothing configured. Gitea takes such a credential as `token …` or
`Bearer …` depending on how Woodpecker was set up, so the script probes which of the two
`/user` accepts rather than assuming, and says which one it used.

The secret mapping is gone from the step as well: referencing a secret that does not
exist is a failure mode of its own, and the fallback is the normal path now. Adding a
`gitea_token` secret and mapping it back in is how you publish as somebody else.

Documents the release flow the pipeline now implements: push a vX.Y.Z tag, the pipeline
builds Linux and Windows and creates the release with them in it, and `make release` from
a Mac pushes the macOS package onto the same release. Either half can go first.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 17:15:58 +02:00
mr.zeroandClaude Opus 5 2f725fdd14 CI publishes the release itself
ci/woodpecker/push/woodpecker Pipeline is pending
ci/woodpecker/manual/woodpecker Pipeline was successful
The flow is now: a vX.Y.Z tag starts the pipeline, the pipeline creates the release with
the Linux and Windows packages in it, and the macOS package is pushed on top from a Mac
with make release. scripts/ci-upload.sh therefore creates the release when the tag has
none, taking its body from RELEASE_NOTES.md, instead of requiring one to exist.

Also carries a one-off diagnostic in the check step: whether Woodpecker hands steps a
forge credential of their own. If it does, the release step needs no secret.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 17:12:16 +02:00
mr.zeroandClaude Opus 5 526c67b069 Registry-only stores, a quieter window, and a CI that builds
ci/woodpecker/manual/woodpecker Pipeline was successful
A store no longer needs a repository of its own. The engine's built-in defaults
already cover the host-to-asset mapping, the install modes, the platforms and the
behaviour; what they cannot know is identity — a slug, a name and a catalog URL — and
that is exactly what a registry record carries. So `storeRepositoryUrl` is optional: a
record with a name and a catalog is a complete store, the id falls back from the
repository name to the catalog host (`teletypegames.org` becomes `teletypegames`) to the
display name, and the client writes a three-section config. Given a repository it still
reads it, and that file stays the authority on how the store behaves; a repository
without a config.json is treated as no repository at all.

Measured end to end against a local registry serving one record with a null repository:
the engine and the core downloaded, engine 1.1.0 accepted the written config, it listed
the same ten titles the configured store does, and a hosted title synced into a sandbox
with its menu entry written.

The "Install all" button is gone, and with it the string it used. Titles are installed
one at a time from their own cards.

No footer. The window carried a bar at the bottom at all times — a toggle and a line of
absolute paths — for something most sessions never need. The log is still there, folder
buttons included, behind a quiet switch at the bottom of the side menu; it takes no room
until it is opened, and an arriving line does not open it, because the store logs on
every refresh and a window that unfolds panels by itself is worse than one that keeps
quiet.

Three faults that every automated count had passed, found by photographing the setup
screen: the store badge rendered as an empty pill with no store open; the gate's picker
showed as an empty dropdown stub, because an explicit `display` beats the browser's own
`[hidden]` rule; and the gate went up while the empty-catalog line stayed on screen
underneath it. The last was a design fault — whether the gate is up was a call on a
view rather than state, so the two could disagree. The setup screen is now a field in
the state store, and that one field decides which of the gate and the grid is drawn.
The window test's gate assertion was wrong too: it demanded a store picker, which only
appears when the registry offers more than one store, so one store — the ordinary case —
failed it.

CI builds the packages this machine cannot. `.woodpecker.yaml` runs the checks on every
push and, on a tag or by hand, builds the Linux packages in
`electronuserland/builder:22` and the Windows ones in `:22-wine`, then attaches them to
the release with scripts/ci-upload.sh. The pipeline lives here rather than in the update
server's `/build/config` extension, which serves game-platform pipelines publishing into
the site's catalog — a different product with a different target. macOS stays a local
build: Apple's toolchain and its signing exist only on a Mac.

Both build steps verify what they produced, because a half-finished Wine build leaves a
162 KB stub named like the real installer and `ls` is happy with it. The Linux step was
rehearsed locally in the same image (AppImage 128 MB, deb 100 MB); the Wine step cannot
be rehearsed on Apple Silicon, where 16 KB host pages break Wine's 4 KB assumption, so
the runner is where it is proven. The size check was tested against both outcomes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 16:52:59 +02:00