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