========================================================================
discord-tools --help
========================================================================
usage: discord-tools [-h] [--profile PROFILE] [--json] [--jsonl]
                     {auth,doctor,discover,search,members,send,create,clear-messages,delete,leave-server,profiles,archive,review,structure,role,permission,member,invite,audit-log,webhook,emoji,sticker,automod,channel,message,watch,schedule,event,bot} ...

positional arguments:
  {auth,doctor,discover,search,members,send,create,clear-messages,delete,leave-server,profiles,archive,review,structure,role,permission,member,invite,audit-log,webhook,emoji,sticker,automod,channel,message,watch,schedule,event,bot}
    auth                Guided bot setup: Developer Portal walkthrough, token check, invite URL
    doctor              Check token, message-content intent, servers, and channel permissions
    discover            List the server -> channel -> thread tree with IDs
    search              Search and export messages (history fetch + local filter)
    members             List a server's members with usernames and IDs
    send                Send a message to a channel or thread as the bot
    create              Create a channel, category, or thread
    clear-messages      Clear a channel, thread, or server's messages (dry-run by default)
    delete              Delete a channel, category, or thread (dry-run by default; see leave-
                        server for servers)
    leave-server        Make the bot leave a server (nothing in it is deleted; dry-run by default)
    profiles            List the stored bot profiles, or remove one (no token is ever printed)
    archive             The local archive: sync history into it, search it, export it, prune it
    review              The review queue: attachments and links the archive saw, fetched into
                        quarantine only after you approve
    structure           Structure blueprints: export a server's roles, categories, channels,
                        overwrites, forum tags, AutoMod and settings; diff and apply them
                        elsewhere with new IDs
    role                A server's roles: list, create, edit (name, colour, hoist, mentionable,
                        permissions), delete (typed name)
    permission          Permission overwrites on a channel or category: show them, set one role's
    member              A server's members: list, kick, ban, unban, timeout, untimeout, nick.
                        `members` is the older spelling of `member list`
    invite              A server's invites: list them with their links, create one, revoke one
    audit-log           The server's own audit log: who did what, filtered by action, by person or
                        by time
    webhook             A server's webhooks: list them with their URLs hidden, create one, delete
                        one
    emoji               A server's custom emoji: list them, add one from a file, remove one
    sticker             A server's stickers: list them, add one from a file, remove one
    automod             The server's own AutoMod rules, which Discord runs itself: list, create,
                        edit, delete
    channel             A channel's own settings: name, topic, age gate, slow mode, position
    message             Act on messages a channel holds: reply, edit, delete, forward, copy,
                        react, pin, list pins, poll, typing, bookmark
    watch               Rules and the runner: watch a server live and act on what happens (macOS
                        and Linux)
    schedule            Runner-held scheduled posts: they fire only while `watch run` is up on
                        this machine
    event               Server-held scheduled events: Discord holds them, so they happen with this
                        machine off
    bot                 Show or edit the active profile's bot settings and invite URL

options:
  -h, --help            show this help message and exit
  --profile PROFILE     Named bot profile from ~/.discord-tools/ (default: default)
  --json                Print one machine-readable envelope on stdout; previews, prompts and
                        progress go to stderr
  --jsonl               Stream one JSON record per line on stdout, then the envelope as the last
                        line

========================================================================
discord-tools auth --help
========================================================================
usage: discord-tools auth [-h]

options:
  -h, --help  show this help message and exit

========================================================================
discord-tools doctor --help
========================================================================
usage: discord-tools doctor [-h] [--channel CHANNEL]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Also check the bot's permissions and message visibility in this
                     channel/thread ID

========================================================================
discord-tools discover --help
========================================================================
usage: discord-tools discover [-h] [--server SERVER] [--json [PATH]]

options:
  -h, --help       show this help message and exit
  --server SERVER  Limit to one server ID
  --json [PATH]    Write the tree to this JSON file; with no path, print the envelope to stdout

========================================================================
discord-tools search --help
========================================================================
usage: discord-tools search [-h] --channel CHANNEL [--keyword KEYWORD] [--from-user FROM_USER]
                            [--since SINCE] [--until UNTIL] [--limit LIMIT]
                            [--format {json,csv,jsonl,markdown,html}] [--output OUTPUT]
                            [--archive]

options:
  -h, --help            show this help message and exit
  --channel CHANNEL     Channel or thread ID
  --keyword, --contains KEYWORD
                        Case-insensitive text filter
  --from-user FROM_USER
                        Author username or ID
  --since SINCE         Inclusive ISO date or datetime lower bound
  --until UNTIL         Inclusive ISO date or datetime upper bound
  --limit LIMIT         Maximum exported messages
  --format {json,csv,jsonl,markdown,html}
                        Export format
  --output OUTPUT       Output file; relative names land in ~/.discord-tools/exports/. Prints a
                        readable table when omitted
  --archive             Search the local archive instead of fetching history (an alias of `archive
                        search`; --keyword is the query)

========================================================================
discord-tools members --help
========================================================================
usage: discord-tools members [-h] --server SERVER [--format {json,csv}] [--output OUTPUT]

options:
  -h, --help           show this help message and exit
  --server SERVER      Server ID
  --format {json,csv}  Export format
  --output OUTPUT      Output file; relative names land in ~/.discord-tools/exports/. Prints a
                       readable table when omitted

========================================================================
discord-tools send --help
========================================================================
usage: discord-tools send [-h] --channel CHANNEL [--text TEXT] [--file PATH]
                          [--reply-to MESSAGE_ID] [--at TIME] [--mention {users,roles,everyone}]
                          [--yes]

