2026-09-16 19:24:59 +02:00
|
|
|
name: halkyon_learn_flutter
|
|
|
|
|
description: A new Flutter project with Serverpod.
|
|
|
|
|
|
|
|
|
|
# The following line prevents the package from being accidentally published to
|
|
|
|
|
# pub.dev using `pub publish`. This is preferred for private packages.
|
|
|
|
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|
|
|
|
|
|
|
|
|
# The following defines the version and build number for your application.
|
|
|
|
|
# A version number is three numbers separated by dots, like 1.2.43
|
|
|
|
|
# followed by an optional build number separated by a +.
|
|
|
|
|
# Both the version and the builder number may be overridden in flutter
|
|
|
|
|
# build by specifying --build-name and --build-number, respectively.
|
|
|
|
|
# In Android, build-name is used as versionName while build-number used as versionCode.
|
|
|
|
|
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
|
|
|
|
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
|
|
|
|
# Read more about iOS versioning at
|
|
|
|
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
|
|
|
|
version: 1.0.0+1
|
|
|
|
|
|
|
|
|
|
environment:
|
|
|
|
|
sdk: '^3.13.0'
|
|
|
|
|
flutter: '^3.44.4'
|
|
|
|
|
|
|
|
|
|
resolution: workspace
|
|
|
|
|
|
|
|
|
|
dependencies:
|
2026-09-30 08:38:08 +02:00
|
|
|
# Our fork of the editor's main branch, moved to win32 v6 so the app can stay in the pub
|
|
|
|
|
# workspace. A local path until the fork is hosted; then a git URL pinned to a commit.
|
|
|
|
|
appflowy_editor:
|
|
|
|
|
path: ../../appflowy-editor
|
2026-09-16 19:24:59 +02:00
|
|
|
# The following adds the Cupertino Icons font to your application.
|
|
|
|
|
# Use with the CupertinoIcons class for iOS style icons.
|
feat(app): study with FSRS
A studyset's card list gains "Study". The study screen shows the front, then the answer and the four ratings, each labelled with when the card would come back; every rating is recorded with how long answering took, and the queue is worked out anew after each.
Schedules are never stored: scheduleOf replays a card's reviews in time order with FSRS-6 (fsrs v2.0.1, pinned exactly so every device on one app version computes the same). The package's fuzz can only be seeded through an API meant for tests, and due dates don't feed back into a card's state, so the replay runs without fuzz and fuzzedDays spreads the final due date over FSRS's range, picked by a stable FNV-1a fraction of the card's id and review count. studyQueue takes due cards earliest first, then new cards in studyset order, 20 per studyset and local day, and brings a learning card due within 20 minutes early when nothing else is due. Deleting a card deletes its reviews.
Tests: the replay (learning, growing intervals, the same schedule whatever order reviews arrive in, previews matching what a rating yields), the fuzz range, the queue (order, the daily limit counted per local day, learn-ahead), the repository, the session bloc under a controlled clock, the screen, and a sync test for ratings on two devices. AGENTS.md records the review log and scheduling, and how plugin lint rules are ignored.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 16:59:07 +02:00
|
|
|
clock: ^1.1.3
|
2026-09-16 19:24:59 +02:00
|
|
|
cupertino_icons: ^1.0.5
|
2026-09-30 08:38:08 +02:00
|
|
|
equatable: ^3.0.0
|
2026-09-16 19:24:59 +02:00
|
|
|
flutter:
|
|
|
|
|
sdk: flutter
|
feat(app): sign in anonymously on first launch
The app's first patterns. Dependencies (lib/src/core/dependencies) is the composition root, built at startup and handed down by DependenciesScope; it replaces the scaffold's global client and restores a stored session before the first frame, so a restart never creates a second anonymous account. AuthGateway with ServerpodAuthGateway is the boundary to the server's authentication, AuthRepository signs in anonymously when nobody is signed in, and SessionBloc (flutter_bloc) keeps a person signed in, also after signing out or a revoked session. SessionGate shows a spinner while signing in, offers to try again when that fails, and builds the app anew for every person. AccountButton explains that progress is saved on this device and asks before signing out of an anonymous account, which can't be restored. AppBlocObserver logs all blocs.
Tests: the repository, the bloc's sequences (a stored session is kept, a failed sign-in is retried, signing out starts anew), and the widgets, including that cancelling the sign-out keeps the account. test/support holds the fake gateway and testDependencies(). AGENTS.md describes the composition root and the test factory.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 09:04:02 +02:00
|
|
|
flutter_bloc: ^9.1.1
|
fix(app): GitHub sign-in on Linux and Windows waits for the browser
Signing in with GitHub on Linux ended in "Unable to connect" at 127.0.0.1:43823 after authorizing. flutter_web_auth_2 (v5.1.0, unchanged on its master) ends every pending sign-in when the app is resumed. That suits mobile, where coming back without finishing means giving up, but on the desktop the window regaining focus resumes the app, and the package's loopback server closed before GitHub sent the browser back. FluffyChat's issue #3341 and the package's #171 report the same.
The app now puts its own Linux and Windows implementation behind the package's platform interface (LoopbackWebAuth): the system browser and a loopback address, as RFC 8252 recommends, waiting until GitHub answers, the person cancels, or five minutes pass. It listens on 127.0.0.1 only and answers only the callback's path. Serverpod's PKCE and state check stay in use. There, the account dialog shows "Continue in your browser." with a Cancel button, and closing the dialog cancels the sign-in.
Serverpod (v4.0.3) reports a cancelled browser round trip as an unknown error, so the gateway knows a cancel by having asked for it. A cancel on GitHub's own page, or leaving the browser on Android, still reads as a failure; AGENTS.md says so.
The regression test drives the package's front through a change of focus. With the package's behaviour it fails with the same refused connection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 20:18:18 +02:00
|
|
|
# The app's own browser half of GitHub sign-in on Linux and Windows
|
|
|
|
|
# (LoopbackWebAuth) plugs in here, and opens the browser and brings the window
|
|
|
|
|
# back with the same packages flutter_web_auth_2 uses.
|
|
|
|
|
flutter_web_auth_2_platform_interface: ^5.0.0
|
feat(app): flashcards on append-only revisions
A studyset's screen lists its cards (reorderable; a marker on cards changed on two devices) and opens a card's screen with an editor for each side. Saving appends a revision whose parents are all current heads. mergeRevisions merges several heads per side against their newest common ancestor, as decided: different sides merge automatically, the same side changed differently is a conflict. The card screen then shows every version of that side with "Keep this", and saving is possible once each conflicted side is settled, which resolves the conflict for every device. Nothing is merged silently inside a side.
CardRepository watches a studyset's cards, creates at the end and moves by fractional index (fractional_indexing_dart, checked against the reference algorithm's test vectors), and deletes by blanking every revision first (ADR 0002, rule 2). Deleting a studyset now deletes its cards the same way before the studyset goes. Every person gets a CardRepository whose revisions name them as author. RichContent gains plainText for the list's previews.
Tests: the merge (chains, different and same sides, conflicts, resolving, three heads, missing parents, arrival order), the payload, the repository against a fake gateway, both blocs, and the widgets, including that cancelling a delete keeps the card. The sync tests, which need the running server, cover merging and conflicts across two devices and blank revisions on the server; their device helper is now shared in test/sync/support. AGENTS.md describes the revision pattern, the fractional order, and two tooling traps.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 14:41:44 +02:00
|
|
|
fractional_indexing_dart: ^1.0.7
|
feat(app): study with FSRS
A studyset's card list gains "Study". The study screen shows the front, then the answer and the four ratings, each labelled with when the card would come back; every rating is recorded with how long answering took, and the queue is worked out anew after each.
Schedules are never stored: scheduleOf replays a card's reviews in time order with FSRS-6 (fsrs v2.0.1, pinned exactly so every device on one app version computes the same). The package's fuzz can only be seeded through an API meant for tests, and due dates don't feed back into a card's state, so the replay runs without fuzz and fuzzedDays spreads the final due date over FSRS's range, picked by a stable FNV-1a fraction of the card's id and review count. studyQueue takes due cards earliest first, then new cards in studyset order, 20 per studyset and local day, and brings a learning card due within 20 minutes early when nothing else is due. Deleting a card deletes its reviews.
Tests: the replay (learning, growing intervals, the same schedule whatever order reviews arrive in, previews matching what a rating yields), the fuzz range, the queue (order, the daily limit counted per local day, learn-ahead), the repository, the session bloc under a controlled clock, the screen, and a sync test for ratings on two devices. AGENTS.md records the review log and scheduling, and how plugin lint rules are ignored.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 16:59:07 +02:00
|
|
|
# Pinned exactly: every device on one app version must compute the same
|
|
|
|
|
# schedules.
|
|
|
|
|
fsrs: 2.0.1
|
2026-09-16 19:24:59 +02:00
|
|
|
halkyon_learn_client:
|
|
|
|
|
path: ../halkyon_learn_client
|
2026-09-29 23:11:00 +02:00
|
|
|
material_ui: ^1.5.0
|
feat(server): studysets, the first synced table (migration pending)
Adopts serverpod_offline_sync v0.0.8 (ADR 0001): its module (nickname offline_sync) and the experimental database: sync in generator.yaml, its server and client packages, and overrides that keep the four Serverpod core packages on v4.0.2, since the package pins v4.0.0 exactly and the spike showed it works on v4.0.2. The app's new dependencies come along because the workspace shares one lock file.
Studyset is the first synced model. Its space owns it, so it has no owner column, and only the envelope is a column: keyId and nonce stay null (no end-to-end encryption; ADR 0002, rule 6), and payload holds the content as versioned UTF-8 JSON, so a new content field changes the payload's schema version instead of this table, whose every migration locks older app versions out of syncing (rule 3). The audience column of the original design is gone: it served key selection, and the engine's spaces decide who reads a row.
The generated server and client code is included. The migration isn't: it is created together with the move to Serverpod v4.0.3 and reviewed first, like the client's local migration (the client's lib/migrations is still empty).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 10:11:24 +02:00
|
|
|
path: ^1.9.1
|
|
|
|
|
path_provider: ^2.1.6
|
build: Serverpod v4.0.3
Moves every Serverpod package, and the four overrides for serverpod_offline_sync, from v4.0.2 to v4.0.3 before the first synced table's migration exists, so that migration is created on the version that stays.
v4.0.3 contains fixes only. Checked before moving: serverpod_database gained only backwards-compatible changes, none of which the sync package calls into. Server-side session keys are hashed as before (the cheaper argon2 applies to JWT refresh tokens, which we don't use), so no session ends. The auth module's profile image relation is now deferred, which fixes restoring a Postgres dump; step 7's migration carries that change.
argon2 now runs in serverpod_argon2 (BSD-3), a new dependency of the server only: a prebuilt, statically linked library that needs no glibc, bundled by dart build cli like the SQLite libraries, so the Docker build is unchanged. It doesn't reach the app.
The code generator still fails on Dart v3.13's primary constructors in endpoint files (tried again), so the server keeps the four syntax lints off. The regenerated test tools gain withServerpod's ephemeralDatabase option.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 10:42:34 +02:00
|
|
|
serverpod_auth_idp_flutter: 4.0.3
|
|
|
|
|
serverpod_flutter: 4.0.3
|
feat(server): studysets, the first synced table (migration pending)
Adopts serverpod_offline_sync v0.0.8 (ADR 0001): its module (nickname offline_sync) and the experimental database: sync in generator.yaml, its server and client packages, and overrides that keep the four Serverpod core packages on v4.0.2, since the package pins v4.0.0 exactly and the spike showed it works on v4.0.2. The app's new dependencies come along because the workspace shares one lock file.
Studyset is the first synced model. Its space owns it, so it has no owner column, and only the envelope is a column: keyId and nonce stay null (no end-to-end encryption; ADR 0002, rule 6), and payload holds the content as versioned UTF-8 JSON, so a new content field changes the payload's schema version instead of this table, whose every migration locks older app versions out of syncing (rule 3). The audience column of the original design is gone: it served key selection, and the engine's spaces decide who reads a row.
The generated server and client code is included. The migration isn't: it is created together with the move to Serverpod v4.0.3 and reviewed first, like the client's local migration (the client's lib/migrations is still empty).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 10:11:24 +02:00
|
|
|
serverpod_offline_sync_client: 0.0.8
|
fix(app): GitHub sign-in on Linux and Windows waits for the browser
Signing in with GitHub on Linux ended in "Unable to connect" at 127.0.0.1:43823 after authorizing. flutter_web_auth_2 (v5.1.0, unchanged on its master) ends every pending sign-in when the app is resumed. That suits mobile, where coming back without finishing means giving up, but on the desktop the window regaining focus resumes the app, and the package's loopback server closed before GitHub sent the browser back. FluffyChat's issue #3341 and the package's #171 report the same.
The app now puts its own Linux and Windows implementation behind the package's platform interface (LoopbackWebAuth): the system browser and a loopback address, as RFC 8252 recommends, waiting until GitHub answers, the person cancels, or five minutes pass. It listens on 127.0.0.1 only and answers only the callback's path. Serverpod's PKCE and state check stay in use. There, the account dialog shows "Continue in your browser." with a Cancel button, and closing the dialog cancels the sign-in.
Serverpod (v4.0.3) reports a cancelled browser round trip as an unknown error, so the gateway knows a cancel by having asked for it. A cancel on GitHub's own page, or leaving the browser on Android, still reads as a failure; AGENTS.md says so.
The regression test drives the package's front through a change of focus. With the package's behaviour it fails with the same refused connection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 20:18:18 +02:00
|
|
|
url_launcher: ^6.3.2
|
|
|
|
|
window_to_front: ^0.0.4
|
2026-09-16 19:24:59 +02:00
|
|
|
|
|
|
|
|
dev_dependencies:
|
feat(server): studysets, the first synced table (migration pending)
Adopts serverpod_offline_sync v0.0.8 (ADR 0001): its module (nickname offline_sync) and the experimental database: sync in generator.yaml, its server and client packages, and overrides that keep the four Serverpod core packages on v4.0.2, since the package pins v4.0.0 exactly and the spike showed it works on v4.0.2. The app's new dependencies come along because the workspace shares one lock file.
Studyset is the first synced model. Its space owns it, so it has no owner column, and only the envelope is a column: keyId and nonce stay null (no end-to-end encryption; ADR 0002, rule 6), and payload holds the content as versioned UTF-8 JSON, so a new content field changes the payload's schema version instead of this table, whose every migration locks older app versions out of syncing (rule 3). The audience column of the original design is gone: it served key selection, and the engine's spaces decide who reads a row.
The generated server and client code is included. The migration isn't: it is created together with the move to Serverpod v4.0.3 and reviewed first, like the client's local migration (the client's lib/migrations is still empty).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 10:11:24 +02:00
|
|
|
fake_async: ^1.3.3
|
2026-09-16 19:24:59 +02:00
|
|
|
# Used for agents to drive the app through the Dart MCP
|
|
|
|
|
flutter_driver:
|
|
|
|
|
sdk: flutter
|
|
|
|
|
flutter_test:
|
|
|
|
|
sdk: flutter
|
fix(app): GitHub sign-in on Linux and Windows waits for the browser
Signing in with GitHub on Linux ended in "Unable to connect" at 127.0.0.1:43823 after authorizing. flutter_web_auth_2 (v5.1.0, unchanged on its master) ends every pending sign-in when the app is resumed. That suits mobile, where coming back without finishing means giving up, but on the desktop the window regaining focus resumes the app, and the package's loopback server closed before GitHub sent the browser back. FluffyChat's issue #3341 and the package's #171 report the same.
The app now puts its own Linux and Windows implementation behind the package's platform interface (LoopbackWebAuth): the system browser and a loopback address, as RFC 8252 recommends, waiting until GitHub answers, the person cancels, or five minutes pass. It listens on 127.0.0.1 only and answers only the callback's path. Serverpod's PKCE and state check stay in use. There, the account dialog shows "Continue in your browser." with a Cancel button, and closing the dialog cancels the sign-in.
Serverpod (v4.0.3) reports a cancelled browser round trip as an unknown error, so the gateway knows a cancel by having asked for it. A cancel on GitHub's own page, or leaving the browser on Android, still reads as a failure; AGENTS.md says so.
The regression test drives the package's front through a change of focus. With the package's behaviour it fails with the same refused connection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 20:18:18 +02:00
|
|
|
# A test drives sign-in through its front, as Serverpod's GitHub sign-in does.
|
|
|
|
|
flutter_web_auth_2: ^5.1.0
|
test(app): studysets synced against a running server
The first tests that need serverpod start running (ADR 0001, rule 9: the client's and the server's sync engines can't share one process), tagged requires-server: tool/check.sh skips them, flutter test -t requires-server runs them. Every device is its own client and local database with the app's real gateway and repository, and syncs only when a test says so.
They state: two devices of one person end up with the same studysets; a deleted studyset leaves the other devices, and its payload is blank on the server, checked with SQL against the development database because the engine keeps deleted rows; a studyset written into another person's space never reaches them; claiming another person's space shows none of their studysets, since the server sends only the spaces the signed-in person has access to. As written here, the forgery test also expects the server to refuse and log the write, and the SQL checks connect over TCP; the first run against the server corrected both (see the commit "the sync tests pass against the running server").
They live in the app package: the server's Docker build resolves its dependencies with only the server package present, so a dev dependency on the client package would break it. They never initialize a Flutter test binding, which would replace real HTTP with a mock. Without a server they fail at sign-in with "connection refused".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 12:15:30 +02:00
|
|
|
# The sync tests (test/sync/) sign in like the app and read the server's database.
|
|
|
|
|
postgres: ^3.5.16
|
|
|
|
|
serverpod_auth_core_client: 4.0.3
|
|
|
|
|
yaml: ^3.1.4
|
2026-09-16 19:24:59 +02:00
|
|
|
|
|
|
|
|
dependency_overrides:
|
|
|
|
|
flutter_secure_storage: ^10.0.0
|
|
|
|
|
|
|
|
|
|
# For information on the generic Dart part of this file, see the
|
|
|
|
|
# following page: https://dart.dev/tools/pub/pubspec
|
|
|
|
|
|
|
|
|
|
# The following section is specific to Flutter.
|
|
|
|
|
flutter:
|
|
|
|
|
|
|
|
|
|
# The following line ensures that the Material Icons font is
|
|
|
|
|
# included with your application, so that you can use the icons in
|
|
|
|
|
# the material Icons class.
|
|
|
|
|
uses-material-design: true
|
|
|
|
|
|
|
|
|
|
# To add assets to your application, add an assets section, like this:
|
|
|
|
|
# assets:
|
|
|
|
|
# - images/a_dot_burr.jpeg
|
|
|
|
|
# - images/a_dot_ham.jpeg
|
|
|
|
|
|
|
|
|
|
# An image asset can refer to one or more resolution-specific "variants", see
|
|
|
|
|
# https://flutter.dev/assets-and-images/#resolution-aware.
|
|
|
|
|
|
|
|
|
|
# For details regarding adding assets from package dependencies, see
|
|
|
|
|
# https://flutter.dev/assets-and-images/#from-packages
|
|
|
|
|
assets:
|
|
|
|
|
- assets/config.json
|
|
|
|
|
|
|
|
|
|
# To add custom fonts to your application, add a fonts section here,
|
|
|
|
|
# in this "flutter" section. Each entry in this list should have a
|
|
|
|
|
# "family" key with the font family name, and a "fonts" key with a
|
|
|
|
|
# list giving the asset and other descriptors for the font. For
|
|
|
|
|
# example:
|
|
|
|
|
# fonts:
|
|
|
|
|
# - family: Schyler
|
|
|
|
|
# fonts:
|
|
|
|
|
# - asset: fonts/Schyler-Regular.ttf
|
|
|
|
|
# - asset: fonts/Schyler-Italic.ttf
|
|
|
|
|
# style: italic
|
|
|
|
|
# - family: Trajan Pro
|
|
|
|
|
# fonts:
|
|
|
|
|
# - asset: fonts/TrajanPro.ttf
|
|
|
|
|
# - asset: fonts/TrajanPro_Bold.ttf
|
|
|
|
|
# weight: 700
|
|
|
|
|
#
|
|
|
|
|
# For details regarding fonts from package dependencies,
|
|
|
|
|
# see https://flutter.dev/custom-fonts/#from-packages
|