Improve connection UX based on feedback

Web UI:
- Change sidebar "API Tokens" to "Connections"
- Change empty state button to "Make Your First Connection"
- Add TUI option to "About Connected Apps" info banner
- Add both TUI and CLI options to pairing modal

TUI:
- Change dialog title to "Connect to your CmdForge Account"
- Add account creation hint in username prompt
- Improve instructions with full URL and steps
- Fix timer refresh by calling loop.draw_screen()

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
rob 2026-01-14 01:45:01 -04:00
parent 367fac204b
commit d2c668dc99
4 changed files with 22 additions and 14 deletions

View File

@ -489,8 +489,9 @@ class CmdForgeUI:
# Show waiting dialog
status_text = urwid.Text(('label', f"Connecting as @{username}...\nDevice: {hostname}\n\nWaiting for approval..."))
instructions = urwid.Text(
"\nGo to cmdforge.brrd.tech/dashboard/connected-apps\n"
"and click 'Connect New App' to approve."
"\nIn your browser, go to:\n"
" https://cmdforge.brrd.tech/dashboard/connected-apps\n"
"and click 'Connect New App', then 'I've Run the Command'."
)
countdown_text = urwid.Text(('label', "Expires in 5:00"))
@ -510,7 +511,7 @@ class CmdForgeUI:
self.close_overlay()
dialog = Dialog("Connecting...", body, [("Cancel", on_cancel)])
self.show_overlay(dialog, width=55, height=16)
self.show_overlay(dialog, width=60, height=18)
def poll_for_connection():
"""Background thread to poll for connection."""
@ -524,14 +525,14 @@ class CmdForgeUI:
self.loop.set_alarm_in(0, lambda l, d: self._on_connect_timeout())
return
# Update countdown
# Update countdown - capture values to avoid closure issues
remaining = int(max_time - elapsed)
mins = remaining // 60
secs = remaining % 60
def update_countdown(l, d, m=mins, s=secs):
def update_countdown(loop, data, m=mins, s=secs):
countdown_text.set_text(('label', f"Expires in {m}:{s:02d}"))
self.refresh()
loop.draw_screen()
if self.loop:
self.loop.set_alarm_in(0, update_countdown)
@ -550,8 +551,10 @@ class CmdForgeUI:
token = data.get("data", {}).get("token")
if token:
set_registry_token(token)
def on_success(loop, data):
self._on_connect_success(tool, version, username, hostname)
if self.loop:
self.loop.set_alarm_in(0, lambda l, d: self._on_connect_success(tool, version, username, hostname))
self.loop.set_alarm_in(0, on_success)
return
except Exception:
@ -564,8 +567,8 @@ class CmdForgeUI:
thread.start()
self.input_dialog(
"Connect Account",
"Enter your CmdForge username",
"Connect to your CmdForge Account",
"Username (create account at cmdforge.brrd.tech)",
"",
on_username
)

View File

@ -47,7 +47,7 @@
<svg class="w-5 h-5 mr-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/>
</svg>
API Tokens
Connections
</a>
<a href="{{ url_for('web.dashboard_settings') }}"
class="flex items-center px-4 py-3 text-sm font-medium {{ 'bg-indigo-50 text-indigo-700 border-l-4 border-indigo-600' if active_page == 'settings' else 'text-gray-700 hover:bg-gray-50' }}">

View File

@ -42,7 +42,7 @@
</svg>
</div>
<div class="ml-4">
<p class="text-sm text-gray-500">API Tokens</p>
<p class="text-sm text-gray-500">Connections</p>
<p class="text-2xl font-bold text-gray-900">{{ stats.tokens_count }}</p>
</div>
</div>

View File

@ -31,7 +31,8 @@
<h4 class="text-sm font-medium text-blue-800">About Connected Apps</h4>
<p class="mt-1 text-sm text-blue-700">
Connected apps can publish tools and sync your work across devices.
Run <code class="px-1 bg-blue-100 rounded">cmdforge config connect &lt;username&gt;</code> in your terminal,
You can connect via the <strong>TUI</strong> (<code class="px-1 bg-blue-100 rounded">cmdforge ui</code> → Connect button)
or run <code class="px-1 bg-blue-100 rounded">cmdforge config connect {{ user.slug }}</code> in your terminal,
then click "Connect New App" here to complete the connection.
</p>
</div>
@ -106,7 +107,7 @@
<button type="button"
onclick="startPairing()"
class="mt-6 inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-indigo-600 rounded-md hover:bg-indigo-700">
Connect Your First App
Make Your First Connection
</button>
</div>
{% endif %}
@ -128,8 +129,12 @@
<div id="pairing-step-1">
<p class="text-sm text-gray-600 mb-4">
To connect a new app, run this command in your terminal:
To connect a new app, use <strong>either</strong> method:
</p>
<p class="text-sm text-gray-700 mb-2"><strong>Option 1: TUI</strong></p>
<pre class="bg-gray-900 text-gray-100 text-sm p-3 rounded-lg overflow-x-auto mb-3"><code>cmdforge ui</code></pre>
<p class="text-xs text-gray-500 mb-4">Then click the "Connect" button in the UI.</p>
<p class="text-sm text-gray-700 mb-2"><strong>Option 2: Command Line</strong></p>
<pre class="bg-gray-900 text-gray-100 text-sm p-3 rounded-lg overflow-x-auto mb-4"><code>cmdforge config connect {{ user.slug }}</code></pre>
<p class="text-sm text-gray-600 mb-4">
Then click the button below to complete the connection.