Skip to content

Migrate to GTKX 1.6, fix unit conversion, add home-use limits - #1

Merged
tduarte merged 4 commits into
mainfrom
claude/init-5c91e8
Oct 3, 2026
Merged

tduarte merged 4 commits into
mainfrom
claude/init-5c91e8

Conversation

@tduarte

@tduarte tduarte commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Why

pnpm install no longer works on main. The pinned @gtkx/react@0.11.1 depends on @gtkx/ffi, and every version of that package has been removed from npm. GTKX is now at 1.6, where @gtkx/ffi became @gtkx/runtime, and the API changed enough that this is a port rather than a version bump.

What changed

App (src/app.tsx, src/utils/calculations.ts)

  • Ported to the GTKX 1.6 API. Bindings are generated per project (@gtkx/gi/*, @gtkx/jsx/*) by gtkx codegen.
  • Preferences and About now use AdwPreferencesDialog and AdwAboutDialog instead of separate portaled windows.
  • The header bar menu is a GMenu driven by win.preferences/win.about actions. Ctrl+, is registered as an app accelerator.
  • The brew method is a ComboRow that shows the ratio as its subtitle. Coffee and water are AdwSpinRows.
  • Unit conversion fix: coffee weight in grams is now the only stored value, and everything on screen is derived from it. Switching units converts the amounts (30 g ↔ 1.06 oz) without drift. Before, the raw number was kept, so 20 g became 20 oz.
  • Home-use limits: each method has a maximum water volume (MAX_WATER_ML). The coffee maximum is derived from it through the ratio, so the two rows never clamp out of sync:
    • Espresso: 60 ml / 30 g
    • Pour Over: 1200 ml / 80 g
    • French Press: 1500 ml / 125 g
    • AeroPress: 500 ml / 45 g
  • Changing method clamps the coffee to the new limit. The water +/- step is now 5 ml (0.25 fl oz).
  • Removed leftover debug fetch() calls that posted app state to 127.0.0.1:7242.

Tooling and packaging

  • gtkx.config.ts replaces the app ID in package.json. The scripts are now pnpm dev, typecheck, build and build:flatpak.
  • gtkx deploy --target flatpak generates the manifest, desktop entry and metainfo, and bundles Node. This replaces:
    • the hand-written flatpak/ manifest and its @gtkx/native wrapper
    • the SEA scripts, scripts/bundle.ts, src/dev.tsx and tsconfig.app.json
  • The runtime is now GNOME 50, because GTKX 1.x needs GTK 4.20 and Adwaita 1.8. Icons moved to data/icons/ in the hicolor layout.
  • vite.config.ts excludes build/ from the dev watcher. The Flatpak build tree contains symlink loops that ran gtkx dev out of memory.
  • CI now uses Node 24, runs the typecheck, and builds with pnpm build:flatpak in the gnome-50 container.
  • Fixed stale monorepo paths in run-dev.sh and the README. tsconfig.app.tsbuildinfo is no longer tracked.
  • Added CLAUDE.md. AGENTS.md is generated by gtkx codegen, which recommends committing it.

Flatpak releases (added later in this PR)

Ported the release flow from tduarte/Scribe. Pushing a v* tag that matches package.json's version runs .github/workflows/release.yml, which:

  1. builds the tag with gtkx deploy;
  2. GPG-signs the OSTree repo with build-aux/publish-repo.sh;
  3. publishes the repo to GitHub Pages, along with a .flatpakref, a .flatpakrepo and a landing page;
  4. attaches the .flatpak bundle to the GitHub release.

Tested locally with a throwaway key. Installing from the served .flatpakref into a scratch FLATPAK_USER_DIR worked, with gpg-verify=true and gpg-verify-summary=true, and flatpak update and remote-ls worked against it. One-time setup is still needed before the first tag (see docs/RELEASING.md):

  • add the FLATPAK_GPG_PRIVATE_KEY secret;
  • enable Pages with GitHub Actions as the source;
  • add a v* tag rule to the github-pages environment.

The CI workflow also got a fix: SWC's native addon refused the container's world-writable HOME as its cache root, so caches now go under /root/.cache.

Testing

  • pnpm typecheck and pnpm build pass.
  • pnpm build:flatpak built build/out/io.github.tduarte.cafe-1.0.0-x86_64.flatpak (26 MiB) locally. The bundle has not been installed or run.
  • I drove the running app through the GTKX MCP server:
    • Calculation works in both directions.
    • The menu opens both dialogs, which also close correctly.
    • Pour Over limits hold at both ends (0 and 80 g ↔ 1200 ml).
    • Switching to French Press or Espresso keeps or clamps the coffee correctly.
    • Metric → Imperial → Metric comes back exactly (30.0 g / 60 ml).

Reviewer notes

  • CI is unverified. The new workflow has only been written, not run. Watch the first run on this PR.
  • Changing units or method rebuilds the spin rows (key). This is deliberate: otherwise GTK can apply the new value before the new bounds, clamp it, and report it back as a user edit. The comments in app.tsx and CLAUDE.md explain it.

🤖 Generated with Claude Code

tduarte and others added 4 commits October 3, 2026 13:00
The pinned @gtkx/react 0.11.1 depends on @gtkx/ffi, which has been
removed from npm, so dependencies could no longer install.

- Port the app to GTKX 1.6: generated @gtkx/gi/@gtkx/jsx bindings,
  gtkx.config.ts, and gtkx dev/build/codegen/deploy. Preferences and
  About become AdwPreferencesDialog/AdwAboutDialog, the header menu is
  a GMenu driven by window actions, and the inputs are AdwSpinRows.
- Replace the hand-written Flatpak manifest, native shim and SEA
  scripts with `gtkx deploy --target flatpak` (GNOME 50 runtime, since
  GTKX needs GTK 4.20). Update CI to Node 24.
- Keep coffee weight in grams as the single source of truth so
  switching units converts the amounts losslessly instead of keeping
  the raw number (20 g used to become 20 oz).
- Add per-method home-use limits (MAX_WATER_ML); the coffee limit is
  derived through the ratio so both rows always agree.
- Remove leftover debug fetch() logging to 127.0.0.1:7242.
- Exclude build/ from the dev watcher; the Flatpak build tree has
  symlink loops that ran the dev server out of memory.
- Fix stale monorepo paths, untrack tsconfig.app.tsbuildinfo, and add
  CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GitHub sets HOME=/github/home inside job containers, under a
world-writable /github. The SWC native addon (used by gtkx codegen)
refuses that as a cache root (ERR_SWC_NATIVE_CACHE), failing the
typecheck step. Point XDG_CACHE_HOME and SWC_NATIVE_BINDING_CACHE at
/root/.cache instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port the release flow from tduarte/Scribe. Pushing a v* tag that
matches package.json builds it with gtkx deploy, GPG-signs the OSTree
repo (app commit, summary and appstream), and publishes it as a
Flatpak repository on GitHub Pages with a .flatpakref, .flatpakrepo
and landing page; the .flatpak bundle is attached to the GitHub
release.

- .github/workflows/release.yml, build-aux/publish-repo.sh,
  build-aux/pages/index.html
- docs/RELEASING.md: one-time setup (signing key secret, Pages, v* tag
  deployment rule) and how to cut a release
- Pin the Flatpak branch to "stable" in gtkx.config.ts
- Refresh assets/Screenshot.png with the GTKX 1.6 UI

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gtkx codegen reads GTK's GIR files from the host, and the
flatpak-github-actions container has none, so the typecheck failed
with "GIR file Gtk-4.0.gir not found". Install the GNOME 50 Platform
and SDK into the user installation that gtkx deploy builds from, and
point codegen at the SDK's gir-1.0 through a new GTKX_GIR_PATH
override in gtkx.config.ts (local development keeps the host
default). Also disable rofiles-fuse, which CI containers often lack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tduarte
tduarte merged commit fb6032c into main Oct 3, 2026
2 checks passed
@tduarte
tduarte deleted the claude/init-5c91e8 branch October 3, 2026 20:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant