Files
amethyst/commonsUI/ARCHITECTURE.md
T
Claude 713b7d41f6 refactor: move feed DAL to commons.feeds, chess UI to nip64Chess.ui, tighten amy budget
Follow-ups to the commons/commonsUI split.

Feed data-access layer: FeedFilter, AdditiveFeedFilter, AdditiveComplexFeedFilter,
ChangesFlowFilter, FeedContentState, FeedState, InvalidatableContent,
DefaultFeedOrder, RepostRenderability and friends move from the misleading
`ui.feeds` package to the root of `commons.feeds`, next to `feeds/custom`.
The `ui.feeds` composables (NewPostsChip, RelayReachMarker, DM history cards)
stay in commonsUI and gain explicit imports. Consumer imports rewritten.

Chess: the eleven composable files in commonsUI move from the flat
`nip64Chess` package to `nip64Chess.ui`; the logic stays in
`commons/…/nip64Chess`. Consumer imports rewritten.

CLI size budget: measured after the split (1.15.2, Linux x64) the JVM
tarball is 55 MB and the jlink image tarball 80 MB, so the release gate
drops from 200 MB to 120 MB per asset. BUILDING.md, the architecture docs,
the feed-patterns skill and the split plan record the new state.

Verified: JVM compiles for commons, commonsUI, cli, desktopApp; Android debug
compiles for nappletHost and amethyst; commons/commonsUI/cli/desktopApp JVM
test suites.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N56KzPSYiN5edMRamvKEgD
2026-09-12 20:13:18 +00:00

3.3 KiB

commonsUI — the Compose half of the shared layer

commonsUI holds every piece of shared code that needs Compose UI and is therefore useless to the headless cli:

  • composables (ui/<area>, <feature>/ui — e.g. nip64Chess/ui, profile/ui — and the historical flat audio renderers),
  • ImageVector icons (icons, hashtags, robohash) and the icon fonts,
  • theme, layouts, markdown rendering (ui/markdown, jvmAndroid),
  • Coil (service/image: CoilImageBridge + BlurHash/ThumbHash/Base64/Blossom fetchers),
  • the composeResources tree (translated strings, fonts, the napplet shell + shim files) and the generated com.vitorpamplona.amethyst.commons.resources.Res,
  • the @Composable relay-client entry points (observeUser*, *FilterAssemblerSubscription, KeyDataSourceSubscription),
  • state holders that carry a foundation/ui type (LevelFeedViewModel with its LazyListState, ChatNewMessageState with TextFieldValue, EmojiSuggestionState with TextFieldState).

It depends on :commons (and :quartz) as api, so a consumer that adds :commonsUI sees the headless layer transitively. amethyst, desktopApp, nappletHost and benchmark depend on it; cli, geode, marmotBench must never.

Same packages as commons

Every file keeps its com.vitorpamplona.amethyst.commons.* package. The split is a build-graph boundary, not a package rename: nothing in the apps had to change an import, and a file can move between the two modules with a git mv. The rule for which module a file lives in is mechanical:

imports androidx.compose.ui / foundation / material3 / animation, Coil, org.jetbrains.compose.resources, Res, org.jetbrains.skia, or declares a @Composable → commonsUI. Otherwise → commons.

The only cross-module gotcha is internal: a commonsUI file cannot see an internal declaration in commons. Make it public (or move the caller).

The full package taxonomy — including which packages are "mixed" (logic in commons, composables here, same package name) — is the table in commons/ARCHITECTURE.md §2. Read that first; this file only documents what is specific to the UI module.

Source sets

Source set For
commonMain Composables, icons, theme, Coil fetchers, composeResources. Gated by verifyKmpPurity like commons.
jvmAndroid Markdown renderer (ui/markdown), Coil-OkHttp + Blossom read-auth fetcher, the viewModel() helper.
jvmMain Desktop Coil bridge (CoilImageBridge.jvm.kt), compose.desktop.currentOs. dependsOn(jvmAndroid) + skikoMain.
androidMain Android Coil bridge. dependsOn(jvmAndroid).
skikoMain org.jetbrains.skia pixel helpers shared by desktop JVM + iOS (SkiaBitmapConverter).
iosMain iOS Coil bridge. Compile-only spike today.

Tooling that points here

  • Icon fonts: tools/material-symbols-subset/subset.sh and tools/icon-font/build_icon_font.py read icons/ and write composeResources/font/ in this module (see root .claude/CLAUDE.md, "Icons").
  • Translations: crowdin.yml and tools/strings-migrate/ target commonsUI/src/commonMain/composeResources/.
  • CI: .github/workflows/build.yml runs :commonsUI:jvmTest, :commonsUI:verifyKmpPurity and the iOS compile/test tasks next to the :commons ones.