- conv-ls/new/show/delete/rename -> вложенные под agentik-cli conv
- ConvCommand — Subcommand-родитель, регистрирует 5 дочерних
команд в init { subcommands(...) }
- ConvSubcommand(name, description) extends AgentikSubcommand —
базовый класс для всех conv-подкоманд (наследует --server/--id)
Два гоччаса kotlinx.cli 0.3.6 которые пришлось обойти:
1. parent.execute() вызывается ПОСЛЕ leaf.execute() всегда когда
leaf достигнут через parent. Если parent делает что-то в
execute() — вывод дублируется после каждой дочерней команды.
Фикс: ConvCommand.execute() = Unit (no-op). Дочерние команды
смотрятся через 'agentik-cli conv --help'.
2. По умолчанию 'conv new --server ...' парсится как
conv[--server ...] + позиционный arg 'new' на уровне
родителя, и дочерняя команда не запускается. Фикс:
ArgParser(strictSubcommandOptionsOrder = true) — все аргументы
после имени subcommand передаются в его парсер.
Smoke (linuxX64 kexe + JVM fatjar): conv ls/new/rename/show/delete
+ msgs/send/interrupt/info работают.
7.4 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 <command> [args...]
Команды верхнего уровня:
conv <subcommand> операции над диалогами (см. ниже)
msgs <id> [--limit N] показать сообщения
send <id> <text...> отправить ход, стримит response-события в stdout
interrupt <id> прервать текущий ход
info показать конфиг (server URL + agent id)
Подкоманды `conv`:
conv ls список диалогов
conv new [--temp] создать диалог, печатает id
conv show <id> метаданные диалога
conv delete <id> удалить диалог
conv rename <id> <title> переименовать
--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 "привет"
agentik-cli info # через AGENTIK_SERVER env-переменную
Как запустить
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 conv --help
Native linuxX64
./gradlew :agentik-cli:linkReleaseExecutableLinuxX64
./agentik-cli/build/bin/linuxX64/releaseExecutable/agentik-cli.kexe conv --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 через корутины.
Готчасы kotlinx.cli
- Вложенные subcommands + parent.execute(). В kotlinx.cli 0.3.6
parent.execute()вызывается ПОСЛЕleaf.execute()всегда, когда leaf был достигнут через parent. ПоэтомуConvCommand.execute()сделан no-op (override fun execute() = Unit), иначе вывод дочерней команды дублируется выводом родителя. Дочерние команды смотрятся черезagentik-cli conv --help. - strictSubcommandOptionsOrder. Без этого флага
conv new --server ...парсится какconv [--server ...]+ позиционный аргументnewна уровне родителя — и дочерняя команда не запускается. ВArgParserсразу включаетсяstrictSubcommandOptionsOrder = true.
Тесты
Тесты для подкоманд пока не написаны (TODO). Базовый smoke покрывается руками против живого сервера.
./gradlew :agentik-cli:jvmTest # 0/0 — пока пусто
Версии
gradle/libs.versions.toml → [versions] agentik-agentik-cli.