No description
  • Dart 78.6%
  • PLpgSQL 19.3%
  • Kotlin 1.1%
  • C++ 0.4%
  • CMake 0.2%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Tizian 「ティツィアーン」 8c70ad98a1
feat(app): an authenticator's key copied, marked sensitive, and its code six digits
A phone without a camera whose authenticator doesn't open otpauth: had no
way but typing the key. It is copied again, the key alone (ADR 0017
amended, the developer's decision of 3 Nov 2026): on Android through each
app's SensitiveClipboard.kt, marked EXTRA_IS_SENSITIVE, so Gboard and the
system show no preview and keep it out of their histories; elsewhere through
Flutter's clipboard. Emptied 60 seconds later if the clipboard still holds
it. The recovery phrase and codes stay never copied.

The code's field counted "/7", taking an optional space for a seventh
character: it now takes six digits alone, a pasted space dropped, and counts
nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-11-04 09:32:01 +01:00
.forgejo/workflows build(ci): the deploy step is named for the instance, which it deploys whole, not learn.halkyon.eu alone 2026-11-03 00:28:38 +01:00
.vscode build: Melos, a Dart check and every path for the single repository 2026-10-22 18:11:04 +02:00
apps feat(app): an authenticator's key copied, marked sensitive, and its code six digits 2026-11-04 09:32:01 +01:00
deploy build(deploy)!: compose.yaml's link goes, now learn.halkyon.eu's .env names compose.learn.yaml 2026-11-03 00:28:33 +01:00
docs/adr feat(app): an authenticator's key copied, marked sensitive, and its code six digits 2026-11-04 09:32:01 +01:00
packages feat(app): an authenticator's key copied, marked sensitive, and its code six digits 2026-11-04 09:32:01 +01:00
snap feat(icons): every icon fades from cobalt into its app's backdrop; Learn shows its own inside the app; Train's dumbbell (ADR 0031, D5 to D7) 2026-11-02 23:12:20 +01:00
test fix(release): every snap packed without --output, into its project, then moved 2026-11-04 09:31:54 +01:00
tool feat(meditate): the app: Today, Explore, Profile, the sitting and its bells 2026-11-04 09:31:56 +01:00
.dockerignore build(todo): Todo deployable beside Learn's server, and released as an APK, on F-Droid and as a snap (ADR 0033, step 5) 2026-11-02 16:04:00 +01:00
.gitignore feat(deploy): Jellyfin at home, published through WireGuard (ADR 0032) 2026-10-30 23:17:57 +01:00
AGENTS.md refactor(app): the device's speech recognition moves from Learn into halkyon_app, with dictation into a text 2026-11-04 09:31:58 +01:00
analysis_options.yaml chore(lint): LeanCode's strict rules and a pre-push check 2026-09-29 23:06:29 +02:00
CLAUDE.md chore: scaffold the Serverpod 4 build 2026-09-24 15:32:29 +02:00
CONTRIBUTING.md docs: one repository for every app and shared package (ADR 0015) 2026-10-22 18:11:04 +02:00
LICENSE.md feat(train): setting up and keeping the Polar Loop (ADR 0030, D34–D36) 2026-10-30 15:52:55 +01:00
pubspec.lock feat(learn): the assistant's field laid out as Claude's, with files attached and questions spoken, and no Check (ADR 0021, D67) 2026-11-02 08:46:37 +01:00
pubspec.yaml feat(meditate): the app: Today, Explore, Profile, the sitting and its bells 2026-11-04 09:31:56 +01:00
README.md build: CI and the snap build with Flutter v3.47.8, as the laptop does 2026-10-30 17:43:24 +01:00

Halkyon

Halkyon's apps and the packages they share, in one repository. Each app is a Flutter app for Linux, Windows, macOS, Android and iOS with a Serverpod server of its own, offline-first, and anyone may run an instance of it: the apps, the servers and everything needed to host an instance are published.

App What it is Where
Halkyon Learn Creating, sharing and studying study material, flashcards scheduled with FSRS apps/learn/, at learn.halkyon.eu
Halkyon Todo To-dos; for now a shell on the shared packages: sign-in, instances, the account apps/todo/
Halkyon Train Running, cycling and rowing (ADR 0030); for now a shell on the shared packages apps/train/

Halkyon Meditate is to follow.

Layout

  • apps/<app>/: each app's server, generated client and Flutter app.
  • packages/: what the apps share, taken by path: halkyon_ui (the look: theme, bundled Noto Sans, layout, shared widgets), halkyon_app (instances, signing in, each person's data and its sync), halkyon_base (what every server has, as a Serverpod module with its generated client halkyon_base_client: signing in, the account and its deletion, the pruning, the instance's basics), halkyon_core (low-level primitives) and halkyon_interop (contracts between apps).
  • deploy/: what runs an instance (Docker Compose: Caddy, the server, PostgreSQL), learn.halkyon.eu's today.
  • tool/: the checks, the pre-push hook and the release scripts. docs/adr/: the decisions and their reasons.

One pub workspace holds every package: one pubspec.lock, one version of each dependency. Melos runs scripts across them.

Getting started

  • Flutter v3.47.8, the version CI uses (FLUTTER_VERSION in .forgejo/workflows/ci.yaml), with each platform you build for set up by Flutter's own guides; what an app needs beyond that is in its README.
  • The Serverpod CLI v4.0.4: dart install serverpod_cli@4.0.4. Pass --no-analytics to every call; otherwise it reports the commands run to Serverpod.
  • A C++ compiler, for flutter test too: a dependency of Learn's compiles MeCab as it builds.
flutter pub get                               # every package of the workspace
dart run melos list                           # the packages
ln -s ../../tool/pre-push .git/hooks/pre-push # the checks before every push
dart run tool/check.dart                      # format, analysis, every package's tests

dart run tool/check.dart --changed-since=origin/main tests only what changed since main and what depends on it; dart run melos run test:flutter --scope=<package> one package's Flutter tests. Each server's tests start an embedded PostgreSQL (no Docker) and need test passwords in the server's git-ignored config/passwords.yaml (the module's README and each app's say which). How the code is organised and the rules it follows are in AGENTS.md and each app's own.

Licences

The servers and the server module are under the Server Side Public License 1.0, the apps, the client packages and the other shared packages under the GNU Affero General Public License 3.0 or later. LICENSE.md says which covers what, CONTRIBUTING.md how to contribute.