Files
correx/docs/modules/apps/app-cli.adoc
T
kami 9734eec63c docs: add module documentation in AsciiDoc with PlantUML diagrams
Generated by per-group subagents covering all 52 modules across:
core (18), infrastructure (10), apps (5), interfaces (3),
plugins (7), testing (9)

Documentation format:
- AsciiDoc (.adoc) files in docs/modules/<group>/
- PlantUML (.puml) files in docs/diagrams/
- .adoc files reference diagrams via include:: directives

Each doc covers: purpose, responsibilities, non-responsibilities,
key types, event flow, integration points, invariants, PlantUML
diagram, known issues, and open questions.
2026-05-26 16:59:21 +04:00

85 lines
3.5 KiB
Plaintext

= app-cli
== purpose
Command-line interface built with Clikt that connects to the Correx server to start, manage, and observe sessions. Designed for scripted/headless usage and non-interactive environments.
== responsibilities
* Start sessions by workflow ID via HTTP POST to the server
* Attach to a session's WebSocket stream and relay lifecycle events (session, stage, tool, approval) to stdout
* Prompt for approval decisions (approve / reject / steer) when a TTY is available
* Support `--json` output for machine parsing and `--quiet` for error-only mode
* List sessions, resume/cancel sessions, fetch session events
* List inference providers and their health status
* Send approval decisions to the server via HTTP
== non-responsibilities
* Does not maintain persistent state or local event cache
* Does not contain domain orchestration logic
* Does not perform inference or tool execution
* Does not implement the approval engine — only forwards user decisions
* Does not run a server
== key types
=== CorrexCli
* **kind**: `CliktCommand` (root)
* **purpose**: Top-level CLI command. Defines global flags `--json` and `--quiet`.
=== RunCommand
* **kind**: `CliktCommand` (subcommand)
* **purpose**: Starts a session for a workflow and streams events to stdout. Supports `--workflow`, `--session`, `--auto-approve`, `--host`, `--port`.
=== CliWsClient
* **kind**: class
* **purpose**: Thin Ktor WebSocket client wrapping `HttpClient.webSocket`. Calls `onMessage` callback per frame; returns `false` from callback to close the stream.
=== SystemExitException
* **kind**: exception
* **purpose**: Propagates exit codes (0 = success, 1 = session failure, 2 = rejection in non-TTY mode).
=== RunContext / ApprovalContext
* **kind**: internal data classes
* **purpose**: Carry session ID, JSON flag, auto-approve flag, TTY status through the message handling loop.
== event flow
*inbound:* WebSocket frames from server encoded as JSON `ServerMessage` variants. The CLI decodes the `type` field from a raw `JsonObject` (not deserialized via `ProtocolSerializer`).
*outbound:* `ApprovalResponsePayload` sent as text frames on the WebSocket session.
== integration points
* `apps:cli` depends only on external libraries: Clikt (CLI framework) and Ktor client (HTTP + WebSockets)
* Talks to the server at `http://{host}:{port}` via REST and `ws://{host}:{port}/sessions/{id}/stream`
== invariants
* `CliWsClient.sessionStream` breaks out of the frame loop when `onMessage` returns `false`
* Auto-approve without a TTY is impossible — if `--auto-approve` is not set and no TTY, all approvals are rejected
* Exit code 2 means the user rejected an approval in non-interactive mode
* `RunCommand` creates one session and one WebSocket connection per invocation
== PlantUML diagram
[plantuml, app-cli, "png"]
----
include::../../diagrams/app-cli.puml[]
----
== known issues
* JSON output format is hand-constructed in `printLine()` rather than using a serializer — field ordering and escaping may diverge from `ServerMessage` serialization
* `--session` (resume) acceptance on the server side is not yet implemented — the parameter is forwarded but the server's response is untested
* `resolveDecision` blocks on stdin in TTY mode — no timeout mechanism for user input
== open questions
* Should session resume reconnect to an existing WebSocket stream or replay from the event store? Currently the parameter is accepted but behavior is undefined.
* Should `RunCommand` support multiple sessions concurrently (e.g., `--watch` mode)?