Decisions
0008. The artifact split: runner, app, testkit and core
tui4s-core becomes a composite of three artifacts in this repository: tui4s-runner, tui4s-app and tui4s-testkit, each with its own version and tag, in the same packages, with tui4s.internal sealed.
Status
Accepted
Date
2026-10-19 (D25, issue #17; the user: "do it before L3"). Done at 132358f.
Context
tui4s-coreheld three layers under one name: the runner (renderer, embedder, component model), the app shell (TuiApp) and the test kit (Headless,Screen).- A kyo-ui user who wants only "run this UI in a terminal" (a library, or an app with its own
main) had no artifact that says so. - The spec of 2026-10-01 put the test kit inside core (Q6: "one artifact fewer to version and release").
- Each module already had its own version and tag (
<module>-v<semver>, ADR 0014). - Nothing was published, so the split was free before 0.1 and a breaking change after it.
Decision
- The repository publishes four artifacts for the terminal:
tui4s-runner(Layout, Paint, Canvas, Runner, Mount, Dispatch, the terminal code,Hooks,Component,Tui.run,TuiOptions,Tui.size,Screen,tui4s.spi),tui4s-app(TuiApp),tui4s-testkit(Headless, aliases of theScreentypes) and the compositetui4s-core. - The jar of
tui4s-coreholds onlyobject tui4s.Core. It depends on the three, and its test sources are the integration suites. - All artifacts use the same packages (
tui4s,tui4s.internal,tui4s.spi,tui4s.testkit), so imports do not change. tui4s.internalis sealed: each top-level definition isprivate[tui4s].PublicApiTestchecks the seal across the four jars, and that no public signature names an internal type.- The release order is runner, then app and testkit, then core. The composite watches the three directories for the version policy.
- The names stay
tui4s-*, notkyo-ui-*.
Alternatives considered
- One artifact
tui4s-corewith the test kit inside (spec Q6, the default of 2026-10-01). Superseded: the runner had no artifact of its own. - A separate repository for the runner. D25 says "in-repo, not a separate repository". The reason is not recorded beyond that.
- Core depends on an external
kyo-ui-terminal-runner. Rejected for the name:kyo-ui-*is the namespace of upstream. Other reasons are not recorded. - Split after 0.1. Rejected: the split is free now and breaking later.
Consequences
- Good: a kyo-ui user takes
tui4s-runneralone, andtui4s-testkitin theTestscope. - Good:
TuiAppandHeadlessevolve with their own versions. - Bad: four tags to release in order, and three more deployment tag patterns in the
maven-centralenvironment (runner-v*,app-v*,testkit-v*): a human step. - Bad:
private[tui4s]is public in the bytecode. MiMa sees the internal types, so an internal change can break binary compatibility across the jars. - Note: the planned zio and cats modules depended on the runner. They were removed on 2026-10-20 (ADR 0014).
References
- Decision log: D25. Issue #17 (closed). Spec section 9, Q6 (superseded).
- Gate 1 answer 1 (the seal of
tui4s.internal, 2026-10-13). - ARCHITECTURE.md: "What tui4s is" (the module table). CONTRIBUTING.md: "Compatibility and versioning", "Releasing".
0007. Compiler flags from sbt-tpolecat
sbt-tpolecat sets the scalac options; warnings stay warnings on a developer machine, and CI (SBT_TPOLECAT_CI) turns them into errors.
0009. tui4s-use and tui4s-widgets, cross-built
Composables (tui4s-use) and widgets (tui4s-widgets) are published modules of this repository, plain kyo-ui code for the JVM and Scala.js, with no dependency on tui4s-core.