refactor(pairing): remove redundant CLI commands

CLI pairing commands (list/approve/deny/revoke) are fully replaceable by
`nanobot agent -m "/pairing ..."`, which routes through the same
CommandRouter and handle_pairing_command() backend. Removing them
cuts 86 lines of duplicate surface area without losing any functionality.

- Remove pairing_app and its 4 subcommands from cli/commands.py
- Update format_pairing_reply() to drop the "Via CLI" line
This commit is contained in:
chengyongru 2026-05-15 13:33:12 +08:00 committed by Xubin Ren
parent 88ff64be48
commit b9522e0a4d
2 changed files with 1 additions and 88 deletions

View File

@ -1620,91 +1620,5 @@ def _login_github_copilot() -> None:
raise typer.Exit(1) raise typer.Exit(1)
# ============================================================================
# Pairing Commands
# ============================================================================
pairing_app = typer.Typer(help="Manage DM pairing approvals")
app.add_typer(pairing_app, name="pairing")
@pairing_app.command("list")
def pairing_list():
"""Show pending pairing requests."""
from nanobot.pairing import format_expiry, list_pending
pending = list_pending()
if not pending:
console.print("[dim]No pending pairing requests.[/dim]")
return
table = Table(title="Pending Pairing Requests")
table.add_column("Code", style="cyan")
table.add_column("Channel", style="magenta")
table.add_column("Sender ID", style="yellow")
table.add_column("Expires", style="green")
for item in pending:
expiry = format_expiry(item.get("expires_at", 0))
table.add_row(
item["code"],
item["channel"],
item["sender_id"],
expiry,
)
console.print(table)
@pairing_app.command("approve")
def pairing_approve(
code: str = typer.Argument(..., help="Pairing code to approve"),
):
"""Approve a pending pairing code."""
from nanobot.pairing import approve_code
result = approve_code(code)
if result is None:
console.print(f"[red]✗[/red] Invalid or expired pairing code: {code}")
raise typer.Exit(1)
channel, sender_id = result
console.print(
f"[green]✓[/green] Approved pairing code {code}"
f"{sender_id} can now access {channel}"
)
@pairing_app.command("deny")
def pairing_deny(
code: str = typer.Argument(..., help="Pairing code to deny"),
):
"""Deny and discard a pending pairing code."""
from nanobot.pairing import deny_code
if deny_code(code):
console.print(f"[green]✓[/green] Denied pairing code {code}")
else:
console.print(f"[yellow]! Pairing code {code} not found or already expired[/yellow]")
@pairing_app.command("revoke")
def pairing_revoke(
channel: str = typer.Argument(..., help="Channel name (e.g. telegram)"),
user_id: str = typer.Argument(..., help="User ID to revoke"),
):
"""Revoke an approved sender from a channel."""
from nanobot.pairing import revoke
if revoke(channel, user_id):
console.print(
f"[green]✓[/green] Revoked {user_id} from {channel}"
)
else:
console.print(
f"[yellow]! {user_id} was not in the approved list for {channel}[/yellow]"
)
if __name__ == "__main__": if __name__ == "__main__":
app() app()

View File

@ -187,8 +187,7 @@ def format_pairing_reply(code: str) -> str:
"Hi there! This assistant only responds to approved users.\n\n" "Hi there! This assistant only responds to approved users.\n\n"
f"Your pairing code is: `{code}`\n\n" f"Your pairing code is: `{code}`\n\n"
"To get access, ask the owner to approve this code:\n" "To get access, ask the owner to approve this code:\n"
f"- In this chat: send `/pairing approve {code}`\n" f"- In this chat: send `/pairing approve {code}`"
f"- Via CLI: run `nanobot pairing approve {code}`"
) )