mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
188 lines
5.4 KiB
Python
188 lines
5.4 KiB
Python
"""AstrBot CLI entry point"""
|
|
|
|
import os
|
|
import platform
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import click
|
|
from click.shell_completion import get_completion_class
|
|
|
|
from . import __version__
|
|
from .commands import bk, config, init, password, plugin, run, service, uninstall
|
|
from .i18n import t
|
|
|
|
|
|
def print_version_detail() -> None:
|
|
"""Print detailed version info (same for --version and version command)"""
|
|
from astrbot.core.utils.astrbot_path import astrbot_paths
|
|
|
|
click.echo(f"AstrBot: {__version__}")
|
|
click.echo(f"Python: {sys.version.split()[0]}")
|
|
click.echo(f"System: {platform.system()} {platform.release()}")
|
|
click.echo(f"Machine: {platform.machine()}")
|
|
|
|
git_root = Path(astrbot_paths.root) / ".git"
|
|
if git_root.exists():
|
|
import subprocess
|
|
|
|
try:
|
|
git_hash = subprocess.check_output(
|
|
["git", "rev-parse", "--short", "HEAD"],
|
|
cwd=str(astrbot_paths.root),
|
|
text=True,
|
|
).strip()
|
|
git_branch = subprocess.check_output(
|
|
["git", "rev-parse", "--abbrev-ref", "HEAD"],
|
|
cwd=str(astrbot_paths.root),
|
|
text=True,
|
|
).strip()
|
|
click.echo(f"Git Branch: {git_branch}")
|
|
click.echo(f"Git Commit: {git_hash}")
|
|
except Exception:
|
|
pass
|
|
|
|
click.echo(f"AstrBot Root: {astrbot_paths.root}")
|
|
click.echo(f"Platform: {platform.platform()}")
|
|
|
|
|
|
def version_callback(ctx: click.Context, param: click.Parameter, value: bool) -> bool:
|
|
"""Callback for --version to show detailed version and exit."""
|
|
if not value:
|
|
return value
|
|
print_version_detail()
|
|
ctx.exit()
|
|
return value
|
|
|
|
|
|
class AstrBotCLIGroup(click.Group):
|
|
COMMAND_ALIASES = {
|
|
"conf": "config",
|
|
"plug": "plugin",
|
|
}
|
|
|
|
def get_command(self, ctx: click.Context, cmd_name: str) -> click.Command | None:
|
|
command = super().get_command(ctx, cmd_name)
|
|
if command is not None:
|
|
return command
|
|
alias_target = self.COMMAND_ALIASES.get(cmd_name)
|
|
if alias_target is None:
|
|
return None
|
|
return super().get_command(ctx, alias_target)
|
|
|
|
|
|
@click.group(cls=AstrBotCLIGroup)
|
|
@click.version_option(__version__, prog_name="AstrBot")
|
|
def cli() -> None:
|
|
"""Astrbot
|
|
Agentic IM Chatbot infrastructure that integrates lots of IM platforms, LLMs, plugins and AI feature, and can be your openclaw alternative. ✨
|
|
"""
|
|
|
|
|
|
@click.command()
|
|
@click.argument("command_name", required=False, type=str)
|
|
@click.option(
|
|
"--all",
|
|
"-a",
|
|
is_flag=True,
|
|
help="Show help for all commands recursively.",
|
|
)
|
|
def help(command_name: str | None, all: bool) -> None:
|
|
"""Display help information for commands
|
|
|
|
If COMMAND_NAME is provided, display detailed help for that command.
|
|
Otherwise, display general help information.
|
|
"""
|
|
ctx = click.get_current_context()
|
|
|
|
if all:
|
|
|
|
def print_recursive_help(command, parent_ctx):
|
|
name = command.name
|
|
if parent_ctx is None:
|
|
name = "astrbot"
|
|
|
|
cmd_ctx = click.Context(command, info_name=name, parent=parent_ctx)
|
|
click.echo(command.get_help(cmd_ctx))
|
|
click.echo("\n" + "-" * 50 + "\n")
|
|
|
|
if isinstance(command, click.Group):
|
|
for subcommand in command.commands.values():
|
|
print_recursive_help(subcommand, cmd_ctx)
|
|
|
|
print_recursive_help(cli, None)
|
|
return
|
|
|
|
if command_name:
|
|
# Find the specified command
|
|
command = cli.get_command(ctx, command_name)
|
|
if command:
|
|
# Display help for the specific command
|
|
parent = ctx.parent or ctx
|
|
cmd_ctx = click.Context(command, info_name=command.name, parent=parent)
|
|
click.echo(command.get_help(cmd_ctx))
|
|
else:
|
|
click.echo(t("cli_unknown_command", command=command_name))
|
|
sys.exit(1)
|
|
else:
|
|
# Display general help information
|
|
click.echo(cli.get_help(ctx))
|
|
|
|
|
|
cli.add_command(init)
|
|
cli.add_command(run)
|
|
cli.add_command(help)
|
|
cli.add_command(plugin)
|
|
cli.add_command(config)
|
|
cli.add_command(uninstall)
|
|
cli.add_command(bk)
|
|
cli.add_command(password)
|
|
cli.add_command(service)
|
|
|
|
|
|
@click.command()
|
|
@click.argument("shell", required=False, type=click.Choice(["bash", "zsh", "fish"]))
|
|
def completion(shell: str | None) -> None:
|
|
"""Generate shell completion script"""
|
|
if shell is None:
|
|
shell_path = os.environ.get("SHELL", "")
|
|
if "zsh" in shell_path:
|
|
shell = "zsh"
|
|
elif "bash" in shell_path:
|
|
shell = "bash"
|
|
elif "fish" in shell_path:
|
|
shell = "fish"
|
|
else:
|
|
click.echo(
|
|
"Could not detect shell. Please specify one of: bash, zsh, fish",
|
|
err=True,
|
|
)
|
|
sys.exit(1)
|
|
|
|
comp_cls = get_completion_class(shell)
|
|
if comp_cls is None:
|
|
click.echo(f"No completion support for shell: {shell}", err=True)
|
|
sys.exit(1)
|
|
comp = comp_cls(
|
|
cli,
|
|
ctx_args={},
|
|
prog_name="astrbot",
|
|
complete_var="_ASTRBOT_COMPLETE",
|
|
)
|
|
click.echo(comp.source())
|
|
|
|
|
|
cli.add_command(completion)
|
|
|
|
|
|
@click.command(name="version")
|
|
def version_cmd() -> None:
|
|
"""Display detailed version information"""
|
|
print_version_detail()
|
|
|
|
|
|
cli.add_command(version_cmd)
|
|
|
|
if __name__ == "__main__":
|
|
cli()
|