Standard CLI Flags for Koder Apps
binaries-and-cli specs/binaries-and-cli/standard-flags.kmd
Toda app Koder com binário CLI/desktop/TUI (Flutter desktop, Bubble Tea TUI, cobra CLI) deve aceitar um conjunto comum de flags com contrato preciso: `--version` e `--help` que terminam **antes** de qualquer init de GUI/runtime; `--user-data-dir` que isola profile/cache da sessão real do usuário; `--no-startup-window` que desacopla boot do runtime de criação de janela top-level. A motivação é tornar **probes de automação seguros por construção** — inspecionar versão / capability / capacity de um app Koder não pode abrir GUI, herdar sessão, ou consumir display do usuário.
Corpo da especificação
Spec — Standard CLI Flags for Koder Apps
Motivação
Em 2026-05-28 uma sessão de IA tentou detectar a versão de Kruze
instalada via /opt/koder/kruze/koder_kruze --version. O binário,
sem implementar o flag, ignorou-o e bootou a app inteira no display
do owner — três janelas Kruze restauraram a sessão interativa do
usuário (tabs do dia: claude.com, kds.koder.dev, etc.) e ficaram
travadas porque concorriam por GPU + display com o smoke-bench em
progresso. Episódio documentado em meta/context/handoff/recaps/ 2026-05.md (2026-05-28 turn 21+).
O incidente é uma instância de um defeito de superfície: apps Koder desktop não têm contrato comum sobre como respondem a flags canônicas que toda automação tenta primeiro. Esta spec fecha esse gap.
Escopo
Todo binário/CLI/desktop/TUI Koder em qualquer um dos paths:
products/<area>/<sector>/app/desktop/products/<area>/<sector>/app/cli/products/<area>/<sector>/app/tui/products/<area>/<sector>/cli/products/<area>/<sector>/tui/dev/<tool>/(koder-tools binaries)
Componentes que não se aplicam: apps mobile (app/mobile/),
app TV (app/tv/), web (app/web/), serviços backend (backend/),
SDK libraries (engines/sdk/).
R1 — --version / -v
Imprime a string canônica de versão em stdout e termina com exit status 0. Nenhuma inicialização de runtime de GUI/CEF/Flutter
engine/GTK/X11/Wayland/audio é permitida nesse caminho. O argv
parsing deve detectar este flag antes de chamar initCEFProcesses
/ gtk_init / Wayland connect / análogos.
Formato canônico de saída (uma linha):
<slug> <semver>
ou, quando o app distribui múltiplos binários sob a mesma versão de
release (cf. naming.kmd §"single-binary vs multi-binary family"):
<binary> v<semver> (<slug>)
Exemplos:
$ kruze --version
kruze 1.0.53
$ kterm -v
kterm 1.32.4
$ kicon --version
kicon v0.18.2 (koder-tools)
Anti-padrões proibidos:
- Booting a app antes de imprimir versão
- Imprimir versão E continuar (precisa SAIR)
- Exit code ≠ 0
- Adicionar prefixos longos (
Welcome to Koder…,Copyright …) — uma linha curta, parseável
R2 — --help / -h
Imprime usage em stdout e termina com exit status 0. Mesma regra
"zero inicialização de runtime de GUI" do R1.
Usage deve incluir, em ordem:
- Linha "Usage:" com forma canônica
- Lista de flags com descrição curta (uma linha cada)
- Link ou path pra documentação completa (README.kmd do componente,
ou URL
https://<slug>.koder.dev/docs/cliquando publicada)
Exemplos:
$ kruze --help
Usage: kruze [options] [url]
Options:
--version, -v Print version and exit.
--help, -h Print this help and exit.
--user-data-dir=DIR Isolate profile/cache to DIR.
--no-startup-window Boot without creating a top-level window
(requires --cdp-port for control).
--headless Hide the main window after boot.
--incognito Start in incognito mode.
--new-window Open a new top-level (when already running).
--cdp-port=PORT Bind CEF remote-debugging to PORT.
--batch SUBCMD [...] Run a batch subcommand and exit.
--debug-mode Enable in-app inspection capture.
--debug-jsonl=PATH Append CDP events as JSON Lines to PATH.
Documentation: https://kruze.koder.dev/docs/cli
R3 — --user-data-dir=<PATH>
Isola todo state per-user (profile, cache, cookies, session, logs)
em <PATH> em vez do default. Default é o que naming.kmd define
por target (Linux: $XDG_DATA_HOME/<slug>/, macOS: ~/Library/ Application Support/<slug>/, Windows: %APPDATA%\<slug>\).
Quando --user-data-dir=<PATH> está presente:
- Toda escrita de profile/cache/cookies/session ROTEIA para
<PATH> - Default location não é tocada (nem lida, nem escrita)
- Path inexistente é criado (com
mkdir -psemantics) — falhar apenas se o path não pode ser criado por motivo de permissão - Path relativo é resolvido a partir de
$PWD
CEF/Chromium-based apps já têm suporte nativo a --user-data-dir —
o flag deve ser passado adiante ao runtime sem reinterpretação.
GTK/Bubble Tea apps precisam implementar o roteamento manualmente.
Caso de uso primário: probes de automação seguros. Toda
ferramenta que invoca um app Koder pra inspecionar capability /
versão / state DEVE usar --user-data-dir apontando pra path
descartável (ex.: /tmp/probe-<random>/). Sem isso, o probe herda
a sessão real do usuário.
R4 — --no-startup-window
Boota o runtime sem criar janela top-level visível. Compõe com
--cdp-port=<N> pra modo "puramente controlled via CDP" e com
--batch <subcmd> pra one-shot.
Diferente de --headless: --headless ainda CRIA a janela (oculta
via windowManager.hide()); --no-startup-window não cria janela
nenhuma. Em apps Flutter/GTK, isso significa skip de
GtkApplicationWindow + FlView (cf. kruze#175.1 para
arquitetura proposta).
Nota de implementação: este flag é o mais difícil dos 4 porque
requer alterações estruturais no runner GTK/Wayland (cf. KRUZE-175.1
análise técnica). É mandatory na spec mas não-bloqueante pra
release de app que já implemente R1+R2+R3 — falha-soft com mensagem
"--no-startup-window not yet implemented; use --headless for
similar behavior" + exit 1 quando o flag é passado. R5 da spec
elabora.
R5 — Implementação gradual permitida
Apps podem shippear R1+R2+R3 antes de R4. O contrato fraco:
| Flag | Mandatory release-gate | Falha-soft permitida |
|---|---|---|
--version / -v | sim | não |
--help / -h | sim | não |
--user-data-dir=<PATH> | sim | não |
--no-startup-window | sim | sim (mensagem + exit 1) até KRUZE-175.1 / equivalente cobrir |
Release engineering bloqueia release de app que não implementa
R1+R2+R3. R4 pode falhar-soft enquanto o ticket de implementação
estrutural está aberto + linkado no koder.toml [compat].
R6 — Probes de automação devem usar os flags
Toda ferramenta Koder que invoca apps Koder (incl. agentes de IA) DEVE usar:
--versionpara detecção de versão (NUNCA parse binário/strings)--user-data-dir=/tmp/<slug>-probe-<random>/para qualquer invocação que não é o uso normal do usuário
Violar isso é violação direta de policies/heavy-work-isolation.kmd §R9 (proteção da sessão interativa do owner — implícita até esta
spec; explícita após).
Tests (validação da spec)
| ID | Verificação |
|---|---|
| T1 | <binary> --version imprime uma linha + exit 0 em < 1s wall-clock (zero GUI init) |
| T2 | <binary> -v é equivalente a <binary> --version |
| T3 | <binary> --help imprime usage + exit 0 em < 1s wall-clock |
| T4 | <binary> -h é equivalente a <binary> --help |
| T5 | <binary> --user-data-dir=/tmp/probe-X --headless --cdp-port 9999 about:blank cria /tmp/probe-X/ e NÃO escreve em $XDG_DATA_HOME/<slug>/ |
| T6 | <binary> --no-startup-window --cdp-port 9999 ou exibe banner "not implemented" + exit 1, OU boota sem janela top-level (R4 cumprido) |
| T7 | Audit-walk de cada app/desktop/, app/cli/, app/tui/, cli/, tui/ no monorepo lista quais componentes implementam R1-R3 vs estão pendentes |
Cross-references
specs/binaries-and-cli/naming.kmd— define o nome do binário; esta spec define seu contrato CLIpolicies/headless-first.kmd— R8 SDK reuse aplica quando consumidor automatiza esses flagspolicies/heavy-work-isolation.kmd §R9— carve-out de laptop pressupõe esses flags pra probes seguros
Histórico
- 2026-05-28 — spec criada após incidente "rogue Kruze windows" durante KRUZE-181 fase 2 carve-out run. Kruze ficou como reference implementation (R1+R2+R3 implementadas; R4 pendente em KRUZE-175.1).
Referências
specs/binaries-and-cli/naming.kmdpolicies/headless-first.kmdpolicies/heavy-work-isolation.kmd