nandi/frqpublic Fork 0
ec5b47d7dfcbe057abdcd1a62dcc6c99dc76a815
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

CLAUDE.md · 111 lines · 5.2 KBmarkdown Blame HistoryRaw
Read the clock in the reader's zone when /etc/localtime is a file bffe879 nandi 18d ago1# Working in this repo
2
3## Nix
4
Build the window somewhere with room for it 1451151 nandi 5d ago5**STOP BUILDING LOCALLY. Build on Modal.** This machine is for editing and for
6evaluating — `nix flake check`, `nix eval`, `nix build --dry-run`, `nix repl`
7— and not for realising a derivation. A local `nix build .#frq` gets killed for
8memory long before it finishes, and the minutes spent finding that out are
9minutes not spent on the change. So:
Read the clock in the reader's zone when /etc/localtime is a file bffe879 nandi 18d ago10
11```bash
Point the docs at .modal/, and at the file they now build 972ab37 nandi 5d ago12modal run .modal/frq/container.py # .#appimage, on Modal
Read the clock in the reader's zone when /etc/localtime is a file bffe879 nandi 18d ago13```
14
Point the docs at .modal/, and at the file they now build 972ab37 nandi 5d ago15The container is `.modal/`, not a fourth source tree: it is CI config that
16happens to live here, the way `.github/` would be.
17
Build the window somewhere with room for it 1451151 nandi 5d ago18`--dry-run` locally to see what *would* be built, then hand the build to Modal.
19The one exception is a derivation you already know is trivial and already
20substitutable; if you are unsure, it is not the exception.
21
22`modal app logs` is no substitute for watching that command: it resolves
23deployed apps by name, not the ephemeral one a `modal run` creates, and carries
24nothing until the Sandbox starts — the image build streams to the client and
25nowhere else.
26
27You are already running inside the Arch distrobox, where `nix` lives, so run
28the evaluating commands directly — do not wrap them in `distrobox enter`.
29
30The container runs as a Modal **Sandbox on a real VM**, which is what makes
31`nix build` work out there at all: the ptyshim that used to stand in for a
32working pty under gVisor is deprecated, and nothing here should reintroduce it.
33Substitution comes from the `nix-cache` Modal Volume plus cache.nixos.org and
34nix-cache.wasix.org — libjoltcosmic's dependency tree is the one that makes
35that cache worth having.
36
37A remote builder (`eu.nixbuild.net`) is also configured here, for the case
38where you want the graph built somewhere other than Modal: `--store
39ssh-ng://eu.nixbuild.net --eval-store auto` rather than a `builders` entry, so
40the whole graph stays there and only .drv files go up.
Read the clock in the reader's zone when /etc/localtime is a file bffe879 nandi 18d ago41
Follow the xorg renames, and stop wrapping nix in distrobox a400a00 nandi 16d ago42One thing this container is *not* representative of: `/etc/localtime` is a
43regular file here rather than a symlink, so anything that reads the zone out
Read the clock in the reader's zone when /etc/localtime is a file bffe879 nandi 18d ago44of its path sees nothing. That is a real deployment shape, not an artefact —
45frq.clock handles it.
Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago46
Build the window somewhere with room for it 1451151 nandi 5d ago47## Never pipe a long task through `tail`
48
49`tail` and `head` do not emit anything until their input ends, so a build, a
50test run or a deploy piped through one shows nothing at all until it is over —
51and if it is killed or times out first, its output is lost with it. That is the
52opposite of what you want from the commands that take longest.
53
54Let them write to the terminal, or `tee` them if you want a copy to grep
55afterwards:
56
57```bash
Point the docs at .modal/, and at the file they now build 972ab37 nandi 5d ago58modal run .modal/frq/container.py 2>&1 | tee /tmp/frq-build.log
Build the window somewhere with room for it 1451151 nandi 5d ago59```
60
61Trim afterwards, on the file, where the whole run is still there to re-read.
62The same goes for `grep` and `awk` in a live pipeline: they buffer when their
63output is not a terminal, so pass `--line-buffered` / `fflush()` or watch the
64file instead.
65
Split the tree three ways, and let the phone be Flutter's 7070931 nandi 7d ago66## The three source trees
67
68```
69common/ .cljc jolt AND ClojureDart
70src/ .clj jolt only
71flutter/ .cljd ClojureDart only
72```
73
74The extension is the boundary, not a convention: ClojureDart reads `.cljd` and
75`.cljc` and never `.clj`, jolt reads all three. So the rule for anything under
76`common/` is that it may not require `jolt.*`, `glimmer*` or a `dart:` library
77— if it needs the host, it asks `frq.io`, and the backend that installed itself
78answers. `frq.io.jolt` is required for its side effect by `frq.app`;
79`frq.io.dart` is installed by `flutter/src/frq/main.cljd`, which has to await
80the storage directory first.
81
82Adding a host call means adding it to the seam in `common/frq/io.cljc` and to
83both implementations. Name it for the result rather than the mechanism — the
84seam has `write-private-file!` and not a chmod, because Dart has no chmod.
85
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 7d ago86`flutter/` builds two things, from one `clojure -M:cljd compile`:
87
88`just apk`, out of the flake's own `.#flutter` shell (clojure, jdk17, flutter)
89and its `.#android-sdk` package. Impure on purpose: Gradle fetches its own
90dependencies and writes into `ANDROID_HOME`, so the recipe copies the store SDK
91to `flutter/.home` and lets it finish there. It is the only APK there is — the
92jolt APK, `nix/android.nix`, `android/` and the `.#apk` outputs are gone,
93because every backend that APK could paint with is retired.
94
95`just flutter-desktop`, out of `.#flutter-desktop` (the same clojure and
96flutter, with cmake, ninja, pkg-config and gtk3 where the JDK and the SDK are).
97Impure for the network half of the same reasons and no writable-SDK dance, since
Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 7d ago98nothing writes into the store. nixGL off NixOS, like `just cosmic run`.
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 7d ago99
Name the libcosmic recipe for its backend: `just cosmic run` 5ba9382 nandi 7d ago100So there are two desktop GUIs and they are both first-class: `just cosmic
101run` is libcosmic under jolt, `just flutter-desktop` is Flutter's Linux target
102over
Paint the desktop with Flutter too, beside libcosmic fc5f63c nandi 7d ago103`frq.hiccup`. Same screens out of `common/frq/screens/`, two renderers. jvui and
104Vidya were experiments and are gone; libcosmic is a desktop window and does not
105cross to a phone, which is what the Flutter half is for.
106
107The consequence for `common/` is that "the phone" is no longer a synonym for
108"the ClojureDart side" — two targets compile it. An implementation that branches
109on the platform has to ask (`Platform.isAndroid`) rather than assume; see
110`frq.io.dart/write-private-file!`, where assuming cost a token its file mode.
111See flutter/README.md.