# The Halkyon project: every app and the packages they share, one pub workspace. # # `_` is the conventional name of a pub workspace's root, which is never published or # imported, so the naming lint doesn't apply to it. name: _ # ignore: package_names publish_to: none environment: sdk: '^3.13.0' # Every package of every Halkyon app and the packages they share (ADR 0015): one # resolution, one lockfile, one version of each dependency across the apps. workspace: - apps/learn/halkyon_learn_client - apps/learn/halkyon_learn_server - apps/learn/halkyon_learn_flutter - apps/learn/halkyon_learn_curator - apps/meditate/halkyon_meditate_client - apps/meditate/halkyon_meditate_server - apps/meditate/halkyon_meditate_flutter - apps/todo/halkyon_todo_client - apps/todo/halkyon_todo_server - apps/todo/halkyon_todo_flutter - apps/train/halkyon_train_client - apps/train/halkyon_train_server - apps/train/halkyon_train_flutter - packages/halkyon_app - packages/halkyon_base_client - packages/halkyon_base_server - packages/halkyon_core - packages/halkyon_editor - packages/halkyon_interop - packages/halkyon_keys - packages/halkyon_llm - packages/halkyon_oidc_client - packages/halkyon_oidc_flutter - packages/halkyon_oidc_server - packages/halkyon_ui - packages/halkyon_ui/example dev_dependencies: # The checks' own Dart SDK for the images (tool/check.dart), unzipped. archive: ^4.3.0 # The tools' (tool/check.dart, tool/release.dart) options, and their tests (test/). args: ^2.7.0 # The release tool's checksums, its calls to Forgejo's API, and the pubspecs it reads. crypto: ^3.0.7 http: ^1.6.0 # Referenced by analysis_options.yaml in this directory. leancode_lint: ^27.0.0 # Runs scripts across the workspace's packages (`melos:` below): `dart run melos …`. melos: ^8.9.0 path: ^1.9.1 test: ^1.31.1 yaml: ^3.1.4 dependency_overrides: # Learn's flutter_launcher_icons (0.14.4, its latest, from June 2025) asks for # cli_util ^0.4.1, Melos for 0.5 or later. Of cli_util it uses only the logger # (`Logger.standard`, `Logger.verbose`, `Ansi`, `Progress`), the same in 0.5.2. # Drop this once flutter_launcher_icons allows 0.5. cli_util: ^0.5.2 # Two Android plugins patched for Kotlin built into the Android Gradle # plugin (android.builtInKotlin=true, which every app sets since 4 Nov # 2026): their latest releases still apply the Kotlin Gradle plugin # themselves, which Flutter warns will fail builds. Only android/build.gradle # differs from the release (third_party/README.md); drop each override once # its plugin's own release has migrated. flutter_web_auth_2 is # halkyon_oidc_flutter's, keyboard_height_plugin appflowy_editor's (Learn's # notes). flutter_web_auth_2: path: third_party/flutter_web_auth_2 keyboard_height_plugin: path: third_party/keyboard_height_plugin # The offline sync package's shared part from our fork: v0.0.10 with eight # changes. Byte payloads compared as bytes: v0.0.10 compares them byte by byte # through a UUID parse that throws for each byte, so a sync touching a few thousand # cards kept the server busy for minutes, answering nobody, while its client timed # out and sent everything again (2026-10-12). onInboundMerge, called only when # changes from the remote peer were merged: onMergeSuccess fires for a space this # device only pushed to, so every repository read everything again after each # save's sync (2026-10-17). A local delete, and a merge only inserting new rows # or only deleting rows, skip the foreign key projection pass when they can't # change it: the pass loaded nearly every synced row, 8 s for one delete and 9.5 s # for each rating another device made, in a library of 8,000 cards (2026-10-17). # Such a merge writes its new rows up to 1,000 to a statement: a first push of # that library took the server 35 s, now 5 (2026-10-17). And projections are # rebuilt once after the synced tables changed, not on every session and merge # (upstream #150). The changes a device lacks are collected with their rows read # 500 to a statement per table, not one statement each: a new device's first sync # of a library of 56,000 rows kept halkyon.li's server busy some 100 s, sending # nothing, so the client closed the stream after 40 s and started over # (2026-11-09). The server hands each change out as it is read, so a device hears # from it before the whole collection is read (2026-11-11). A write without a # transaction acts in the space it touches, and a host names where a new row goes # (`newRowSpace`), for spaces people share (ADR 0044, D24; 2026-11-11). Pinned to a # signed commit of the fork's branch halkyon/space-writes (on # halkyon/streamed-collection, on halkyon/batched-row-reads, on # halkyon/batch-inserts, on halkyon/fast-merge-deletes, on halkyon/fast-merges, on # halkyon/fast-deletes, on halkyon/inbound-merges, on halkyon/byte-payloads); drop # each change once a release of the package has it. serverpod_offline_sync: git: url: https://code.halkyon.app/project-halkyon/serverpod-offline-sync.git path: packages/serverpod_offline_sync ref: 845fb557db3e21cf78b152f9e39ba6a26947bab9 # Melos (https://melos.invertase.dev): its scripts run across the workspace's packages, # `dart run melos run `, and take Melos' filters, such as # `--diff=origin/main --include-dependents` for only what changed since main and what # depends on it. tool/check.dart runs the tests through them. melos: scripts: analyze: description: Analyses the whole workspace, infos fatal too, as CI does. run: dart analyze --fatal-infos test:dart: description: The tests of the packages without Flutter (servers, curator, the shared Dart packages). Each server's start a PostgreSQL of their own on one port, so one package at a time. exec: command: dart test concurrency: 1 packageFilters: flutter: false dirExists: test test:flutter: description: The tests of the Flutter packages, those needing a running server left out (`flutter test -t requires-server` runs them by hand). exec: command: flutter test -x requires-server concurrency: 1 packageFilters: flutter: true dirExists: test generate: description: Serverpod's code generation in every server package (the CLI on the PATH, at the version CI pins). exec: command: serverpod --no-analytics generate concurrency: 1 packageFilters: fileExists: config/generator.yaml check: description: Every check a push has to pass (tool/check.dart). run: dart run tool/check.dart