9734eec63c
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.
85 lines
3.5 KiB
Plaintext
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)?
|