149 lines
6.8 KiB
Markdown
149 lines
6.8 KiB
Markdown
# wip-tui
|
||
|
||
`wip-tui` is an interactive terminal client for exploring and operating a WIP
|
||
Worldspace. It is a presentation and terminal-interaction layer over
|
||
`wip-client`: Known Space, request identity, validators, immutable operation call
|
||
contexts, stale transitions, response classification, and bounded histories remain
|
||
owned by the client runtime.
|
||
|
||
## Start
|
||
|
||
Supply one `http` or `https` endpoint:
|
||
|
||
```console
|
||
cargo run -p wip-tui -- --endpoint https://wip.example.test/api/wip
|
||
```
|
||
|
||
The same canonical endpoint is used unchanged to construct requests, perform
|
||
HTTP I/O, and partition the client cache. WIP over HTTP does not define separate
|
||
HTTPS and development-HTTP profiles; URL scheme, TLS, certificate, authentication,
|
||
and proxy policy belong to the HTTP implementation and deployment.
|
||
|
||
The endpoint may instead be supplied as `WIP_ENDPOINT`. A non-secret cache
|
||
partition identity may be supplied with `--security-context NAME` or
|
||
`WIP_SECURITY_CONTEXT`. The default request timeout is 30 seconds and can be
|
||
changed with `--timeout SECONDS`.
|
||
|
||
An Authorization header can be read from an environment variable without placing
|
||
its value in arguments, application state, errors, snapshots, or debug output:
|
||
|
||
```console
|
||
export WIP_AUTHORIZATION='Bearer …'
|
||
cargo run -p wip-tui -- https://wip.example.test/wip
|
||
```
|
||
|
||
Use `--authorization-env OTHER_VARIABLE` to select another variable. The value is
|
||
redacted from `Debug` and is never rendered. Shell and process environment security
|
||
remain the operator's responsibility.
|
||
|
||
### Filesystem server example
|
||
|
||
In one terminal:
|
||
|
||
```console
|
||
mkdir -p /tmp/wip-example
|
||
printf 'hello world' >/tmp/wip-example/notes.txt
|
||
cargo run -p wip-fs-server -- \
|
||
--root /tmp/wip-example \
|
||
--listen 127.0.0.1:8080 \
|
||
--base-path /wip \
|
||
--read-write
|
||
```
|
||
|
||
In another:
|
||
|
||
```console
|
||
cargo run -p wip-tui -- http://127.0.0.1:8080/wip
|
||
```
|
||
|
||
Expand `/`, select `notes.txt`, focus the Interface/Operation pane, and choose
|
||
`read`; descriptors advertised by visible Objects are normally prefetched already.
|
||
The editor labels `offset` and `length` as optional; leave both blank to read the
|
||
bounded file. `Bytes` results are shown as a bounded hex preview. For `replace`,
|
||
enter `contents` as RFC 4648 base64—for example, `dXBkYXRlZA==` for
|
||
`updated`—then review the target Entry, interface reference, operation, and value
|
||
on the confirmation screen before pressing Enter again.
|
||
|
||
## Keyboard bindings
|
||
|
||
All required actions are keyboard-accessible.
|
||
|
||
| Key | Action |
|
||
| --- | --- |
|
||
| `↑`/`k`, `↓`/`j` | Move within the focused tree, operation list, history, or editor |
|
||
| `→`/`l`, `Enter` | Expand a tree node lazily; load/select an interface or operation |
|
||
| `←`/`h` | Collapse a node or move to its parent |
|
||
| `Tab` | Cycle Tree → Selected Entry → Operations → History |
|
||
| `r` | Reobserve the selected Entry and its direct subtree |
|
||
| `c` | Cancel the newest retrieval; a dispatched operation is never presented as canceled |
|
||
| `R` | Reconnect after connection failure |
|
||
| `?` | Open help |
|
||
| `Esc` | Close a modal or return to the tree |
|
||
| `q`, `Ctrl-C` | Exit and restore the terminal |
|
||
|
||
Inside an argument editor, printable keys are field input, arrows move fields,
|
||
Backspace edits, Enter validates, and Esc cancels. The confirmation screen requires
|
||
a second explicit Enter (or `e`) to execute once. There is no operation auto-retry.
|
||
|
||
## Screen model
|
||
|
||
- **Worldspace tree** starts at `/`, lazily materializes expanded nodes, and
|
||
prefetches children for each visible Object so emptiness and the next expansion
|
||
frontier are known without selecting that Object first. Text labels distinguish
|
||
unloaded, loading, empty, stale, and failed state; color is supplemental. Every
|
||
successful expansion is complete for its requested depth.
|
||
- **Selected Entry** shows only public WIP path, object name, description, ordered
|
||
interfaces, and freshness. Validators, credentials, Host internals, and backend
|
||
paths are deliberately hidden. If current metadata disappears, old text is not
|
||
presented as current.
|
||
- **Interfaces / Operations** identifies every operation by `(interface reference,
|
||
operation name)`. Descriptor lookahead follows fresh visible Objects, shares the
|
||
client's in-flight/cache bounds, and never retries retained failures implicitly.
|
||
The pane shows descriptor documentation, ordered parameters, required/optional
|
||
status, and result types.
|
||
- **Argument editor** supports Unit, Boolean, Integer, Number, String, base64 Bytes,
|
||
Record, List, Entry, Enum, Union, Json, and descriptor-local named types. Record,
|
||
List, Union, and Json values use JSON syntax. Union input is
|
||
`{"$case":"name","value":…}` when the selected case has a payload. Diagnostics
|
||
remain attached to the failing field.
|
||
- **Recent results / diagnostics** explicitly distinguishes success, Host failure,
|
||
invalid protocol response, transport failure, client-local failure, and unknown
|
||
operation outcome. Large values, bytes, nesting, and control characters are
|
||
bounded before rendering. Only descriptor-declared `Entry` results become
|
||
navigation targets; path-looking String or Json values do not.
|
||
|
||
Terminals below 48×14 show a minimum-size screen instead of attempting the full
|
||
layout.
|
||
|
||
## Validator and failure behavior
|
||
|
||
Object and interface validators are observed and attached automatically by
|
||
`wip-client`; users neither copy nor edit them. A successful operation may update the
|
||
cached Object validator but does not by itself make the Object observation stale.
|
||
Validator mismatch, interface mismatch, `OperationOutcomeUnknown`, undecodable
|
||
post-dispatch responses, and post-dispatch timeout/disconnect are displayed using
|
||
the runtime's authoritative transition.
|
||
|
||
For an unknown outcome, the UI states that execution or side effects may have
|
||
occurred, marks the related Entry stale, and tells the user to refresh. Refreshing
|
||
does not recreate the call: the user must select the operation, review fresh input,
|
||
and explicitly execute again. The same no-auto-retry rule applies after validator
|
||
or interface mismatch.
|
||
|
||
Retrieval work runs on I/O workers while the input/render loop continues. Responses
|
||
return with the original `RequestId`, so an old completion cannot populate another
|
||
Entry's details. Canceling a retrieval records a local cancellation and drops its
|
||
late response. Once an operation crosses dispatch, cancellation is never described
|
||
as undoing execution.
|
||
|
||
## Tests
|
||
|
||
The library form keeps reducers and rendering independent of a real terminal.
|
||
`ratatui::TestBackend` snapshots cover tree/detail/result states and the minimum-size
|
||
fallback. Unit tests cover reducer focus, selection, modal confirmation, key
|
||
translation, descriptor inputs, bounded values, and descriptor-directed Entry
|
||
results. The real HTTP integration test launches `wip-fs-server` on a temporary
|
||
root and covers tree selection, reads, validator-protected replacement, external
|
||
stale-validator rejection without retry, explicit refresh/re-execution, and
|
||
symlink confinement.
|