feat(cli): make hermes portal the human-readable Portal onboarding alias
`hermes portal` (no subcommand) now runs the one-shot Nous Portal onboarding — OAuth login, switch provider to Nous, offer Tool Gateway — identical to `hermes setup --portal` and the human-readable alias for `hermes auth add nous --type oauth` (which still works). The prior status default moves to `hermes portal info`; `status` is kept as a hidden back-compat alias. `open`/`tools` subcommands are unchanged. User-facing hints and docs (status.py, conversation_loop 401 guidance, SystemPage, README, website docs + zh-Hans) now point at `hermes portal` / `hermes portal info`. `--manual-paste` references keep the explicit auth command since `hermes portal` does not expose that flag.
This commit is contained in:
parent
39fee4f3bc
commit
da4f407e51
21 changed files with 212 additions and 58 deletions
|
|
@ -1,12 +1,20 @@
|
|||
"""``hermes portal`` — small CLI surface for Nous Portal users.
|
||||
"""``hermes portal`` — the human-readable entry point for Nous Portal.
|
||||
|
||||
Running ``hermes portal`` with no subcommand performs the one-shot Portal
|
||||
onboarding: OAuth login, switch the inference provider to Nous, and offer to
|
||||
enable the Tool Gateway. It is the friendly alias for
|
||||
``hermes auth add nous --type oauth`` (which still works) and is identical to
|
||||
``hermes setup --portal``.
|
||||
|
||||
Subcommands:
|
||||
status Show Portal auth state + which Tool Gateway tools are routed.
|
||||
(none) Log in to Nous Portal + set it up (one-shot onboarding).
|
||||
login Explicit alias for the default one-shot onboarding.
|
||||
info Show Portal auth state + which Tool Gateway tools are routed.
|
||||
open Open the Portal subscription page in the user's default browser.
|
||||
tools List Tool Gateway tools and which are active in the current config.
|
||||
|
||||
This command is intentionally minimal — it does not duplicate functionality
|
||||
already in ``hermes auth`` or ``hermes tools``. It's a discovery + status
|
||||
already in ``hermes auth`` or ``hermes tools``. It's the onboarding + discovery
|
||||
surface for the Portal subscription itself.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
|
@ -49,7 +57,7 @@ def _cmd_status(args) -> int:
|
|||
else:
|
||||
print(f" Auth: {color('not logged in', Colors.YELLOW)}")
|
||||
print(f" Sign up: {SUBSCRIPTION_URL}")
|
||||
print(f" Login: hermes auth add nous --type oauth")
|
||||
print(f" Login: hermes portal")
|
||||
|
||||
# Provider selection (independent of auth)
|
||||
model_cfg = config.get("model") if isinstance(config.get("model"), dict) else {}
|
||||
|
|
@ -134,7 +142,7 @@ def _cmd_tools(args) -> int:
|
|||
print(color(" ────────────────────", Colors.MAGENTA))
|
||||
|
||||
if not features.nous_auth_present:
|
||||
print(color(" Not logged into Nous Portal — sign in with `hermes auth add nous --type oauth`.", Colors.YELLOW))
|
||||
print(color(" Not logged into Nous Portal — sign in with `hermes portal`.", Colors.YELLOW))
|
||||
print()
|
||||
|
||||
label_width = max(len(label) for _, label, _ in catalog)
|
||||
|
|
@ -158,14 +166,36 @@ def _cmd_tools(args) -> int:
|
|||
return 0
|
||||
|
||||
|
||||
def _cmd_login(args) -> int:
|
||||
"""Run the one-shot Nous Portal onboarding (OAuth + provider + Tool Gateway).
|
||||
|
||||
This is the human-readable front door for `hermes auth add nous --type
|
||||
oauth`. It reuses the exact wiring behind `hermes setup --portal` so the
|
||||
two commands stay in lockstep: device-code login, switch the inference
|
||||
provider to Nous, then offer the Tool Gateway opt-in.
|
||||
"""
|
||||
from hermes_cli.setup import _run_portal_one_shot
|
||||
|
||||
config = load_config() or {}
|
||||
try:
|
||||
_run_portal_one_shot(config)
|
||||
except (KeyboardInterrupt, EOFError):
|
||||
print()
|
||||
print("Portal setup cancelled.")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def portal_command(args) -> int:
|
||||
"""Top-level dispatch for `hermes portal <subcommand>`."""
|
||||
sub = getattr(args, "portal_command", None)
|
||||
if sub in {None, ""}:
|
||||
# Default to status — matches gh / kubectl conventions where the
|
||||
# subcommand-less form gives a useful overview.
|
||||
return _cmd_status(args)
|
||||
if sub == "status":
|
||||
if sub in {None, "", "login"}:
|
||||
# Default to the one-shot onboarding — `hermes portal` is the
|
||||
# human-readable alias for `hermes auth add nous --type oauth` /
|
||||
# `hermes setup --portal`.
|
||||
return _cmd_login(args)
|
||||
if sub in {"info", "status"}:
|
||||
# `status` kept as a back-compat alias for the prior default.
|
||||
return _cmd_status(args)
|
||||
if sub == "open":
|
||||
return _cmd_open(args)
|
||||
|
|
@ -180,19 +210,26 @@ def add_parser(subparsers) -> None:
|
|||
"""Register `hermes portal` on the given argparse subparsers object."""
|
||||
portal_parser = subparsers.add_parser(
|
||||
"portal",
|
||||
help="Nous Portal status, subscription, and Tool Gateway routing",
|
||||
help="Set up Nous Portal (OAuth login + Tool Gateway); see also `portal info`",
|
||||
description=(
|
||||
"Inspect Nous Portal auth, Tool Gateway routing, and open the "
|
||||
"Portal subscription page. Subcommands: status (default), "
|
||||
"open, tools."
|
||||
"Run `hermes portal` with no subcommand to log in to Nous Portal "
|
||||
"and set it up (the human-readable alias for `hermes auth add nous "
|
||||
"--type oauth`, identical to `hermes setup --portal`). Subcommands: "
|
||||
"login (default), info, open, tools."
|
||||
),
|
||||
)
|
||||
portal_sub = portal_parser.add_subparsers(dest="portal_command")
|
||||
|
||||
portal_sub.add_parser(
|
||||
"status",
|
||||
help="Show Portal auth + Tool Gateway routing summary (default)",
|
||||
"login",
|
||||
help="Log in to Nous Portal + set it up (default; one-shot onboarding)",
|
||||
)
|
||||
portal_sub.add_parser(
|
||||
"info",
|
||||
help="Show Portal auth + Tool Gateway routing summary",
|
||||
)
|
||||
# `status` retained as a hidden back-compat alias for `info`.
|
||||
portal_sub.add_parser("status")
|
||||
portal_sub.add_parser(
|
||||
"open",
|
||||
help="Open the Portal subscription page in your default browser",
|
||||
|
|
|
|||
|
|
@ -2828,7 +2828,7 @@ def _run_portal_one_shot(config: dict) -> None:
|
|||
|
||||
print()
|
||||
print_success("Portal setup complete.")
|
||||
print_info(" Run `hermes portal status` to inspect routing.")
|
||||
print_info(" Run `hermes portal info` to inspect routing.")
|
||||
print_info(" Run `hermes` to start chatting.")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ def show_status(args):
|
|||
elif nous_inference_present:
|
||||
nous_label = "not logged in (Nous inference key configured)"
|
||||
else:
|
||||
nous_label = "not logged in (run: hermes auth add nous --type oauth)"
|
||||
nous_label = "not logged in (run: hermes portal)"
|
||||
print(
|
||||
f" {'Nous Portal':<12} {check_mark(nous_logged_in)} "
|
||||
f"{nous_label}"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue