Decisions
0010. The flagship assistant is the blueprint of a real app
One flagship example, an AI chat assistant, shows how to structure a real tui4s app: a pure domain, services as traits with interpreters, one store, Kyo layers and errors as values.
Status
Accepted
Date
2026-10-17 (D3, D4). Landed on 2026-10-19 (L3).
Context
- The user asked for "a large example that shows how to structure a real application" and for "a chat bot that can use ChatGPT or Anthropic (API key, or a subscription if it is permitted)".
- Provider rules (research of 2026-10-17): an API key is permitted for both. A claude.ai login or token reuse in a third-party app is forbidden. Driving the user's own
claude -pis gray, and without--bareit runs the project's hooks and MCP servers. OpenAI "Sign in with ChatGPT" for open-source apps was a preview (search summaries only). - The official Java SDKs are 39 MB and 69 MB core jars plus Kotlin, Jackson and OkHttp. kyo-http RC7 can stream SSE on a POST and is already on the classpath through kyo-ui.
- A tui4s handler runs on the runner fiber. A handler that waits for the network freezes input, so actions that wait must fork.
Decision
- One flagship app: the assistant (
modules/assistant, mainexamples.assistant.AssistantApp,--fakefor no network). - Providers: Anthropic and OpenAI with the user's API key, and a scripted fake provider. Codex app-server is second (not built; #48). A Claude Code CLI backend is never in published code.
- Keys come from environment variables or a file with mode 0600 (
SecretsJvm), never from a login token. - The shape is the blueprint for a new app: a pure domain with laws (the transcript fold, the title rule, the SSE split, the codec round trip); services as traits (
ChatProvider,Secrets,ConversationStore,AppLog) with their interpreters in amake(JVM, browser, in memory for tests); one store for the app; the wiring with Kyo layers in the main; errors as values (Abortwith a sealed error type). - The HTTP seam (
KyoHttp) follows no redirect and has a 5-minute idle limit. The review found that a redirect carried the key to the new host. - Thin SSE wires over kyo-http, no vendor SDK.
- The app opts in to the Anthropic server-side fallbacks for its default model (header
anthropic-beta: server-side-fallback-2026-07-01, fieldfallbacks: "default"). The user must know this.
Alternatives considered
- Several small apps. Not chosen: the user asked for one large example. The small examples (counter, todo, dashboard, forms, gallery) stay for single features.
- A chat bot in the docs only. Not recorded.
- The official provider SDKs. Rejected for their size and their dependencies.
- A subscription login. Rejected: forbidden for Anthropic; unverified terms for OpenAI.
- A Claude Code CLI backend. Rejected for published code: a gray area under the provider rules, and a child process runs the hooks and MCP servers of the folder.
Consequences
- Good: the assistant is the reference for CONTRIBUTING.md ("Follow it for a new app") and for the docs.
- Good: in-memory interpreters make 13 headless tests and 86 module tests possible with no network.
- Bad: the server-side fallbacks change which model answers when a safety rule declines. This is an opt-in in
Wires.scala; it needs a line in the docs (#35). - Bad: the OpenAI default model id is unchecked data; effort and thinking are not sent; the run log file has the umask mode.
- Bad:
Surfacemixes data and the key-vault capability (a deferred review finding, #36).
References
- Roadmap: 2.5, 2.6 (the handler trap), D3, D4. Handoff: L3 ("USER MUST KNOW").
- CONTRIBUTING.md: "UI architecture and API design" (the assistant item).
- README: "A real app: the assistant".
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.
0011. The web target: a standalone Scala.js app and one theme
The web build of the assistant is a static Scala.js app from the shared module, with no server and no link to the terminal app; one Theme value renders both looks to one Stylesheet.