docs(cli): add per-command CLI pages
This commit is contained in:
@@ -47,8 +47,8 @@ export function registerChannelsCli(program: Command) {
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink(
|
||||
"/configuration",
|
||||
"docs.clawd.bot/configuration",
|
||||
"/cli/channels",
|
||||
"docs.clawd.bot/cli/channels",
|
||||
)}\n`,
|
||||
);
|
||||
|
||||
|
||||
@@ -18,8 +18,7 @@ export function registerCronCli(program: Command) {
|
||||
.description("Manage cron jobs (via Gateway)")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cron-jobs", "docs.clawd.bot/cron-jobs")}\n`,
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/cron", "docs.clawd.bot/cli/cron")}\n`,
|
||||
);
|
||||
|
||||
registerCronStatusCommand(cron);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { Command } from "commander";
|
||||
import { danger } from "../../globals.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { formatDocsLink } from "../../terminal/links.js";
|
||||
import { theme } from "../../terminal/theme.js";
|
||||
import type { GatewayRpcOpts } from "../gateway-rpc.js";
|
||||
import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js";
|
||||
|
||||
@@ -12,6 +14,10 @@ export function registerWakeCommand(program: Command) {
|
||||
.requiredOption("--text <text>", "System event text")
|
||||
.option("--mode <mode>", "Wake mode (now|next-heartbeat)", "next-heartbeat")
|
||||
.option("--json", "Output JSON", false),
|
||||
)
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/wake", "docs.clawd.bot/cli/wake")}\n`,
|
||||
).action(async (opts: GatewayRpcOpts & { text?: string; mode?: string }) => {
|
||||
try {
|
||||
const result = await callGatewayFromCli(
|
||||
|
||||
@@ -17,7 +17,8 @@ export function registerDaemonCli(program: Command) {
|
||||
.description("Manage the Gateway daemon service (launchd/systemd/schtasks)")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/gateway", "docs.clawd.bot/gateway")}\n`,
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/daemon", "docs.clawd.bot/cli/daemon")}\n`,
|
||||
);
|
||||
|
||||
daemon
|
||||
|
||||
@@ -7,6 +7,8 @@ import type { Command } from "commander";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js";
|
||||
import { getWideAreaZonePath, WIDE_AREA_DISCOVERY_DOMAIN } from "../infra/widearea-dns.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
import { theme } from "../terminal/theme.js";
|
||||
|
||||
type RunOpts = { allowFailure?: boolean; inherit?: boolean };
|
||||
|
||||
@@ -90,7 +92,11 @@ function ensureImportLine(corefilePath: string, importGlob: string): boolean {
|
||||
export function registerDnsCli(program: Command) {
|
||||
const dns = program
|
||||
.command("dns")
|
||||
.description("DNS helpers for wide-area discovery (Tailscale + CoreDNS)");
|
||||
.description("DNS helpers for wide-area discovery (Tailscale + CoreDNS)")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/dns", "docs.clawd.bot/cli/dns")}\n`,
|
||||
);
|
||||
|
||||
dns
|
||||
.command("setup")
|
||||
|
||||
@@ -12,7 +12,7 @@ export function registerDocsCli(program: Command) {
|
||||
.argument("[query...]", "Search query")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/hubs", "docs.clawd.bot/hubs")}\n`,
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/docs", "docs.clawd.bot/cli/docs")}\n`,
|
||||
)
|
||||
.action(async (queryParts: string[]) => {
|
||||
try {
|
||||
|
||||
@@ -25,7 +25,8 @@ export function registerGatewayCli(program: Command) {
|
||||
.description("Run the WebSocket Gateway")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/gateway", "docs.clawd.bot/gateway")}\n`,
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/gateway", "docs.clawd.bot/cli/gateway")}\n`,
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -18,9 +18,17 @@ import {
|
||||
runGmailSetup,
|
||||
} from "../hooks/gmail-ops.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
import { theme } from "../terminal/theme.js";
|
||||
|
||||
export function registerHooksCli(program: Command) {
|
||||
const hooks = program.command("hooks").description("Webhook helpers and hook-based integrations");
|
||||
const hooks = program
|
||||
.command("hooks")
|
||||
.description("Webhook helpers and hook-based integrations")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/hooks", "docs.clawd.bot/cli/hooks")}\n`,
|
||||
);
|
||||
|
||||
const gmail = hooks.command("gmail").description("Gmail Pub/Sub hooks (via gogcli)");
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ export function registerLogsCli(program: Command) {
|
||||
.option("--no-color", "Disable ANSI colors")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/logging", "docs.clawd.bot/logging")}\n`,
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/logs", "docs.clawd.bot/cli/logs")}\n`,
|
||||
);
|
||||
|
||||
addGatewayClientOptions(logs);
|
||||
|
||||
@@ -5,6 +5,8 @@ import { resolveDefaultAgentId } from "../agents/agent-scope.js";
|
||||
import { loadConfig } from "../config/config.js";
|
||||
import { getMemorySearchManager } from "../memory/index.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
import { theme } from "../terminal/theme.js";
|
||||
|
||||
type MemoryCommandOptions = {
|
||||
agent?: string;
|
||||
@@ -18,7 +20,13 @@ function resolveAgent(cfg: ReturnType<typeof loadConfig>, agent?: string) {
|
||||
}
|
||||
|
||||
export function registerMemoryCli(program: Command) {
|
||||
const memory = program.command("memory").description("Memory search tools");
|
||||
const memory = program
|
||||
.command("memory")
|
||||
.description("Memory search tools")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/memory", "docs.clawd.bot/cli/memory")}\n`,
|
||||
);
|
||||
|
||||
memory
|
||||
.command("status")
|
||||
|
||||
@@ -37,7 +37,8 @@ export function registerModelsCli(program: Command) {
|
||||
.option("--status-plain", "Plain output (alias for `models status --plain`)", false)
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/models", "docs.clawd.bot/models")}\n`,
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/models", "docs.clawd.bot/cli/models")}\n`,
|
||||
);
|
||||
|
||||
models
|
||||
|
||||
@@ -16,7 +16,7 @@ export function registerNodesCli(program: Command) {
|
||||
.description("Manage gateway-owned node pairing")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/nodes", "docs.clawd.bot/nodes")}\n`,
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/nodes", "docs.clawd.bot/cli/nodes")}\n`,
|
||||
);
|
||||
|
||||
registerNodesStatusCommands(nodes);
|
||||
|
||||
@@ -11,6 +11,8 @@ import {
|
||||
listChannelPairingRequests,
|
||||
type PairingChannel,
|
||||
} from "../pairing/pairing-store.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
import { theme } from "../terminal/theme.js";
|
||||
|
||||
const CHANNELS: PairingChannel[] = listPairingChannels();
|
||||
|
||||
@@ -26,7 +28,12 @@ async function notifyApproved(channel: PairingChannel, id: string) {
|
||||
export function registerPairingCli(program: Command) {
|
||||
const pairing = program
|
||||
.command("pairing")
|
||||
.description("Secure DM pairing (approve inbound requests)");
|
||||
.description("Secure DM pairing (approve inbound requests)")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/pairing", "docs.clawd.bot/cli/pairing")}\n`,
|
||||
);
|
||||
|
||||
pairing
|
||||
.command("list")
|
||||
|
||||
@@ -54,7 +54,14 @@ function formatPluginLine(plugin: PluginRecord, verbose = false): string {
|
||||
}
|
||||
|
||||
export function registerPluginsCli(program: Command) {
|
||||
const plugins = program.command("plugins").description("Manage Clawdbot plugins/extensions");
|
||||
const plugins = program
|
||||
.command("plugins")
|
||||
.description("Manage Clawdbot plugins/extensions")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/plugins", "docs.clawd.bot/cli/plugins")}\n`,
|
||||
);
|
||||
|
||||
plugins
|
||||
.command("list")
|
||||
|
||||
@@ -48,7 +48,7 @@ Examples:
|
||||
clawdbot agent --to +15555550123 --message "Trace logs" --verbose on --json
|
||||
clawdbot agent --to +15555550123 --message "Summon reply" --deliver
|
||||
|
||||
${theme.muted("Docs:")} ${formatDocsLink("/agent-send", "docs.clawd.bot/agent-send")}`,
|
||||
${theme.muted("Docs:")} ${formatDocsLink("/cli/agent", "docs.clawd.bot/cli/agent")}`,
|
||||
)
|
||||
.action(async (opts) => {
|
||||
const verboseLevel = typeof opts.verbose === "string" ? opts.verbose.toLowerCase() : "";
|
||||
@@ -65,7 +65,11 @@ ${theme.muted("Docs:")} ${formatDocsLink("/agent-send", "docs.clawd.bot/agent-se
|
||||
|
||||
const agents = program
|
||||
.command("agents")
|
||||
.description("Manage isolated agents (workspaces + auth + routing)");
|
||||
.description("Manage isolated agents (workspaces + auth + routing)")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/agents", "docs.clawd.bot/cli/agents")}\n`,
|
||||
);
|
||||
|
||||
agents
|
||||
.command("list")
|
||||
|
||||
@@ -5,6 +5,8 @@ import {
|
||||
configureCommandWithSections,
|
||||
} from "../../commands/configure.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { formatDocsLink } from "../../terminal/links.js";
|
||||
import { theme } from "../../terminal/theme.js";
|
||||
|
||||
export function registerConfigureCommand(program: Command) {
|
||||
const register = (name: "configure" | "config") => {
|
||||
@@ -15,6 +17,11 @@ export function registerConfigureCommand(program: Command) {
|
||||
? "Alias for `clawdbot configure`"
|
||||
: "Interactive prompt to set up credentials, devices, and agent defaults",
|
||||
)
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/configure", "docs.clawd.bot/cli/configure")}\n`,
|
||||
)
|
||||
.option(
|
||||
"--section <section>",
|
||||
`Configuration sections (repeatable). Options: ${CONFIGURE_WIZARD_SECTIONS.join(", ")}`,
|
||||
|
||||
@@ -4,11 +4,17 @@ import { doctorCommand } from "../../commands/doctor.js";
|
||||
import { resetCommand } from "../../commands/reset.js";
|
||||
import { uninstallCommand } from "../../commands/uninstall.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { formatDocsLink } from "../../terminal/links.js";
|
||||
import { theme } from "../../terminal/theme.js";
|
||||
|
||||
export function registerMaintenanceCommands(program: Command) {
|
||||
program
|
||||
.command("doctor")
|
||||
.description("Health checks + quick fixes for the gateway and channels")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/doctor", "docs.clawd.bot/cli/doctor")}\n`,
|
||||
)
|
||||
.option("--no-workspace-suggestions", "Disable workspace memory system suggestions", false)
|
||||
.option("--yes", "Accept defaults without prompting", false)
|
||||
.option("--repair", "Apply recommended repairs without prompting", false)
|
||||
@@ -36,6 +42,11 @@ export function registerMaintenanceCommands(program: Command) {
|
||||
program
|
||||
.command("dashboard")
|
||||
.description("Open the Control UI with your current token")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/dashboard", "docs.clawd.bot/cli/dashboard")}\n`,
|
||||
)
|
||||
.option("--no-open", "Print URL but do not launch a browser", false)
|
||||
.action(async (opts) => {
|
||||
try {
|
||||
@@ -51,6 +62,10 @@ export function registerMaintenanceCommands(program: Command) {
|
||||
program
|
||||
.command("reset")
|
||||
.description("Reset local config/state (keeps the CLI installed)")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/reset", "docs.clawd.bot/cli/reset")}\n`,
|
||||
)
|
||||
.option("--scope <scope>", "config|config+creds+sessions|full (default: interactive prompt)")
|
||||
.option("--yes", "Skip confirmation prompts", false)
|
||||
.option("--non-interactive", "Disable prompts (requires --scope + --yes)", false)
|
||||
@@ -72,6 +87,11 @@ export function registerMaintenanceCommands(program: Command) {
|
||||
program
|
||||
.command("uninstall")
|
||||
.description("Uninstall the gateway service + local data (CLI remains)")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/uninstall", "docs.clawd.bot/cli/uninstall")}\n`,
|
||||
)
|
||||
.option("--service", "Remove the gateway service", false)
|
||||
.option("--state", "Remove state + config", false)
|
||||
.option("--workspace", "Remove workspace dirs", false)
|
||||
|
||||
@@ -9,6 +9,8 @@ import type {
|
||||
TailscaleMode,
|
||||
} from "../../commands/onboard-types.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { formatDocsLink } from "../../terminal/links.js";
|
||||
import { theme } from "../../terminal/theme.js";
|
||||
|
||||
function resolveInstallDaemonFlag(
|
||||
command: unknown,
|
||||
@@ -32,6 +34,11 @@ export function registerOnboardCommand(program: Command) {
|
||||
program
|
||||
.command("onboard")
|
||||
.description("Interactive wizard to set up the gateway, workspace, and skills")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/onboard", "docs.clawd.bot/cli/onboard")}\n`,
|
||||
)
|
||||
.option("--workspace <dir>", "Agent workspace directory (default: ~/clawd)")
|
||||
.option("--reset", "Reset config + credentials + sessions + workspace before running wizard")
|
||||
.option("--non-interactive", "Run without prompts", false)
|
||||
|
||||
@@ -2,12 +2,18 @@ import type { Command } from "commander";
|
||||
import { onboardCommand } from "../../commands/onboard.js";
|
||||
import { setupCommand } from "../../commands/setup.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { formatDocsLink } from "../../terminal/links.js";
|
||||
import { theme } from "../../terminal/theme.js";
|
||||
import { hasExplicitOptions } from "../command-options.js";
|
||||
|
||||
export function registerSetupCommand(program: Command) {
|
||||
program
|
||||
.command("setup")
|
||||
.description("Initialize ~/.clawdbot/clawdbot.json and the agent workspace")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/setup", "docs.clawd.bot/cli/setup")}\n`,
|
||||
)
|
||||
.option(
|
||||
"--workspace <dir>",
|
||||
"Agent workspace directory (default: ~/clawd; stored as agents.defaults.workspace)",
|
||||
|
||||
@@ -4,6 +4,8 @@ import { sessionsCommand } from "../../commands/sessions.js";
|
||||
import { statusCommand } from "../../commands/status.js";
|
||||
import { setVerbose } from "../../globals.js";
|
||||
import { defaultRuntime } from "../../runtime.js";
|
||||
import { formatDocsLink } from "../../terminal/links.js";
|
||||
import { theme } from "../../terminal/theme.js";
|
||||
import { parsePositiveIntOrUndefined } from "./helpers.js";
|
||||
|
||||
export function registerStatusHealthSessionsCommands(program: Command) {
|
||||
@@ -29,6 +31,10 @@ Examples:
|
||||
clawdbot status --deep --timeout 5000 # tighten probe timeout
|
||||
clawdbot channels status # gateway channel runtime + probes`,
|
||||
)
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/status", "docs.clawd.bot/cli/status")}\n`,
|
||||
)
|
||||
.action(async (opts) => {
|
||||
const verbose = Boolean(opts.verbose || opts.debug);
|
||||
setVerbose(verbose);
|
||||
@@ -63,6 +69,10 @@ Examples:
|
||||
.option("--timeout <ms>", "Connection timeout in milliseconds", "10000")
|
||||
.option("--verbose", "Verbose logging", false)
|
||||
.option("--debug", "Alias for --verbose", false)
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/health", "docs.clawd.bot/cli/health")}\n`,
|
||||
)
|
||||
.action(async (opts) => {
|
||||
const verbose = Boolean(opts.verbose || opts.debug);
|
||||
setVerbose(verbose);
|
||||
@@ -105,6 +115,11 @@ Examples:
|
||||
|
||||
Shows token usage per session when the agent reports it; set agents.defaults.contextTokens to see % of your model window.`,
|
||||
)
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sessions", "docs.clawd.bot/cli/sessions")}\n`,
|
||||
)
|
||||
.action(async (opts) => {
|
||||
setVerbose(Boolean(opts.verbose));
|
||||
await sessionsCommand(
|
||||
|
||||
@@ -87,7 +87,8 @@ export function registerSandboxCli(program: Command) {
|
||||
.addHelpText("after", EXAMPLES.main)
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/sandbox", "docs.clawd.bot/sandbox")}\n`,
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/sandbox", "docs.clawd.bot/cli/sandbox")}\n`,
|
||||
)
|
||||
.action(() => {
|
||||
sandbox.help({ error: true });
|
||||
|
||||
@@ -5,6 +5,7 @@ import { loadConfig } from "../config/config.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { runSecurityAudit } from "../security/audit.js";
|
||||
import { fixSecurityFootguns } from "../security/fix.js";
|
||||
import { formatDocsLink } from "../terminal/links.js";
|
||||
import { isRich, theme } from "../terminal/theme.js";
|
||||
|
||||
type SecurityAuditOptions = {
|
||||
@@ -26,7 +27,14 @@ function formatSummary(summary: { critical: number; warn: number; info: number }
|
||||
}
|
||||
|
||||
export function registerSecurityCli(program: Command) {
|
||||
const security = program.command("security").description("Security tools (audit)");
|
||||
const security = program
|
||||
.command("security")
|
||||
.description("Security tools (audit)")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/security", "docs.clawd.bot/cli/security")}\n`,
|
||||
);
|
||||
|
||||
security
|
||||
.command("audit")
|
||||
|
||||
@@ -334,7 +334,8 @@ export function registerSkillsCli(program: Command) {
|
||||
.description("List and inspect available skills")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/skills", "docs.clawd.bot/skills")}\n`,
|
||||
() =>
|
||||
`\n${theme.muted("Docs:")} ${formatDocsLink("/cli/skills", "docs.clawd.bot/cli/skills")}\n`,
|
||||
);
|
||||
|
||||
skills
|
||||
|
||||
@@ -20,7 +20,7 @@ export function registerTuiCli(program: Command) {
|
||||
.option("--history-limit <n>", "History entries to load", "200")
|
||||
.addHelpText(
|
||||
"after",
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/tui", "docs.clawd.bot/tui")}\n`,
|
||||
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/cli/tui", "docs.clawd.bot/cli/tui")}\n`,
|
||||
)
|
||||
.action(async (opts) => {
|
||||
try {
|
||||
|
||||
@@ -279,7 +279,7 @@ Notes:
|
||||
- For global installs: use npm/pnpm/bun to reinstall (see docs/install/updating.md)
|
||||
- Skips update if the working directory has uncommitted changes
|
||||
|
||||
${theme.muted("Docs:")} ${formatDocsLink("/updating", "docs.clawd.bot/updating")}`,
|
||||
${theme.muted("Docs:")} ${formatDocsLink("/cli/update", "docs.clawd.bot/cli/update")}`,
|
||||
)
|
||||
.action(async (opts) => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user