e68db11aaa
Вместо v1 (history-список + slash-команды) делаем сразу v2: - header (id/conv/focus), history, input, footer - переключение фокуса Tab/Shift-Tab (history/input/sidebar) - ↑↓ scrollback, ←→ курсор в input - Enter submit (User-сообщение в history), Backspace/Del удаление, Esc clear - Ctrl-D/Ctrl-C выход (заглушка — пишет в history, реальный exit добавим) - F1 toggle help-оверлея Архитектурно: используем StateFlow+collectAsState вместо mutableStateOf, потому что в Mosaic 0.18 recompose от mutableStateOf-writes из key-handler не триггерится автоматически (требует ручного Snapshot.apply). StateFlow через collectAsState работает out-of-the-box (см. samples/snake в репо Mosaic). Compose Compiler plugin (org.jetbrains.kotlin.plugin.compose) обязателен — без него @Composable-лямбды компилятся в Function0 вместо Function2 и runMosaicBlocking не находит сигнатуру. Цели сборки: jvm + macosX64/Arm64 + linuxX64/Arm64 + mingwX64 (iOS не нужен). Бэкенд (:client, ktor-cio) — jvmMain only пока, nativeMain заглушка. Tests: 370/370 green.
88 lines
2.9 KiB
Kotlin
88 lines
2.9 KiB
Kotlin
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
|
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
|
|
|
plugins {
|
|
alias(libs.plugins.kotlin.multiplatform)
|
|
alias(libs.plugins.kotlin.serialization)
|
|
alias(libs.plugins.kotlin.compose)
|
|
alias(libs.plugins.shadow)
|
|
}
|
|
|
|
kotlin {
|
|
jvmToolchain(21)
|
|
// Suppress Beta-предупреждения от expect/actual объектов.
|
|
compilerOptions {
|
|
freeCompilerArgs.add("-Xexpect-actual-classes")
|
|
}
|
|
|
|
// Mosaic 0.18 поддерживает JVM + desktop-native (macosX64/macosArm64/linuxX64/linuxArm64/mingwX64).
|
|
// iOS пропускаем — на iOS не бывает TUI-сессий.
|
|
jvm()
|
|
macosX64()
|
|
macosArm64()
|
|
linuxX64()
|
|
linuxArm64()
|
|
mingwX64()
|
|
|
|
sourceSets {
|
|
commonMain.dependencies {
|
|
implementation(project(":proto"))
|
|
|
|
implementation(libs.kotlinx.coroutines.core)
|
|
implementation(libs.kotlinx.serialization.json)
|
|
|
|
// JetBrains Compose runtime — тащит Mosaic как обёртку.
|
|
implementation(libs.mosaic.runtime)
|
|
implementation(libs.mosaic.tty.terminal)
|
|
}
|
|
jvmMain.dependencies {
|
|
implementation(project(":client"))
|
|
}
|
|
commonTest.dependencies {
|
|
implementation(kotlin("test"))
|
|
implementation(libs.kotlinx.coroutines.core)
|
|
}
|
|
}
|
|
|
|
@OptIn(ExperimentalKotlinGradlePluginApi::class)
|
|
jvm {
|
|
binaries {
|
|
executable {
|
|
mainClass.set("pw.binom.agentik.tui.MainKt")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- Fatjar (uberjar) ---
|
|
//
|
|
// Аналогично `:agentik-cli`: shadowJar склеивает `jvmJar` + `jvmRuntimeClasspath` в self-contained
|
|
// `*-all.jar`. Shadow 8.x не авторегистрирует shadowJar в KMP-проектах — регистрируем явно.
|
|
val shadowJarTask = tasks.register<ShadowJar>("shadowJar") {
|
|
archiveBaseName.set("agentik-tui")
|
|
archiveClassifier.set("all")
|
|
description = "Self-contained fatjar with all runtime dependencies bundled (incl. Compose-runtime + Mosaic)."
|
|
group = "build"
|
|
|
|
from(tasks.named("jvmJar"))
|
|
val cc = try {
|
|
@Suppress("UNCHECKED_CAST")
|
|
configurations as org.gradle.api.artifacts.ConfigurationContainer
|
|
} catch (_: ClassCastException) {
|
|
@Suppress("UNCHECKED_CAST")
|
|
(project as org.gradle.api.Project).configurations as org.gradle.api.artifacts.ConfigurationContainer
|
|
}
|
|
from(cc.getByName("jvmRuntimeClasspath"))
|
|
|
|
mergeServiceFiles()
|
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
|
|
manifest {
|
|
attributes["Main-Class"] = "pw.binom.agentik.tui.MainKt"
|
|
attributes["Implementation-Title"] = "agentik-tui"
|
|
attributes["Implementation-Version"] = project.version.toString()
|
|
}
|
|
|
|
includeEmptyDirs = false
|
|
}
|