Skip to content

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.

Specification body

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:

  1. Linha "Usage:" com forma canônica
  2. Lista de flags com descrição curta (uma linha cada)
  3. Link ou path pra documentação completa (README.kmd do componente, ou URL https://<slug>.koder.dev/docs/cli quando 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 -p semantics) — 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:

FlagMandatory release-gateFalha-soft permitida
--version / -vsimnão
--help / -hsimnão
--user-data-dir=<PATH>simnão
--no-startup-windowsimsim (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:

  • --version para 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)

IDVerificaçã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)
T7Audit-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 CLI
  • policies/headless-first.kmd — R8 SDK reuse aplica quando consumidor automatiza esses flags
  • policies/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).

References