- Добавил нативные таргеты с реальной реализацией (не stub-ы):
- linuxX64 kexe ~5 МБ — собран, запускается, проходит
smoke против 192.168.76.166 (--help, info, conv-ls,
conv-new, send со стримом response-events, AGENTIK_SERVER
env-переменная).
- mingwX64 .exe ~6 МБ — собирается через кросс-компиляцию с Linux.
- macosX64 / macosArm64 — на Linux-хосте не линкуются (нужен
macOS-раннер, Apple Mach-O), но target-объявления + entryPoint
валидны.
- entryPoint на K/N — FQN без 'Kt': pw.binom.agentik.cli.main
(на JVM по-прежнему AgentikCliKt через mainClass.set).
- platformEnv: expect/actual split. Native actual — getenv()
из platform.posix через kotlinx.cinterop, помеченный
@OptIn(ExperimentalForeignApi::class).
- linuxArm64 у :agentik-cli отсутствует — kotlinx.cli 0.3.6 не
публикует klib для linuxArm64. У :client linuxArm64 сохранён
(асимметрия допустима: :client нужен только :agentik-cli,
который на linuxArm64 не работает).
- README обновлён: target matrix, env-vars, native entry-point,
платформенные детали.
6.3 KiB
:agentik-cli — one-shot CLI клиент к /agentik
Что это
One-shot subcommand CLI (Kotlin Multiplatform) к серверу
:standalone через :client по HTTP+SSE. Один вызов — одна команда:
стрим ответа send идёт в stdout построчно, никакого embedded-REPL.
Решает: быстрый способ дёрнуть агента из shell-скрипта или руками, не поднимая отдельную TUI-сессию.
Платформы
| Платформа | Артефакт | Размер | Статус |
|---|---|---|---|
jvm (JRE 21) |
*-all.jar |
~7 МБ | ✓ собирается и работает |
linuxX64 |
.kexe |
~5 МБ | ✓ собирается и работает на этом хосте |
macosX64 |
.kexe |
— | собирается на macOS-раннере |
macosArm64 |
.kexe |
— | собирается на macOS-arm64-раннере |
mingwX64 |
.exe |
~6 МБ | ✓ собирается (cross-compile с Linux) |
linuxArm64 |
— | — | нет — kotlinx-cli 0.3.6 не публикует klib для linuxArm64 |
iOS |
— | — | нет смысла на iOS |
Подкоманды
agentik-cli <subcommand> [options]
Subcommands:
conv-ls Список диалогов агента
conv-new Создать диалог; печатает id
conv-show Метаданные диалога
conv-delete Удалить диалог
conv-rename Переименовать диалог
msgs Показать сообщения диалога
send Отправить user-ход и стримить ответ
interrupt Прервать текущий ход диалога
info Показать server URL и agent id
--server URL и --id ID (env: AGENTIK_SERVER, AGENTIK_AGENT_ID)
задаются после имени subcommand'а — kotlinx.cli не шарит опции
родителя в subcommand. Пример:
agentik-cli conv-ls --server http://192.168.76.166:8080/agentik
agentik-cli conv-new --server http://localhost:8080/agentik
agentik-cli send --server http://localhost:8080/agentik conv-abc "привет"
Как запустить
JVM (fatjar)
./gradlew :agentik-cli:shadowJar
java --enable-native-access=ALL-UNNAMED \
-jar agentik-cli/build/libs/agentik-cli-0.1.0-SNAPSHOT-all.jar --help
Native linuxX64
./gradlew :agentik-cli:linkReleaseExecutableLinuxX64
./agentik-cli/build/bin/linuxX64/releaseExecutable/agentik-cli.kexe --help
Native macOS / Windows
На Linux-хосте macosX64/macosArm64 линкуются пустыми (нужен
macOS-раннер, Apple Mach-O формат). mingwX64 собирается через
кросс-компиляцию.
CI-ноут: запускать ./gradlew :agentik-cli:linkReleaseExecutableMacosX64 :agentik-cli:linkReleaseExecutableMacosArm64 на macos-latest
раннере Gitea Actions.
Примеры
# Список диалогов (таблица)
agentik-cli conv-ls --server http://localhost:8080/agentik
# Создать диалог
ID=$(agentik-cli conv-new --server http://localhost:8080/agentik)
echo "new conv: $ID"
# Переименовать
agentik-cli conv-rename --server http://localhost:8080/agentik "$ID" "мой чат"
# Отправить ход и стримить ответ
agentik-cli send --server http://localhost:8080/agentik "$ID" "2+2"
# Показать последние N сообщений
agentik-cli msgs --server http://localhost:8080/agentik "$ID" --limit 10
# Прервать активный ход
agentik-cli interrupt --server http://localhost:8080/agentik "$ID"
# Удалить
agentik-cli conv-delete --server http://localhost:8080/agentik "$ID"
# Через env-переменную
AGENTIK_SERVER=http://localhost:8080/agentik agentik-cli info
Формат вывода send
Каждое SSE-событие печатается отдельной строкой event <Type> ... —
пригодно для парсинга через awk/jq-обёртки:
event StartReasoning
event StartResponse TEXT
event AppendText \n\n
event AppendText Привет!
event End
Терминальные события (End, Interrupted, Error) тоже
печатаются; CLI выходит сразу после End.
Почему kotlinx.cli (а не clikt)
- kotlinx.cli 0.3.6 (JetBrains, KMP) — единственный зрелый
arg-parser, который стабильно линкуется под
linux_x64+macos_x64/macos_arm64+mingw_x64. Минус: нетlinux_arm64. - clikt-multiplatform 5.x (ajalt) — имеет linuxArm64, но
ломается на native linker:
duplicate symbol selfAndAncestorsмеждуcliktиclikt-mordantcommonMain (issue ajalt/clikt#598). Workaroundkotlin.native.cacheKind.linuxX64=noneзамедляет сборку на порядки и не решает проблему до конца. Поэтому clikt отвергнут.
Платформенные детали
- entryPoint на K/N — это FQN функции без суффикса
Kt(т.е.pw.binom.agentik.cli.main, а неMainKt.main). JVM conventionMainKt.mainтут не работает — K/N линкер ищет функцию поpackage.main. platformEnv(key)для чтения env-переменных:- JVM:
System.getenv(key)черезjvmMainactual. - Native:
getenv(key)изplatform.posixчерезkotlinx.cinterop.toKString()(nativeMainactual, требует@OptIn(ExperimentalForeignApi::class)).
- JVM:
- Stdout / exit code — работают на K/N через корутины.
Тесты
Тесты для подкоманд пока не написаны (TODO). Базовый smoke покрывается руками против живого сервера.
./gradlew :agentik-cli:jvmTest # 0/0 — пока пусто
Версии
gradle/libs.versions.toml → [versions] agentik-agentik-cli.