75 lines
3.3 KiB
Markdown
75 lines
3.3 KiB
Markdown
# `app-rust`'s `client` module
|
|
|
|
`app-rust/src/client` contains platform- and UI-independent client logic. It
|
|
must not depend on iris; a `use iris::` below this directory is a layering
|
|
defect. `event-model` remains a separate crate because the server and client
|
|
both depend on that wire contract.
|
|
|
|
## Contents
|
|
|
|
- `api.rs`: REST client over the injectable `Transport` trait.
|
|
- `sse.rs` and `event_stream.rs`: SSE framing and session-event following.
|
|
- `transcript_cache.rs`: bounded, persistent transcript chunks.
|
|
- `transcript_source.rs`: cache/server selection and live cache updates.
|
|
- `transcript_fold.rs`: event folding, tool grouping, and page healing.
|
|
- `markdown_blocks.rs`, `ansi.rs`, and `highlight/`: display-independent text
|
|
parsing and spans.
|
|
- `config.rs`: enrollment-link parsing and the shared `EnrolledServer` value.
|
|
- `log_ring.rs`: bounded process-local diagnostics.
|
|
|
|
## API coverage
|
|
|
|
`ApiClient` covers session list/read, messages, unqueue, answers, interrupt,
|
|
stop/start, rename, working directory, model, permission mode, notification
|
|
setting, commands, compaction, deletion, and transcript pages.
|
|
|
|
Still missing are setups and discovery, file operations, usage, models and
|
|
downloads, attachments, imports, and the global notifications stream.
|
|
`server/src/routes.rs` is the authoritative route table.
|
|
|
|
## Transcript invariants
|
|
|
|
`join_pages` heals messages and tool runs split across page boundaries. It
|
|
asserts that a tool id does not survive in both halves. It must not assert
|
|
sequence ordering across the seam: a peer note carries the sequence of the
|
|
turn it belongs above and can legitimately interleave with the page where it
|
|
arrived.
|
|
|
|
`Event` has no catch-all variant. A newer server adding an event type will
|
|
make an older client reject that line rather than draw a placeholder. Fixing
|
|
that requires a shared wire-model decision, not a client-only workaround.
|
|
|
|
`TranscriptSource::page(0, ..)` returns `OlderPage::NothingLoaded` without
|
|
touching cache or network. This is deliberately distinct from
|
|
`OlderPage::Events(vec![])`, which means the start of the conversation was
|
|
actually reached. Network and cache parse failures are errors for the same
|
|
reason: none of these states may latch a caller's “no more history” flag.
|
|
|
|
Fetched transcript lines retain the server's exact JSON bytes through
|
|
`RawValue`. Re-serializing parsed JSON can change floating-point text, causing
|
|
the cached and streamed forms of one event to disagree byte-for-byte.
|
|
|
|
The reconnect/backoff loop and cancellation of a live stream belong to the
|
|
embedding runtime. `TranscriptSource::follow` only guarantees that each frame
|
|
is cached before the caller receives it.
|
|
|
|
## Enrollment
|
|
|
|
`EnrolledServer` and `parse_link` understand the same
|
|
`aiapp://enroll?host=H&port=P&token=T[&ca=B]` value used by Android. Storage
|
|
is caller-specific: Android uses its platform storage and the desktop writes a
|
|
0600 file under its XDG config directory.
|
|
|
|
## Markdown scope
|
|
|
|
`markdown_blocks` splits top-level headings, paragraphs, fences, lists,
|
|
tables, and quotes. It intentionally does not build a full nested CommonMark
|
|
AST; inline styling and nested presentation remain renderer concerns until a
|
|
shared non-UI consumer needs them.
|
|
|
|
## Verification
|
|
|
|
Run `./scripts/run-tests.sh` from the repository root. For this crate alone,
|
|
run `cargo test`, `cargo clippy --all-targets`, and `cargo fmt --check` from
|
|
`app-rust/`.
|