feat(dashboard): hermes dashboard register for self-hosted OAuth client

Adds a CLI command that registers this install as a self-hosted dashboard
with the user's Nous Portal account, automating the manual browser flow on
/local-dashboards.

- New hermes_cli/dashboard_register.py: resolves a fresh Nous access token
  from auth.json (fast-fails with a `hermes setup` hint when not logged in),
  POSTs to {portal}/api/oauth/self-hosted-client, and writes
  HERMES_DASHBOARD_OAUTH_CLIENT_ID into ~/.hermes/.env idempotently.
- Docker-style adjective_noun auto-naming; --name and --redirect-uri overrides.
- Persists HERMES_DASHBOARD_PORTAL_URL only when non-default and unset (so a
  Vercel preview / staging portal sticks, prod default stays implicit).
- Refuses in managed/hosted installs (the orchestrator stamps the client_id).
- Post-register hint explains the OAuth gate only engages on a non-loopback bind.
- Nested 'register' subparser leaves bare `hermes dashboard` unchanged.
- 9 unit tests (name gen, fast-fails, POST shape, env writes, redirect URI,
  portal-URL persistence, 401/403 mapping); dashboard lifecycle tests still green.

Depends on NousResearch/nous-account-service#324 (the portal endpoint).
This commit is contained in:
Ben
2026-06-04 00:17:57 -07:00
committed by Teknium
parent 0401176c7a
commit bb291b6bbc
3 changed files with 509 additions and 0 deletions
+40
View File
@@ -11978,6 +11978,13 @@ def cmd_dashboard(args):
)
def cmd_dashboard_register(args):
"""Register a self-hosted dashboard OAuth client with Nous Portal."""
from hermes_cli.dashboard_register import cmd_dashboard_register as _impl
_impl(args)
def cmd_completion(args, parser=None):
"""Print shell completion script."""
from hermes_cli.completion import generate_bash, generate_zsh, generate_fish
@@ -15288,6 +15295,39 @@ Examples:
)
dashboard_parser.set_defaults(func=cmd_dashboard)
# `hermes dashboard register` — register a self-hosted dashboard OAuth
# client with Nous Portal and write the client_id into ~/.hermes/.env.
# Nested subparser so bare `hermes dashboard` keeps launching the server
# (set_defaults(func=cmd_dashboard) above remains the default).
dashboard_subparsers = dashboard_parser.add_subparsers(
dest="dashboard_subcommand"
)
dashboard_register_parser = dashboard_subparsers.add_parser(
"register",
help="Register a self-hosted dashboard with Nous Portal (writes the OAuth client ID to .env)",
description=(
"Register this install as a self-hosted dashboard with your Nous "
"Portal account. Creates an OAuth client, writes "
"HERMES_DASHBOARD_OAUTH_CLIENT_ID into ~/.hermes/.env, and prints "
"how to engage the login gate. Requires being logged in (hermes setup)."
),
)
dashboard_register_parser.add_argument(
"--name",
default=None,
help="Human-readable label for the dashboard (default: an auto-generated name)",
)
dashboard_register_parser.add_argument(
"--redirect-uri",
dest="redirect_uri",
default=None,
help=(
"Optional public HTTPS OAuth redirect URI for the dashboard, e.g. "
"https://hermes.example.com/auth/callback. Omit for localhost-only use."
),
)
dashboard_register_parser.set_defaults(func=cmd_dashboard_register)
# =========================================================================
# desktop (a.k.a. gui) command
#