options:
  -h, --help            show this help message and exit
  --channel CHANNEL     Channel or thread ID
  --text TEXT           Message text, or - to read it from stdin; optional when --file is given
  --file PATH           Attach a file; repeatable
  --reply-to MESSAGE_ID
                        Post as a reply to this message in the same channel
  --at TIME             Post it later instead of now: the same runner-held schedule `schedule post
                        --at` makes
  --mention {users,roles,everyone}
                        Let the post ping this group; repeatable. Nobody is pinged without it, and
                        everyone always asks, even with --yes
  --yes                 Skip the preview and send; the channel must be in DISCORD_SEND_ALLOWLIST

========================================================================
discord-tools create --help
========================================================================
usage: discord-tools create [-h] {channel,category,thread} ...

positional arguments:
  {channel,category,thread}
    channel             Create a channel of any type delete can remove
    category            Create a category
    thread              Create a thread in a text channel

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools create channel --help
========================================================================
usage: discord-tools create channel [-h] --server SERVER --name NAME [--category CATEGORY]
                                    [--type {text,news,voice,stage_voice,forum,media}] [--yes]

options:
  -h, --help            show this help message and exit
  --server SERVER       Server ID
  --name NAME           Channel name
  --category CATEGORY   Category ID to file it under
  --type {text,news,voice,stage_voice,forum,media}
                        Channel type to create (default: text)
  --yes                 Skip the confirmation prompt

========================================================================
discord-tools create category --help
========================================================================
usage: discord-tools create category [-h] --server SERVER --name NAME [--yes]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --name NAME      Category name
  --yes            Skip the confirmation prompt

========================================================================
discord-tools create thread --help
========================================================================
usage: discord-tools create thread [-h] --channel CHANNEL --name NAME [--private] [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Parent channel ID
  --name NAME        Thread name
  --private          Make a private thread instead of a public one
  --yes              Skip the confirmation prompt

========================================================================
discord-tools clear-messages --help
========================================================================
usage: discord-tools clear-messages [-h] (--channel CHANNEL | --server SERVER) [--execute]
                                    [--skip-threads]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or thread ID
  --server SERVER    Clear every accessible message location in this server ID
  --execute          Actually clear messages after typing DELETE
  --skip-threads     With --server: clear channel messages only, leaving threads and forum/media
                     posts untouched

========================================================================
discord-tools delete --help
========================================================================
usage: discord-tools delete [-h] {channel,category,thread} ...

positional arguments:
  {channel,category,thread}
    channel             Delete a channel and everything in it
    category            Delete a category (the channels inside it survive, uncategorised)
    thread              Delete a thread or forum post

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools delete channel --help
========================================================================
usage: discord-tools delete channel [-h] --channel CHANNEL [--execute]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel ID
  --execute          Actually delete it after typing its exact name

========================================================================
discord-tools delete category --help
========================================================================
usage: discord-tools delete category [-h] --category CATEGORY [--execute]

options:
  -h, --help           show this help message and exit
  --category CATEGORY  Category ID
  --execute            Actually delete it after typing its exact name

========================================================================
discord-tools delete thread --help
========================================================================
usage: discord-tools delete thread [-h] --thread THREAD [--execute]

options:
  -h, --help       show this help message and exit
  --thread THREAD  Thread ID
  --execute        Actually delete it after typing its exact name

========================================================================
discord-tools leave-server --help
========================================================================
usage: discord-tools leave-server [-h] --server SERVER [--execute]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --execute        Actually leave after typing the server's exact name

========================================================================
discord-tools bot --help
========================================================================
usage: discord-tools bot [-h] [--invite] [--json [PATH]] [--name NAME] [--description DESCRIPTION]
                         [--avatar AVATAR] [--yes]

options:
  -h, --help            show this help message and exit
  --invite              Print only the invite URL
  --json [PATH]         Write the bot profile to this JSON file; with no path, print the envelope
                        to stdout
  --name NAME           Set the bot's username
  --description DESCRIPTION
                        Set the application description shown on the bot's profile
  --avatar AVATAR       Path to a new avatar image
  --yes                 Skip the confirmation prompt

========================================================================
discord-tools profiles --help
========================================================================
usage: discord-tools profiles [-h] {remove} ...

positional arguments:
  {remove}
    remove    Remove a profile's token and its record after typing the profile's exact name

options:
  -h, --help  show this help message and exit

========================================================================
discord-tools profiles remove --help
========================================================================
usage: discord-tools profiles remove [-h] --name NAME

options:
  -h, --help   show this help message and exit
  --name NAME  Profile name to remove

========================================================================
discord-tools archive --help
========================================================================
usage: discord-tools archive [-h] {sync,status,search,export,retention,forget} ...

positional arguments:
  {sync,status,search,export,retention,forget}
    sync                Fetch new history from every channel and thread the bot can read into
                        ~/.discord-tools/archive.sqlite
    status              Scopes, rows, dates, coverage, size against the budget
    search              Full-text search over the archive, ranked, with an optional regex and
                        context
    export              Write the same result set a search prints, in one of five formats
    retention           Prune one scope's archived messages older than a window (dry-run by
                        default)
    forget              Remove everything archived for one scope or one bot identity (dry-run by
                        default)

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools archive sync --help
========================================================================
usage: discord-tools archive sync [-h] [--server SERVER] [--scope RID_OR_ID] [--since SINCE]
                                  [--full]

options:
  -h, --help         show this help message and exit
  --server SERVER    Only this server ID
  --scope RID_OR_ID  Only this channel or thread (a rid or a numeric ID); repeatable
  --since SINCE      Stop walking back at this ISO date; later runs still resume from the
                     checkpoint
  --full             Ignore the checkpoints and walk every scope from the newest message again

========================================================================
discord-tools archive status --help
========================================================================
usage: discord-tools archive status [-h]

options:
  -h, --help  show this help message and exit

========================================================================
discord-tools archive search --help
========================================================================
usage: discord-tools archive search [-h] --query QUERY [--regex REGEX] [--scope RID_OR_ID]
                                    [--identity IDENTITY] [--from AUTHOR] [--since SINCE]
                                    [--until UNTIL] [--context N] [--limit LIMIT]
                                    [--include-deleted]

options:
  -h, --help           show this help message and exit
  --query QUERY        Full-text query (FTS5 syntax: words, quotes, AND, OR, NOT)
  --regex REGEX        A Python regular expression the matched text must also satisfy
  --scope RID_OR_ID    Only this channel or thread (a rid or a numeric ID); repeatable
  --identity IDENTITY  Only rows archived by this bot identity (a dc:bot rid)
  --from AUTHOR        Only messages from this author: a numeric ID, a username, or a rid
  --since SINCE        Inclusive ISO date or datetime lower bound
  --until UNTIL        Inclusive ISO date or datetime upper bound
  --context N          Also show N neighbouring messages on each side of a hit
  --limit LIMIT        Maximum hits (default: 50)
  --include-deleted    Also show messages marked deleted on a later sync

========================================================================
discord-tools archive export --help
========================================================================
usage: discord-tools archive export [-h] --query QUERY [--regex REGEX] [--scope RID_OR_ID]
                                    [--identity IDENTITY] [--from AUTHOR] [--since SINCE]
                                    [--until UNTIL] [--context N] [--limit LIMIT]
                                    [--include-deleted] [--format {json,csv,jsonl,markdown,html}]
                                    --output OUTPUT

options:
  -h, --help            show this help message and exit
  --query QUERY         Full-text query (FTS5 syntax: words, quotes, AND, OR, NOT)
  --regex REGEX         A Python regular expression the matched text must also satisfy
  --scope RID_OR_ID     Only this channel or thread (a rid or a numeric ID); repeatable
  --identity IDENTITY   Only rows archived by this bot identity (a dc:bot rid)
  --from AUTHOR         Only messages from this author: a numeric ID, a username, or a rid
  --since SINCE         Inclusive ISO date or datetime lower bound
  --until UNTIL         Inclusive ISO date or datetime upper bound
  --context N           Also show N neighbouring messages on each side of a hit
  --limit LIMIT         Maximum hits (default: 50)
  --include-deleted     Also show messages marked deleted on a later sync
  --format {json,csv,jsonl,markdown,html}
                        Export format (default: json)
  --output OUTPUT       Output file; relative names land in ~/.discord-tools/exports/

========================================================================
discord-tools archive retention --help
========================================================================
usage: discord-tools archive retention [-h] --scope RID_OR_ID --keep KEEP [--execute]

options:
  -h, --help         show this help message and exit
  --scope RID_OR_ID  The channel or thread to prune (a rid or a numeric ID)
  --keep KEEP        What to keep: a window like 90d, or a count of newest messages
  --execute          Actually prune after typing the scope's exact name

========================================================================
discord-tools archive forget --help
========================================================================
usage: discord-tools archive forget [-h] (--scope RID_OR_ID | --identity IDENTITY) [--execute]

options:
  -h, --help           show this help message and exit
  --scope RID_OR_ID    The channel or thread to forget (a rid or a numeric ID)
  --identity IDENTITY  The bot identity whose rows all go (a dc:bot rid)
  --execute            Actually remove after typing the target's exact name

========================================================================
discord-tools message --help
========================================================================
usage: discord-tools message [-h]
                             {reply,edit,delete,forward,copy,react,unreact,pin,unpin,pins,poll,typing,bookmark,read,unread,draft} ...

positional arguments:
  {reply,edit,delete,forward,copy,react,unreact,pin,unpin,pins,poll,typing,bookmark,read,unread,draft}
    reply               Reply to a message as the bot (a `send --reply-to`)
    edit                Edit one of the bot's own messages (Discord lets a bot edit no other)
    delete              Delete chosen messages in one channel (dry-run by default; bounded)
    forward             Forward messages to another channel with Discord's own forward header
    copy                Re-post messages' text elsewhere with an attribution line and links to
                        their attachments
    react               Add the bot's reaction to a message
    unreact             Remove the bot's own reaction from a message
    pin                 Pin a message (needs Pin Messages)
    unpin               Unpin a message (needs Pin Messages)
    pins                List a channel's or thread's pinned messages, newest pin first (a read;
                        needs Read Message History)
    poll                Post a poll
    typing              Show the bot typing in a channel for a few seconds
    bookmark            Keep a message as a local bookmark (Discord gives a bot no bookmark API)
    read                Not possible for a Discord bot; exits 2 with PLATFORM_UNSUPPORTED and says
                        why
    unread              Not possible for a Discord bot; exits 2 with PLATFORM_UNSUPPORTED and says
                        why
    draft               Not possible for a Discord bot; exits 2 with PLATFORM_UNSUPPORTED and says
                        why

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools message reply --help
========================================================================
usage: discord-tools message reply [-h] --channel CHANNEL --to MESSAGE_ID [--text TEXT]
                                   [--file PATH] [--mention {users,roles,everyone}] [--yes]

options:
  -h, --help            show this help message and exit
  --channel CHANNEL     Channel or thread ID the message is in
  --to MESSAGE_ID       Message to reply to
  --text TEXT           Reply text, or - to read it from stdin; optional when --file is given
  --file PATH           Attach a file; repeatable
  --mention {users,roles,everyone}
                        Let the post ping this group; repeatable. Nobody is pinged without it, and
                        everyone always asks, even with --yes
  --yes                 Skip the preview and post; the destination must be in
                        DISCORD_SEND_ALLOWLIST

========================================================================
discord-tools message edit --help
========================================================================
usage: discord-tools message edit [-h] --channel CHANNEL --id MESSAGE_ID --text TEXT
                                  [--mention {users,roles,everyone}] [--yes]

options:
  -h, --help            show this help message and exit
  --channel CHANNEL     Channel or thread ID the message is in
  --id MESSAGE_ID       Message ID
  --text TEXT           The new text, or - to read it from stdin
  --mention {users,roles,everyone}
                        Let the post ping this group; repeatable. Nobody is pinged without it, and
                        everyone always asks, even with --yes
  --yes                 Skip the confirmation prompt

========================================================================
discord-tools message delete --help
========================================================================
usage: discord-tools message delete [-h] --channel CHANNEL (--ids MESSAGE_ID [MESSAGE_ID ...] |
                                    --from-search QUERY) [--limit LIMIT] [--i-know] [--execute]

options:
  -h, --help            show this help message and exit
  --channel CHANNEL     Channel or thread ID the message is in
  --ids MESSAGE_ID [MESSAGE_ID ...]
                        Message IDs, space-separated
  --from-search QUERY   Select by a full-text query over this channel's rows in the local archive
  --limit LIMIT         Most messages one run may delete (default 200; above 1000 needs --i-know)
  --i-know              Allow --limit above 1000; the count is typed back at the prompt
  --execute             Actually delete after typing DELETE

========================================================================
discord-tools message forward --help
========================================================================
usage: discord-tools message forward [-h] --channel CHANNEL (--ids MESSAGE_ID [MESSAGE_ID ...] |
                                     --from-search QUERY) [--limit LIMIT] [--i-know]
                                     --to CHANNEL_ID [--yes]

options:
  -h, --help            show this help message and exit
  --channel CHANNEL     Channel or thread ID the message is in
  --ids MESSAGE_ID [MESSAGE_ID ...]
                        Message IDs, space-separated
  --from-search QUERY   Select by a full-text query over this channel's rows in the local archive
  --limit LIMIT         Most messages one run may forward (default 200; above 1000 needs --i-know)
  --i-know              Allow --limit above 1000; the count is typed back at the prompt
  --to CHANNEL_ID       Destination channel or thread ID
  --yes                 Skip the preview and post; the destination must be in
                        DISCORD_SEND_ALLOWLIST

========================================================================
discord-tools message copy --help
========================================================================
usage: discord-tools message copy [-h] --channel CHANNEL (--ids MESSAGE_ID [MESSAGE_ID ...] |
                                  --from-search QUERY) [--limit LIMIT] [--i-know] --to CHANNEL_ID
                                  [--mention {users,roles,everyone}] [--yes]

options:
  -h, --help            show this help message and exit
  --channel CHANNEL     Channel or thread ID the message is in
  --ids MESSAGE_ID [MESSAGE_ID ...]
                        Message IDs, space-separated
  --from-search QUERY   Select by a full-text query over this channel's rows in the local archive
  --limit LIMIT         Most messages one run may copy (default 200; above 1000 needs --i-know)
  --i-know              Allow --limit above 1000; the count is typed back at the prompt
  --to CHANNEL_ID       Destination channel or thread ID
  --mention {users,roles,everyone}
                        Let the post ping this group; repeatable. Nobody is pinged without it, and
                        everyone always asks, even with --yes
  --yes                 Skip the preview and post; the destination must be in
                        DISCORD_SEND_ALLOWLIST

