Task: Connect to a TLS broker from the shell

Table of Contents

This page documents a task in the Provisioning script library story. It captures the goal, current status, acceptance, and any notes or results.

Goal

Let the shell connect to a secured broker on its own, so a fresh system can be provisioned from the shell before (and instead of) connecting through the Qt UI — whose connect triggers the provisioning wizards. The in-REPL connect command must carry TLS and subject prefix: it reuses the connection config the shell binary was started with (options.connection) and accepts –tls-ca/–tls-cert/–tls-key/–subject-prefix overrides. The embedded Qt shell's action is always enabled (reachable before any connection); when the app is not connected the shell opens as a usable bare REPL and prints a ready-to-paste connect line with the TLS paths from the environment.

Status

Field Value
State DONE
Parent story Provisioning script library
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-06-07

Acceptance

  • connect with no TLS flags reuses the binary's startup TLS/prefix; explicit flags override; connect help and a failed plain connect surface the TLS flags.
  • The Shell action is enabled from startup; opening it before connecting gives a usable REPL with a ready-to-paste connect line including the env TLS paths.
  • A fresh system can be provisioned entirely from the embedded shell without the Qt UI connecting first.

Plan

(Implementation strategy. Written when work starts; key decisions are distilled into the parent story's * Decisions at close, but the plan itself stays — it is the historical record of what we did.)

Notes

Gemini UI review of the shell window

A screenshot of the first cut (tmp/Screenshot from 2026-06-08 00-03-05.png) was reviewed by Gemini; the verdict was that the window read as confusing and unprofessional. The review is recorded here and drove the UX pass below.

  • Visual hierarchy. The two panes competed for attention with no clear primary surface. Give the window a left sidebar (the script library) that is visually subordinate to a dominant working surface, and label each region so its role is obvious at a glance.
  • Terminal readability. The transcript was a flat wall of one colour. A terminal should be instantly scannable: the prompt in its own colour, and status markers colour-coded — red for errors, amber for warnings, green for success — matching the shell's ✗ / ⚠ / ✓ prefixes.
  • Typography and colour. Use a proper monospace face for code and the terminal; reserve the accent colours for meaning (status, syntax) so colour always carries information rather than decoration.
  • Layout / component enhancements. Drop the ad-hoc Load/Save toolbar in favour of in-context buttons on the editor itself; give the library tree real file/folder icons; syntax-highlight the editor for ores-shell so a script is readable as code.
  • Summary blueprint. Left sidebar = script library (tree + filter); centre = the editor for the selected script; bottom/right = the live terminal. One clear reading order, one primary surface.

What the UX pass changed

  • ShellMdiWindow laid out as a horizontal splitter: the script library panel (stretch 1) beside the terminal pane (stretch 3) under a "Terminal" header; the old Load/Save toolbar removed.
  • Terminal output colour-coded in on_output_ready: prompt in violet, and ✗ / ⚠ / ✓ lines in red / amber / green.
  • ScriptLibraryPanel reorganised as a vertical splitter — tree (with "Scripts" header + filter) over an editor with an in-context header and Run / Save / Save As / Delete buttons.
  • Library tree gets Folder / DocumentCode icons; library scripts open as pristine templates (Save redirects to Save As).
  • New ScriptHighlighter (QSyntaxHighlighter) highlights ores-shell: command word, --flags, quoted strings, numbers, and # comments.

PRs

PR Title
#1183 [ores.shell] Connect to a TLS broker from the shell

Review

Round 1 (2026-06-08, claude[bot], fixed in 30a0b78)

# Comment summary File Decision Notes
1 connect failure falls through to login on a disconnected session (double error) ShellMdiWindow.cpp Accepted Guarded login block behind a shell_connected flag
2 TLS hint emits empty –tls-cert/–tls-key when only some env vars set ShellMdiWindow.cpp Already fixed Hint simplified earlier; no longer echoes TLS paths
3 stale process_connect docstring (host/port/identifier) connection_commands.hpp Accepted Rewritten to connection_template + args
4 copyright year 2025 vs 2026 connection_commands.hpp Accepted Bumped to 2025-2026
5 nats_options::url default in template not obvious ShellMdiWindow.cpp Accepted Added clarifying comment at REPL construction
6 setEnabled(true) twice / has_tls on merged opts / hint ordering MainWindow.cpp, ShellMdiWindow.cpp Declined Correct as-is; cosmetic/no-op

Result

The shell can now connect to a secured broker on its own. connect reuses the connection the binary was started with (subject prefix and TLS) and accepts --tls-ca/--tls-cert/--tls-key/--subject-prefix overrides; its help lists the flags and a failed plain connect hints them. The repl carries the connection template (the standalone app passes options.connection).

In the Qt UI the Shell action is enabled from startup, and the embedded shell always opens a usable REPL: when the app is connected it connects (logging in only if the app is logged in); when it is not, it stays a bare REPL and prints a ready-to-paste connect line with the env-resolved TLS paths and subject prefix. The shell inherits its connection context (subject prefix from ORES_NATS_SUBJECT_PREFIX, TLS from ORES_NATS_TLS_*) so a script's bare connect host port works. A fresh, bootstrap-mode system can therefore be provisioned entirely from the embedded shell without the UI connecting first — which is what triggers the wizards.

The shell window was reworked for clarity per Gemini's UI review (see Notes). Iterating on the screenshots, the final form is: the script library is a pure browser (tree + filter, descriptions as tooltips), and activating a script opens a standalone editor MDI window with an icon toolbar (Run, Save, Save As, Delete) following the app's entity-window anatomy — a read-only library template disables Save rather than carrying "(read-only)" text. The editor persists its geometry via the existing DetachableMdiSubWindow / UiPersistence mechanism. The terminal colour-codes ✗ / ⚠ / ✓ output.

Scripts no longer hard-code an endpoint: the shell expands $VAR / ${VAR} in scripts and connect accepts a nats:// URL, so a script uses connect $ORES_NATS_URL. A separate fix restored compass client's --instance-name default so the status bar shows the checkout label again.

The library scripts themselves (bootstrap, provision_all) are good enough but their shape is being rethought in a follow-up task (filed in this story): rename them to per-variant <entity>_system_provision.ores (barclays = GLEIF, acme = synthetic, covering all variants) and generate them by tangling the shell recipes — the single source of truth — rather than maintaining a parallel org library.

Built clean (shell + Qt); shell tests green. Interactive GUI verification needs a display and is left for manual testing.

Emacs 29.1 (Org mode 9.6.6)