126 lines
3.9 KiB
Markdown
126 lines
3.9 KiB
Markdown
# XO-CLI & XO-TUI
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
# Clone the CLI Repo
|
|
git clone https://git.harvmaster.com/Harvmaster/xo-cli.git
|
|
|
|
# Move into the cli directory
|
|
cd xo-cli
|
|
|
|
# Install the dependencies
|
|
npm ci
|
|
|
|
# Run the CLI
|
|
npm run dev
|
|
```
|
|
|
|
### Run TUI in dev mode
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
# Not fully tested past this point
|
|
|
|
### Install globally
|
|
|
|
```bash
|
|
# (From the xo-cli directory)
|
|
npm install -g .
|
|
```
|
|
|
|
### Install autocomplete completions (From the xo-cli directory)
|
|
|
|
These commands add `XO_CONFIG_DIR` to your shell config with a default of
|
|
`~/.config/xo-cli`. Set it to an absolute path before installing, or edit the
|
|
generated assignment, to use a different wallet-state directory.
|
|
|
|
#### Install for bash
|
|
|
|
```bash
|
|
npm run autocomplete:install:bash
|
|
```
|
|
|
|
#### Install for zsh
|
|
|
|
```bash
|
|
npm run autocomplete:install:zsh
|
|
```
|
|
|
|
#### Install for fish
|
|
|
|
```bash
|
|
npm run autocomplete:install:fish
|
|
```
|
|
|
|
### Run the CLI
|
|
|
|
```bash
|
|
# If globally installed (Not really usable if not globally installed)
|
|
xo-cli
|
|
```
|
|
|
|
### Run the TUI
|
|
|
|
```bash
|
|
# If globally installed
|
|
xo-tui
|
|
|
|
# If not globally installed
|
|
npm run dev
|
|
```
|
|
|
|
## TODO
|
|
|
|
### Track invitation sync-server connectivity without blocking the UI
|
|
|
|
Each `Invitation` currently owns a `SyncServer` instance for its invitation
|
|
identifier. The invitation uses that instance to open an SSE connection, fetch
|
|
remote state, and publish local changes. Publish requests are intentionally
|
|
fire-and-forget so that invitation actions and the TUI stay responsive when the
|
|
sync server is slow or unavailable.
|
|
|
|
The tradeoff is that failed background requests and SSE connection changes are
|
|
not represented as application state. `SyncServer` already emits `connected`,
|
|
`disconnected`, and `error` events, and `Invitation` emits errors from failed
|
|
publishes, but there is no app-level owner that aggregates those events. The UI
|
|
therefore cannot reliably tell the user that an invitation may only be updated
|
|
locally and is not currently syncing with other participants.
|
|
|
|
Implement an app-owned `InvitationConnectivityService` (or similarly named
|
|
invitation watcher) with the following responsibilities:
|
|
|
|
- Register an invitation and its `SyncServer` when `AppService` creates or loads
|
|
it, and unregister it when the invitation is removed or stopped.
|
|
- Listen for each sync server's `connected`, `disconnected`, and `error` events,
|
|
plus invitation publish failures.
|
|
- Track connectivity separately from the invitation's business status
|
|
(`actionable`, `signed`, `ready`, and so on). Suggested transport states are
|
|
`connecting`, `online`, `offline`, and `degraded`, with the last error and
|
|
last successful connection timestamp available for diagnostics.
|
|
- Expose both per-invitation state and an aggregate app-level state such as
|
|
"one or more invitations are not syncing".
|
|
- Emit normalized connectivity-change events that the CLI can log and the TUI
|
|
can subscribe to without awaiting sync-server requests.
|
|
|
|
Keep local persistence and local invitation actions independent from remote
|
|
sync health. Failed sync attempts should not freeze normal wallet interaction.
|
|
The service should provide a retry path, or observe retry events from the SSE
|
|
client, and clear the warning after connectivity recovers. If publish retries
|
|
are added, make the retry policy explicit and preserve commit idempotency.
|
|
|
|
For UI integration, inject a small notification function or subscribe at the
|
|
app-context layer rather than having invitation instances render UI directly.
|
|
The first version can show an error dialog when the aggregate state becomes
|
|
unhealthy. A less intrusive version can expose the same state as a warning icon
|
|
or message in the TUI status bar and reserve dialogs for prolonged failures or
|
|
explicit user actions.
|
|
|
|
While making this change, consolidate invitation startup ownership. Startup is
|
|
currently triggered during `Invitation.create()` and again by
|
|
`AppService.createInvitation()`. The watcher should have one clear lifecycle
|
|
point so connections, listeners, retries, and cleanup are registered exactly
|
|
once.
|