# XO-CLI & XO-TUI ## Installation ### Full Installation ```bash # Create a new directory since we are going to be pulling in engine too mkdir xo-terminal && cd xo-terminal # ----- Start State Setup ----- # Clone the State Repo git clone https://gitlab.com/Harvmaster/state.git # Move into the state directory cd state git checkout cli-test # Install the dependencies npm ci # Build the state npm run build # ----- End State Setup ----- # Move back to the top level directory cd .. # ----- Start Primitive Setup ----- git clone git@gitlab.com:GeneralProtocols/xo/primitives.git cd primitives git checkout update/syncup-ui-requirements npm ci npm run build # ----- End Primitive Setup ----- # Move back to the top level directory cd .. # ----- Start Utils Setup ----- git clone git@gitlab.com:Harvmaster/xo-cash-utils.git utils cd utils git checkout sse-and-backoff npm ci npm run build # ----- End Utils Setup # Move back to the top level directory cd .. # ----- Start Template Setup ---- # Clone the Template repo git clone https://gitlab.com/Harvmaster/templates.git # Move into themplates directory cd templates # Install deps npm ci #build the templates npm run build # ----- End Templates Setup ---- # Move back to the top level directory cd .. # ----- Start Engine Setup ----- # Clone the Engine Repo (Note, this uses harvey's fork of the engine repo to access the cli-test branch) git clone https://gitlab.com/Harvmaster/engine.git # Move into teh engine directory cd engine # Checkout the cli-test branch git checkout cli-test-update # Install the dependencies npm ci # Build the engine npm run build # ----- End Engine Setup ----- # Move back to the top level directory cd .. # ----- Start CLI Setup ----- # Clone the CLI Repo git clone https://git.harvmaster.com/Harvmaster/xo-cli.git # Move into the cli directory cd xo-cli git checkout kiok-update # Install the dependencies npm ci # Build the cli npm run build # ----- End CLI Setup ----- ``` ### Run TUI in dev mode ```bash npm run dev ``` ### Install globally ```bash # (From the xo-cli directory) npm install -g . ``` ### Install autocomplete completions (From the xo-cli 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.