========================================================================
discord-tools message react --help
========================================================================
usage: discord-tools message react [-h] --channel CHANNEL --id MESSAGE_ID --emoji EMOJI [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or thread ID the message is in
  --id MESSAGE_ID    Message ID
  --emoji EMOJI      A unicode emoji, or a custom one as <:name:id>
  --yes              Skip the confirmation prompt

========================================================================
discord-tools message unreact --help
========================================================================
usage: discord-tools message unreact [-h] --channel CHANNEL --id MESSAGE_ID --emoji EMOJI [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or thread ID the message is in
  --id MESSAGE_ID    Message ID
  --emoji EMOJI      The reaction to remove
  --yes              Skip the confirmation prompt

========================================================================
discord-tools message pin --help
========================================================================
usage: discord-tools message pin [-h] --channel CHANNEL --id MESSAGE_ID [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or thread ID the message is in
  --id MESSAGE_ID    Message ID
  --yes              Skip the confirmation prompt

========================================================================
discord-tools message unpin --help
========================================================================
usage: discord-tools message unpin [-h] --channel CHANNEL --id MESSAGE_ID [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or thread ID the message is in
  --id MESSAGE_ID    Message ID
  --yes              Skip the confirmation prompt

========================================================================
discord-tools message pins --help
========================================================================
usage: discord-tools message pins [-h] --channel CHANNEL

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or thread ID whose pins to list

========================================================================
discord-tools message poll --help
========================================================================
usage: discord-tools message poll [-h] --channel CHANNEL --question QUESTION --option TEXT
                                  [--multiple] [--hours HOURS] [--yes]

options:
  -h, --help           show this help message and exit
  --channel CHANNEL    Channel or thread ID to post in
  --question QUESTION  The question
  --option TEXT        An answer; repeat for each (2 to 10)
  --multiple           Let a voter pick more than one answer
  --hours HOURS        How long it stays open, 1 to 768 (default 24)
  --yes                Skip the preview and post; the destination must be in
                       DISCORD_SEND_ALLOWLIST

========================================================================
discord-tools message typing --help
========================================================================
usage: discord-tools message typing [-h] --channel CHANNEL [--seconds SECONDS] [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or thread ID
  --seconds SECONDS  How long, 1 to 300 (default 5)
  --yes              Skip the confirmation prompt

========================================================================
discord-tools message bookmark --help
========================================================================
usage: discord-tools message bookmark [-h] [--channel CHANNEL] [--id MESSAGE_ID] [--label LABEL]
                                      [--remove] [--list] [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or thread ID the message is in
  --id MESSAGE_ID    Message ID
  --label LABEL      A note to keep with it
  --remove           Drop the bookmark instead of adding it
  --list             Print this machine's bookmarks; no login
  --yes              Skip the confirmation prompt

========================================================================
discord-tools message read --help
========================================================================
usage: discord-tools message read [-h] [--scope SCOPE]

options:
  -h, --help     show this help message and exit
  --scope SCOPE  Channel or thread ID

========================================================================
discord-tools message unread --help
========================================================================
usage: discord-tools message unread [-h] [--scope SCOPE]

options:
  -h, --help     show this help message and exit
  --scope SCOPE  Channel or thread ID

========================================================================
discord-tools message draft --help
========================================================================
usage: discord-tools message draft [-h] [--scope SCOPE] [--text TEXT]

options:
  -h, --help     show this help message and exit
  --scope SCOPE  Channel or thread ID
  --text TEXT    The draft text

========================================================================
discord-tools structure --help
========================================================================
usage: discord-tools structure [-h] {export,diff,apply,remap} ...

positional arguments:
  {export,diff,apply,remap}
    export              Write a server's structure as a deterministic blueprint (never members,
                        messages, webhooks, invites, bans or emoji)
    diff                What a server would need to become the blueprint, object by object
    apply               Make a server match a blueprint with new IDs (dry-run by default;
                        --execute asks for the server's exact name; never deletes)
    remap               The source ID -> target ID table one apply recorded (reads the archive; no
                        login)

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools structure export --help
========================================================================
usage: discord-tools structure export [-h] --target TARGET --output OUTPUT

options:
  -h, --help       show this help message and exit
  --target TARGET  Server ID to export
  --output OUTPUT  Blueprint file; a bare name lands in ~/.discord-tools/exports/

========================================================================
discord-tools structure diff --help
========================================================================
usage: discord-tools structure diff [-h] --blueprint BLUEPRINT --target TARGET

options:
  -h, --help            show this help message and exit
  --blueprint BLUEPRINT
                        A blueprint file from `structure export`
  --target TARGET       Server ID to compare against

========================================================================
discord-tools structure apply --help
========================================================================
usage: discord-tools structure apply [-h] --blueprint BLUEPRINT --target TARGET [--execute]

options:
  -h, --help            show this help message and exit
  --blueprint BLUEPRINT
                        A blueprint file from `structure export`
  --target TARGET       Server ID to apply to
  --execute             Apply for real: shows the steps, then asks you to type the server's exact
                        name. There is no --yes

========================================================================
discord-tools structure remap --help
========================================================================
usage: discord-tools structure remap [-h] --apply-id APPLY_ID

options:
  -h, --help           show this help message and exit
  --apply-id APPLY_ID  The apply id `structure apply` printed

========================================================================
discord-tools role --help
========================================================================
usage: discord-tools role [-h] {list,create,edit,delete} ...

positional arguments:
  {list,create,edit,delete}
    list                Every role with its position, ID, colour, flags and permissions; the bot's
                        own marked
    create              Create a role (preview + y/N; typed server name when it grants
                        Administrator)
    edit                Change a role's name, colour, hoist, mentionable or permissions (preview +
                        y/N)
    delete              Delete a role (dry-run by default; --execute asks for its exact name)

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools role list --help
========================================================================
usage: discord-tools role list [-h] --server SERVER

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID

========================================================================
discord-tools role create --help
========================================================================
usage: discord-tools role create [-h] --server SERVER --name NAME [--colour COLOUR] [--hoist]
                                 [--mentionable] [--permissions PERMISSIONS] [--yes]

options:
  -h, --help            show this help message and exit
  --server SERVER       Server ID
  --name NAME           Role name
  --colour COLOUR       Six hex digits like #FF8800 (default: none)
  --hoist               Show its members separately in the member list
  --mentionable         Let anyone @mention it
  --permissions PERMISSIONS
                        Discord's own permission names, comma-separated
                        (send_messages,manage_channels); default none
  --yes                 Skip the y/N prompt (never answers the Administrator gate)

========================================================================
discord-tools role edit --help
========================================================================
usage: discord-tools role edit [-h] --server SERVER --role ROLE [--name NAME] [--colour COLOUR]
                               [--hoist | --no-hoist] [--mentionable | --no-mentionable]
                               [--permissions PERMISSIONS] [--yes]

options:
  -h, --help            show this help message and exit
  --server SERVER       Server ID
  --role ROLE           Role ID, or `everyone` for the server's default role
  --name NAME           New name
  --colour COLOUR       Six hex digits like #FF8800, or `none`
  --hoist, --no-hoist   Show members separately, or not
  --mentionable, --no-mentionable
                        Mentionable by anyone, or not
  --permissions PERMISSIONS
                        The role's whole permission set as names, comma-separated; `none` clears
                        it. Replaces, never adds
  --yes                 Skip the y/N prompt (never answers the Administrator gate)

========================================================================
discord-tools role delete --help
========================================================================
usage: discord-tools role delete [-h] --server SERVER --role ROLE [--execute]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --role ROLE      Role ID
  --execute        Delete for real after typing the role's exact name (no --yes exists)

========================================================================
discord-tools permission --help
========================================================================
usage: discord-tools permission [-h] {show,set} ...

positional arguments:
  {show,set}
    show      Every role overwrite on a channel or category, by name
    set       Set one role's overwrite on a channel or category (preview + y/N); allow and deny
              merge into what it has

options:
  -h, --help  show this help message and exit

========================================================================
discord-tools permission show --help
========================================================================
usage: discord-tools permission show [-h] [--target TARGET] [--role ROLE] [--names]

options:
  -h, --help       show this help message and exit
  --target TARGET  Channel or category ID
  --role ROLE      Only this role's overwrite (ID, or `everyone`)
  --names          Print every permission name this tool accepts and exit (no login)

========================================================================
discord-tools permission set --help
========================================================================
usage: discord-tools permission set [-h] --target TARGET --role ROLE [--allow ALLOW] [--deny DENY]
                                    [--clear] [--yes]

options:
  -h, --help       show this help message and exit
  --target TARGET  Channel or category ID
  --role ROLE      Role ID, or `everyone`
  --allow ALLOW    Permission names to allow, comma-separated
  --deny DENY      Permission names to deny, comma-separated
  --clear          Remove the role's overwrite entirely instead
  --yes            Skip the y/N prompt

========================================================================
discord-tools member --help
========================================================================
usage: discord-tools member [-h] {list,kick,ban,unban,timeout,untimeout,nick} ...

positional arguments:
  {list,kick,ban,unban,timeout,untimeout,nick}
    list                Every visible member with their username and ID (needs the Server Members
                        intent)
    kick                Remove a member from the server (dry-run by default; --execute asks for
                        their exact username)
    ban                 Ban a user, here or already gone, so they cannot come back (dry-run by
                        default; --execute asks for their exact username, or their ID when they
                        are not here)
    unban               Lift a ban so the user can be invited back (preview + y/N)
    timeout             Stop a member posting, reacting and speaking until a time you name
                        (preview + y/N)
    untimeout           End a member's timeout now rather than when it was due to (preview + y/N)
    nick                Set or clear a member's nickname on this server (preview + y/N)

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools member list --help
========================================================================
usage: discord-tools member list [-h] --server SERVER [--format {json,csv}] [--output OUTPUT]

options:
  -h, --help           show this help message and exit
  --server SERVER      Server ID
  --format {json,csv}  Export format
  --output OUTPUT      Output file; relative names land in ~/.discord-tools/exports/. Prints a
                       readable table when omitted

========================================================================
discord-tools member kick --help
========================================================================
usage: discord-tools member kick [-h] --server SERVER --member MEMBER --reason REASON [--execute]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --member MEMBER  User ID of the member
  --reason REASON  Why; Discord stores it in the server's own audit log
  --execute        Remove a member from the server for real after typing their exact username (no
                   --yes exists)

========================================================================
discord-tools member ban --help
========================================================================
usage: discord-tools member ban [-h] --server SERVER --member MEMBER --reason REASON [--execute]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --member MEMBER  User ID; they need not be in the server
  --reason REASON  Why; Discord stores it in the server's own audit log
  --execute        Ban them for real after typing their exact username, or their ID when they are
                   not here (no --yes exists)

========================================================================
discord-tools member unban --help
========================================================================
usage: discord-tools member unban [-h] --server SERVER --member MEMBER [--reason REASON] [--yes]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --member MEMBER  User ID of the banned user
  --reason REASON  Why; Discord stores it in the server's own audit log
  --yes            Skip the y/N prompt

========================================================================
discord-tools member timeout --help
========================================================================
usage: discord-tools member timeout [-h] --server SERVER --member MEMBER --until TIME
                                    [--reason REASON] [--yes]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --member MEMBER  User ID of the member
  --until TIME     When it ends: an ISO 8601 time, or a duration like 30m, 2h, 7d. Required, and
                   never more than 28 days (Discord's own limit)
  --reason REASON  Why; Discord stores it in the server's own audit log
  --yes            Skip the y/N prompt

========================================================================
discord-tools member nick --help
========================================================================
usage: discord-tools member nick [-h] --server SERVER --member MEMBER --nick NICK
                                 [--reason REASON] [--yes]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --member MEMBER  User ID of the member
  --nick NICK      The new nickname; an empty string clears it back to their username
  --reason REASON  Why; Discord stores it in the server's own audit log
  --yes            Skip the y/N prompt

========================================================================
discord-tools invite --help
========================================================================
usage: discord-tools invite [-h] {list,create,revoke} ...

positional arguments:
  {list,create,revoke}
    list                Every invite with its link, uses and expiry (needs Manage Guild)
    create              Create an invite to a channel and print its link once (preview + y/N)
    revoke              Revoke an invite (dry-run by default; --execute asks for its exact code)

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools invite list --help
========================================================================
usage: discord-tools invite list [-h] --server SERVER

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID

========================================================================
discord-tools invite create --help
========================================================================
usage: discord-tools invite create [-h] --channel CHANNEL [--max-age SECONDS] [--max-uses N]
                                   [--temporary] [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel ID the invite lands in
  --max-age SECONDS  Seconds until it expires; 0 never expires (default: 86400, one day)
  --max-uses N       How many people may use it; 0 is unlimited (default: 0)
  --temporary        Members who join on it lose their roles when they disconnect
  --yes              Skip the y/N prompt

========================================================================
discord-tools invite revoke --help
========================================================================
usage: discord-tools invite revoke [-h] --server SERVER --code CODE [--execute]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --code CODE      The invite code, as `invite list` prints it
  --execute        Revoke for real after typing the exact code (no --yes exists)

========================================================================
discord-tools audit-log --help
========================================================================
usage: discord-tools audit-log [-h] {list} ...

positional arguments:
  {list}
    list      Audit entries, newest first (needs View Audit Log)

options:
  -h, --help  show this help message and exit

========================================================================
discord-tools audit-log list --help
========================================================================
usage: discord-tools audit-log list [-h] --server SERVER [--action ACTION] [--user USER]
                                    [--since TIME] [--limit LIMIT]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --action ACTION  Only this action, in Discord's own snake_case names (kick, ban, member_update,
                   invite_create, ...)
  --user USER      Only entries by this user ID
  --since TIME     Only entries after this ISO 8601 time, or a duration back like 24h
  --limit LIMIT    How many entries at most (default: 50)

========================================================================
discord-tools webhook --help
========================================================================
usage: discord-tools webhook [-h] {list,create,delete} ...

positional arguments:
  {list,create,delete}
    list                Every webhook, each URL's token hidden (needs Manage Webhooks)
    create              Create a webhook on a channel (preview + y/N); --reveal prints its URL
                        once
    delete              Delete a webhook (dry-run by default; --execute asks for its exact name)

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools webhook list --help
========================================================================
usage: discord-tools webhook list [-h] --server SERVER

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID

========================================================================
discord-tools webhook create --help
========================================================================
usage: discord-tools webhook create [-h] --channel CHANNEL --name NAME [--reveal] [--yes]

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel ID the webhook posts into
  --name NAME        What Discord shows as the poster's name by default
  --reveal           Print the whole URL once, on screen. Without it the URL is never shown, here
                     or anywhere else
  --yes              Skip the y/N prompt

========================================================================
discord-tools webhook delete --help
========================================================================
usage: discord-tools webhook delete [-h] --server SERVER --webhook WEBHOOK [--execute]

options:
  -h, --help         show this help message and exit
  --server SERVER    Server ID
  --webhook WEBHOOK  Webhook ID, or its exact name when only one has it
  --execute          Delete for real after typing the webhook's exact name (no --yes exists)

========================================================================
discord-tools emoji --help
========================================================================
usage: discord-tools emoji [-h] {list,add,remove} ...

positional arguments:
  {list,add,remove}
    list             Every custom emoji with the text you paste to use it
    add              Add a custom emoji from an image file (preview + y/N)
    remove           Remove a custom emoji (dry-run by default; --execute asks for its exact name)

options:
  -h, --help         show this help message and exit

========================================================================
discord-tools emoji list --help
========================================================================
usage: discord-tools emoji list [-h] --server SERVER

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID

========================================================================
discord-tools emoji add --help
========================================================================
usage: discord-tools emoji add [-h] --server SERVER --name NAME --file PATH [--yes]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --name NAME      What it is typed as, between colons
  --file PATH      Image file (.png, .jpg, .jpeg, .gif, .webp), at most 256 KiB
  --yes            Skip the y/N prompt

========================================================================
discord-tools emoji remove --help
========================================================================
usage: discord-tools emoji remove [-h] --server SERVER --emoji EMOJI [--execute]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --emoji EMOJI    Emoji ID, or its exact name when only one has it
  --execute        Remove for real after typing the emoji's exact name (no --yes exists)

========================================================================
discord-tools sticker --help
========================================================================
usage: discord-tools sticker [-h] {list,add,remove} ...

positional arguments:
  {list,add,remove}
    list             Every sticker with the emoji it suggests
    add              Add a sticker from a file (preview + y/N)
    remove           Remove a sticker (dry-run by default; --execute asks for its exact name)

options:
  -h, --help         show this help message and exit

========================================================================
discord-tools sticker list --help
========================================================================
usage: discord-tools sticker list [-h] --server SERVER

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID

========================================================================
discord-tools sticker add --help
========================================================================
usage: discord-tools sticker add [-h] --server SERVER --name NAME --file PATH --emoji EMOJI
                                 [--description DESCRIPTION] [--yes]

options:
  -h, --help            show this help message and exit
  --server SERVER       Server ID
  --name NAME           What the sticker is called
  --file PATH           Sticker file (.png, .apng, .json, .gif), at most 512 KiB
  --emoji EMOJI         The unicode emoji Discord suggests it by; Discord requires one
  --description DESCRIPTION
                        What it shows, for people using a screen reader
  --yes                 Skip the y/N prompt

========================================================================
discord-tools sticker remove --help
========================================================================
usage: discord-tools sticker remove [-h] --server SERVER --sticker STICKER [--execute]

options:
  -h, --help         show this help message and exit
  --server SERVER    Server ID
  --sticker STICKER  Sticker ID, or its exact name when only one has it
  --execute          Remove for real after typing the sticker's exact name (no --yes exists)

========================================================================
discord-tools automod --help
========================================================================
usage: discord-tools automod [-h] {list,create,edit,delete} ...

positional arguments:
  {list,create,edit,delete}
    list                Every rule, what it watches for and what it then does (needs Manage
                        Server)
    create              Write a rule Discord applies itself (preview + y/N)
    edit                Change a rule, inside the trigger family it already has (preview + y/N)
    delete              Delete a rule (dry-run by default; --execute asks for its exact name)

options:
  -h, --help            show this help message and exit

========================================================================
discord-tools automod list --help
========================================================================
usage: discord-tools automod list [-h] --server SERVER

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID

========================================================================
discord-tools automod create --help
========================================================================
usage: discord-tools automod create [-h] --server SERVER --name NAME [--keyword TEXT]
                                    [--regex PATTERN] [--preset {profanity,sexual_content,slurs}]
                                    [--mention-limit N] [--spam] [--allow TEXT]
                                    [--block [MESSAGE]] [--alert CHANNEL] [--timeout SECONDS]
                                    [--exempt-role ID] [--exempt-channel ID]
                                    [--enabled | --no-enabled] [--yes]

options:
  -h, --help            show this help message and exit
  --server SERVER       Server ID
  --name NAME           What the rule is called
  --keyword TEXT        A word or phrase to catch; repeat for more
  --regex PATTERN       A pattern to catch; repeat for more, at most 10
  --preset {profanity,sexual_content,slurs}
                        One of Discord's own lists; repeat for more
  --mention-limit N     Catch a message mentioning more than N people (1 to 50)
  --spam                Catch what Discord itself judges to be spam
  --allow TEXT          An exception to a keyword or preset rule; repeat for more
  --block [MESSAGE]     Stop the message posting, optionally telling the author why
  --alert CHANNEL       Post a copy into this channel ID
  --timeout SECONDS     Time the author out (1 second to 28 days)
  --exempt-role ID      A role the rule ignores; repeat for more
  --exempt-channel ID   A channel the rule ignores; repeat for more
  --enabled, --no-enabled
                        Turn it on, or off
  --yes                 Skip the y/N prompt

========================================================================
discord-tools automod edit --help
========================================================================
usage: discord-tools automod edit [-h] --server SERVER --rule RULE [--name NAME] [--keyword TEXT]
                                  [--regex PATTERN] [--preset {profanity,sexual_content,slurs}]
                                  [--mention-limit N] [--spam] [--allow TEXT] [--block [MESSAGE]]
                                  [--alert CHANNEL] [--timeout SECONDS] [--exempt-role ID]
                                  [--exempt-channel ID] [--enabled | --no-enabled] [--yes]

options:
  -h, --help            show this help message and exit
  --server SERVER       Server ID
  --rule RULE           Rule ID, or its exact name
  --name NAME           What the rule is called (renames it)
  --keyword TEXT        A word or phrase to catch; repeat for more
  --regex PATTERN       A pattern to catch; repeat for more, at most 10
  --preset {profanity,sexual_content,slurs}
                        One of Discord's own lists; repeat for more
  --mention-limit N     Catch a message mentioning more than N people (1 to 50)
  --spam                Catch what Discord itself judges to be spam
  --allow TEXT          An exception to a keyword or preset rule; repeat for more
  --block [MESSAGE]     Stop the message posting, optionally telling the author why
  --alert CHANNEL       Post a copy into this channel ID
  --timeout SECONDS     Time the author out (1 second to 28 days)
  --exempt-role ID      A role the rule ignores; repeat for more
  --exempt-channel ID   A channel the rule ignores; repeat for more
  --enabled, --no-enabled
                        Turn it on, or off
  --yes                 Skip the y/N prompt

========================================================================
discord-tools automod delete --help
========================================================================
usage: discord-tools automod delete [-h] --server SERVER --rule RULE [--execute]

options:
  -h, --help       show this help message and exit
  --server SERVER  Server ID
  --rule RULE      Rule ID, or its exact name
  --execute        Delete for real after typing the rule's exact name (no --yes exists)

========================================================================
discord-tools channel --help
========================================================================
usage: discord-tools channel [-h] {show,edit} ...

positional arguments:
  {show,edit}
    show       Print a channel's or category's settings: type, category, name, topic, age gate,
               slow mode, position, counts
    edit       Change a channel's or category's settings (preview + y/N), then read the diff back

options:
  -h, --help   show this help message and exit

========================================================================
discord-tools channel show --help
========================================================================
usage: discord-tools channel show [-h] --channel CHANNEL

options:
  -h, --help         show this help message and exit
  --channel CHANNEL  Channel or category ID

========================================================================
discord-tools channel edit --help
========================================================================
usage: discord-tools channel edit [-h] --channel CHANNEL [--name NAME] [--topic TOPIC]
                                  [--nsfw | --no-nsfw] [--slowmode SECONDS] [--position N] [--yes]

options:
  -h, --help          show this help message and exit
  --channel CHANNEL   Channel or category ID
  --name NAME         New name
  --topic TOPIC       New topic; an empty string clears it
  --nsfw, --no-nsfw   Age-gate it, or not
  --slowmode SECONDS  Seconds between one person's messages; 0 turns it off (at most 21600)
  --position N        Where it sits in its list, counting from 0 at the top
  --yes               Skip the y/N prompt
