# 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 scope, interface name, operation name)` and explicitly displays `scope=…` and `name=…`. Structured references remain intact in selection, acquisition, and call state; display labels are never parsed back into references. 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.