@ibbybuilds/discli 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -71,6 +71,21 @@ discli server info
71
71
  discli server list # List servers the bot is in
72
72
  discli server select <id> # Set default server
73
73
  discli server info # Server overview
74
+ discli server set --name "X" # Change server name
75
+ discli server set --description "X" # Set description
76
+ discli server set --verification medium # Set verification level
77
+ discli server set --notifications only_mentions # Default notifications
78
+ discli server set --content-filter all_members # Content filter
79
+ ```
80
+
81
+ ### Invites
82
+
83
+ ```bash
84
+ discli invite list # List all invites
85
+ discli invite create <channel> # Create invite (never expires)
86
+ discli invite create <ch> --max-age 3600 # Expire after 1 hour
87
+ discli invite create <ch> --max-uses 10 # Max 10 uses
88
+ discli invite delete <code> --confirm # Delete invite
74
89
  ```
75
90
 
76
91
  ### Channels
package/dist/cli.js CHANGED
@@ -144,6 +144,19 @@ var DiscordAPI = class {
144
144
  async getGuild(guildId) {
145
145
  return await this.request("GET", `/guilds/${guildId}?with_counts=true`);
146
146
  }
147
+ async modifyGuild(guildId, data) {
148
+ return await this.request("PATCH", `/guilds/${guildId}`, data);
149
+ }
150
+ // ── Invites ──
151
+ async getGuildInvites(guildId) {
152
+ return await this.request("GET", `/guilds/${guildId}/invites`);
153
+ }
154
+ async createChannelInvite(channelId, opts) {
155
+ return await this.request("POST", `/channels/${channelId}/invites`, opts ?? {});
156
+ }
157
+ async deleteInvite(code) {
158
+ await this.request("DELETE", `/invites/${code}`);
159
+ }
147
160
  // ── Audit Log ──
148
161
  async getAuditLog(guildId, opts) {
149
162
  const params = new URLSearchParams();
@@ -421,6 +434,22 @@ function printTable(rows, columns) {
421
434
  }
422
435
 
423
436
  // src/commands/server.ts
437
+ var VERIFICATION_LEVELS = {
438
+ none: 0,
439
+ low: 1,
440
+ medium: 2,
441
+ high: 3,
442
+ very_high: 4
443
+ };
444
+ var NOTIFICATION_LEVELS = {
445
+ all_messages: 0,
446
+ only_mentions: 1
447
+ };
448
+ var CONTENT_FILTER_LEVELS = {
449
+ disabled: 0,
450
+ members_without_roles: 1,
451
+ all_members: 2
452
+ };
424
453
  function registerServer(program2) {
425
454
  const server = program2.command("server").description("Manage and inspect servers");
426
455
  server.command("list").description("List all servers the bot is in").action(async () => {
@@ -469,6 +498,57 @@ ${guild.name}`);
469
498
  console.log("\u2500".repeat(guild.name.length));
470
499
  printResult(info, fmt);
471
500
  });
501
+ server.command("set").description("Modify server settings").option("--name <name>", "Server name").option("--description <text>", "Server description").option("--verification <level>", "Verification level: none, low, medium, high, very_high").option("--notifications <level>", "Default notifications: all_messages, only_mentions").option("--content-filter <level>", "Content filter: disabled, members_without_roles, all_members").option("--afk-timeout <seconds>", "AFK timeout: 60, 300, 900, 1800, 3600", parseInt).option("--system-channel <id>", "System message channel ID").option("--rules-channel <id>", "Rules channel ID").option("--boost-bar", "Enable boost progress bar").option("--no-boost-bar", "Disable boost progress bar").action(async (opts) => {
502
+ const fmt = resolveFormat(program2.opts().format);
503
+ const api = new DiscordAPI(requireToken());
504
+ const guildId = requireServer(program2.opts().server);
505
+ const data = {};
506
+ if (opts.name) data.name = opts.name;
507
+ if (opts.description) data.description = opts.description;
508
+ if (opts.verification) {
509
+ const level = VERIFICATION_LEVELS[opts.verification];
510
+ if (level === void 0) {
511
+ console.error(`Invalid verification level. Use: ${Object.keys(VERIFICATION_LEVELS).join(", ")}`);
512
+ process.exit(2);
513
+ }
514
+ data.verification_level = level;
515
+ }
516
+ if (opts.notifications) {
517
+ const level = NOTIFICATION_LEVELS[opts.notifications];
518
+ if (level === void 0) {
519
+ console.error(`Invalid notification level. Use: ${Object.keys(NOTIFICATION_LEVELS).join(", ")}`);
520
+ process.exit(2);
521
+ }
522
+ data.default_message_notifications = level;
523
+ }
524
+ if (opts.contentFilter) {
525
+ const level = CONTENT_FILTER_LEVELS[opts.contentFilter];
526
+ if (level === void 0) {
527
+ console.error(`Invalid content filter level. Use: ${Object.keys(CONTENT_FILTER_LEVELS).join(", ")}`);
528
+ process.exit(2);
529
+ }
530
+ data.explicit_content_filter = level;
531
+ }
532
+ if (opts.afkTimeout) data.afk_timeout = opts.afkTimeout;
533
+ if (opts.systemChannel) data.system_channel_id = opts.systemChannel;
534
+ if (opts.rulesChannel) data.rules_channel_id = opts.rulesChannel;
535
+ if (opts.boostBar === true) data.premium_progress_bar_enabled = true;
536
+ if (opts.boostBar === false) data.premium_progress_bar_enabled = false;
537
+ if (Object.keys(data).length === 0) {
538
+ console.error("Specify at least one setting to change.");
539
+ console.error("Options: --name, --description, --verification, --notifications, --content-filter, --afk-timeout, --system-channel, --rules-channel, --boost-bar");
540
+ process.exit(2);
541
+ }
542
+ const guild = await api.modifyGuild(guildId, data);
543
+ if (fmt !== "table") {
544
+ printResult(guild, fmt);
545
+ } else {
546
+ console.log(`Updated server settings for ${guild.name}`);
547
+ for (const [key, value] of Object.entries(data)) {
548
+ console.log(` ${key}: ${value}`);
549
+ }
550
+ }
551
+ });
472
552
  }
473
553
 
474
554
  // src/utils/resolve.ts
@@ -1209,9 +1289,67 @@ function registerAudit(program2) {
1209
1289
  });
1210
1290
  }
1211
1291
 
1292
+ // src/commands/invite.ts
1293
+ function registerInvite(program2) {
1294
+ const invite = program2.command("invite").description("Manage server invites");
1295
+ invite.command("list").description("List all server invites").action(async () => {
1296
+ const fmt = resolveFormat(program2.opts().format);
1297
+ const api = new DiscordAPI(requireToken());
1298
+ const guildId = requireServer(program2.opts().server);
1299
+ const invites = await api.getGuildInvites(guildId);
1300
+ if (fmt !== "table") {
1301
+ printResult(invites, fmt);
1302
+ return;
1303
+ }
1304
+ if (invites.length === 0) {
1305
+ console.log("\n No active invites");
1306
+ return;
1307
+ }
1308
+ const rows = invites.map((inv) => ({
1309
+ code: inv.code,
1310
+ channel: inv.channel?.name ?? "?",
1311
+ inviter: inv.inviter?.username ?? "?",
1312
+ uses: `${inv.uses}/${inv.max_uses || "\u221E"}`,
1313
+ max_age: inv.max_age === 0 ? "never" : `${inv.max_age}s`,
1314
+ temp: inv.temporary ? "yes" : "no"
1315
+ }));
1316
+ console.log("\nInvites");
1317
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
1318
+ printResult(rows, fmt);
1319
+ });
1320
+ invite.command("create").description("Create an invite link").argument("<channel>", "Channel name or ID").option("--max-age <seconds>", "Expire after seconds (0 = never)", parseInt).option("--max-uses <count>", "Max uses (0 = unlimited)", parseInt).option("--temporary", "Grant temporary membership").action(async (channelName, opts) => {
1321
+ const fmt = resolveFormat(program2.opts().format);
1322
+ const api = new DiscordAPI(requireToken());
1323
+ const guildId = requireServer(program2.opts().server);
1324
+ const ch = await resolveChannel(api, guildId, channelName);
1325
+ const inviteOpts = { unique: true };
1326
+ if (opts.maxAge !== void 0) inviteOpts.max_age = opts.maxAge;
1327
+ if (opts.maxUses !== void 0) inviteOpts.max_uses = opts.maxUses;
1328
+ if (opts.temporary) inviteOpts.temporary = true;
1329
+ const inv = await api.createChannelInvite(ch.id, inviteOpts);
1330
+ if (fmt !== "table") {
1331
+ printResult(inv, fmt);
1332
+ } else {
1333
+ console.log(`Created invite: https://discord.gg/${inv.code}`);
1334
+ console.log(` Channel: #${ch.name}`);
1335
+ console.log(` Max uses: ${inv.max_uses || "unlimited"}`);
1336
+ console.log(` Expires: ${inv.max_age === 0 ? "never" : `${inv.max_age}s`}`);
1337
+ }
1338
+ });
1339
+ invite.command("delete").description("Delete an invite").argument("<code>", "Invite code").option("--confirm", "Required to actually delete").action(async (code, opts) => {
1340
+ const api = new DiscordAPI(requireToken());
1341
+ if (!opts.confirm) {
1342
+ console.error(`This will delete invite ${code}. Add --confirm to proceed.`);
1343
+ process.exit(2);
1344
+ }
1345
+ await api.deleteInvite(code);
1346
+ console.log(`Deleted invite ${code}`);
1347
+ });
1348
+ }
1349
+
1212
1350
  // src/cli.ts
1213
1351
  var program = new Command();
1214
- program.name("discli").description("discli \u2014 Discord server management CLI").version("0.3.0").option("--format <fmt>", "Output format: json, yaml, table, auto (auto = yaml when piped, table in terminal)", "auto").option("--server <id>", "Server ID override");
1352
+ program.name("discli").description("discli \u2014 Discord server management CLI").version("0.5.0").option("--format <fmt>", "Output format: json, yaml, table, auto (auto = yaml when piped, table in terminal)", "auto").option("--server <id>", "Server ID override");
1215
1353
  registerInit(program);
1216
1354
  registerServer(program);
1217
1355
  registerChannel(program);
@@ -1220,5 +1358,6 @@ registerMember(program);
1220
1358
  registerPermission(program);
1221
1359
  registerMessage(program);
1222
1360
  registerAudit(program);
1361
+ registerInvite(program);
1223
1362
  program.parse();
1224
1363
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/utils/config.ts","../src/utils/api.ts","../src/commands/init.ts","../src/utils/output.ts","../src/commands/server.ts","../src/utils/resolve.ts","../src/commands/channel.ts","../src/commands/role.ts","../src/commands/member.ts","../src/commands/permission.ts","../src/commands/message.ts","../src/commands/audit.ts"],"sourcesContent":["import { Command } from 'commander';\r\nimport { registerInit } from './commands/init.js';\r\nimport { registerServer } from './commands/server.js';\r\nimport { registerChannel } from './commands/channel.js';\r\nimport { registerRole } from './commands/role.js';\r\nimport { registerMember } from './commands/member.js';\r\nimport { registerPermission } from './commands/permission.js';\r\nimport { registerMessage } from './commands/message.js';\r\nimport { registerAudit } from './commands/audit.js';\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('discli')\r\n .description('discli — Discord server management CLI')\r\n .version('0.3.0')\r\n .option('--format <fmt>', 'Output format: json, yaml, table, auto (auto = yaml when piped, table in terminal)', 'auto')\r\n .option('--server <id>', 'Server ID override');\r\n\r\nregisterInit(program);\r\nregisterServer(program);\r\nregisterChannel(program);\r\nregisterRole(program);\r\nregisterMember(program);\r\nregisterPermission(program);\r\nregisterMessage(program);\r\nregisterAudit(program);\r\n\r\nprogram.parse();\r\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\r\nimport { homedir } from 'os';\r\nimport { join } from 'path';\r\n\r\nconst CONFIG_DIR = join(homedir(), '.discli');\r\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.json');\r\nconst ENV_FILE = join(CONFIG_DIR, '.env');\r\n\r\ninterface DctlConfig {\r\n default_server_id?: string;\r\n default_server_name?: string;\r\n}\r\n\r\nfunction ensureConfigDir(): void {\r\n if (!existsSync(CONFIG_DIR)) {\r\n mkdirSync(CONFIG_DIR, { recursive: true });\r\n }\r\n}\r\n\r\nexport function loadConfig(): DctlConfig {\r\n if (!existsSync(CONFIG_FILE)) return {};\r\n try {\r\n return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\nexport function saveConfig(data: DctlConfig): void {\r\n ensureConfigDir();\r\n writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2) + '\\n');\r\n}\r\n\r\nexport function loadToken(): string | null {\r\n if (!existsSync(ENV_FILE)) return null;\r\n const content = readFileSync(ENV_FILE, 'utf-8');\r\n const match = content.match(/^BOT_TOKEN=(.+)$/m);\r\n return match ? match[1].trim() : null;\r\n}\r\n\r\nexport function saveToken(token: string): void {\r\n ensureConfigDir();\r\n writeFileSync(ENV_FILE, `BOT_TOKEN=${token}\\n`);\r\n}\r\n\r\nexport function getDefaultServer(): string | null {\r\n return loadConfig().default_server_id ?? null;\r\n}\r\n\r\nexport function getDefaultServerName(): string | null {\r\n return loadConfig().default_server_name ?? null;\r\n}\r\n\r\nexport function setDefaultServer(id: string, name: string): void {\r\n const cfg = loadConfig();\r\n cfg.default_server_id = id;\r\n cfg.default_server_name = name;\r\n saveConfig(cfg);\r\n}\r\n\r\nexport function requireToken(): string {\r\n const token = loadToken();\r\n if (!token) {\r\n console.error('Error: Not configured. Run \"discli init\" first.');\r\n process.exit(1);\r\n }\r\n return token;\r\n}\r\n\r\nexport function requireServer(override?: string): string {\r\n const server = override || getDefaultServer();\r\n if (!server) {\r\n console.error('Error: No server selected. Run \"discli server select\" or use --server <id>.');\r\n process.exit(1);\r\n }\r\n return server;\r\n}\r\n","const BASE = 'https://discord.com/api/v10';\r\n\r\nexport const PERMISSION: Record<string, bigint> = {\r\n view_channel: 1n << 10n,\r\n send_messages: 1n << 11n,\r\n send_messages_in_threads: 1n << 38n,\r\n create_public_threads: 1n << 35n,\r\n create_private_threads: 1n << 36n,\r\n embed_links: 1n << 14n,\r\n attach_files: 1n << 15n,\r\n add_reactions: 1n << 6n,\r\n use_external_emojis: 1n << 18n,\r\n read_message_history: 1n << 16n,\r\n mention_everyone: 1n << 17n,\r\n manage_messages: 1n << 13n,\r\n manage_channels: 1n << 4n,\r\n manage_roles: 1n << 28n,\r\n connect: 1n << 20n,\r\n speak: 1n << 21n,\r\n mute_members: 1n << 22n,\r\n deafen_members: 1n << 23n,\r\n move_members: 1n << 24n,\r\n use_voice_activity: 1n << 25n,\r\n};\r\n\r\nexport const CHANNEL_TYPE: Record<string, number> = {\r\n text: 0,\r\n voice: 2,\r\n category: 4,\r\n announcement: 5,\r\n stage: 13,\r\n forum: 15,\r\n};\r\n\r\nexport const CHANNEL_TYPE_NAME: Record<number, string> = Object.fromEntries(\r\n Object.entries(CHANNEL_TYPE).map(([k, v]) => [v, k])\r\n);\r\n\r\nexport class DiscordAPI {\r\n private token: string;\r\n\r\n constructor(token: string) {\r\n this.token = token;\r\n }\r\n\r\n private async request(method: string, path: string, body?: unknown): Promise<unknown> {\r\n const headers: Record<string, string> = {\r\n Authorization: `Bot ${this.token}`,\r\n };\r\n if (body) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n const res = await fetch(`${BASE}${path}`, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (res.status === 429) {\r\n const data = (await res.json()) as { retry_after?: number };\r\n console.error(`Rate limited. Retry after ${data.retry_after ?? '?'}s.`);\r\n process.exit(1);\r\n }\r\n if (res.status === 403) {\r\n console.error('403 Forbidden — missing permissions.');\r\n process.exit(4);\r\n }\r\n if (res.status === 404) {\r\n console.error('404 Not found.');\r\n process.exit(3);\r\n }\r\n if (res.status >= 400) {\r\n const text = await res.text();\r\n console.error(`Discord API error ${res.status}: ${text.slice(0, 200)}`);\r\n process.exit(1);\r\n }\r\n\r\n if (res.status === 204) return null;\r\n return res.json();\r\n }\r\n\r\n // ── Guilds ──\r\n\r\n async listGuilds(): Promise<Guild[]> {\r\n return (await this.request('GET', '/users/@me/guilds')) as Guild[];\r\n }\r\n\r\n async getGuild(guildId: string): Promise<GuildFull> {\r\n return (await this.request('GET', `/guilds/${guildId}?with_counts=true`)) as GuildFull;\r\n }\r\n\r\n // ── Audit Log ──\r\n\r\n async getAuditLog(\r\n guildId: string,\r\n opts?: { user_id?: string; action_type?: number; limit?: number; before?: string }\r\n ): Promise<AuditLog> {\r\n const params = new URLSearchParams();\r\n if (opts?.user_id) params.set('user_id', opts.user_id);\r\n if (opts?.action_type !== undefined) params.set('action_type', String(opts.action_type));\r\n if (opts?.limit) params.set('limit', String(Math.min(opts.limit, 100)));\r\n if (opts?.before) params.set('before', opts.before);\r\n const qs = params.toString();\r\n return (await this.request('GET', `/guilds/${guildId}/audit-logs${qs ? '?' + qs : ''}`)) as AuditLog;\r\n }\r\n\r\n // ── Channels ──\r\n\r\n async listChannels(guildId: string): Promise<Channel[]> {\r\n return (await this.request('GET', `/guilds/${guildId}/channels`)) as Channel[];\r\n }\r\n\r\n async createChannel(\r\n guildId: string,\r\n opts: { name: string; type?: number; parent_id?: string; topic?: string }\r\n ): Promise<Channel> {\r\n return (await this.request('POST', `/guilds/${guildId}/channels`, opts)) as Channel;\r\n }\r\n\r\n // ── Messages ──\r\n\r\n async sendMessage(channelId: string, data: MessagePayload): Promise<Message> {\r\n return (await this.request('POST', `/channels/${channelId}/messages`, data)) as Message;\r\n }\r\n\r\n async getMessages(channelId: string, limit = 50, before?: string): Promise<Message[]> {\r\n let path = `/channels/${channelId}/messages?limit=${Math.min(limit, 100)}`;\r\n if (before) path += `&before=${before}`;\r\n return (await this.request('GET', path)) as Message[];\r\n }\r\n\r\n async getMessage(channelId: string, messageId: string): Promise<Message> {\r\n return (await this.request('GET', `/channels/${channelId}/messages/${messageId}`)) as Message;\r\n }\r\n\r\n async editMessage(channelId: string, messageId: string, data: MessagePayload): Promise<Message> {\r\n return (await this.request('PATCH', `/channels/${channelId}/messages/${messageId}`, data)) as Message;\r\n }\r\n\r\n // ── Reactions ──\r\n\r\n async addReaction(channelId: string, messageId: string, emoji: string): Promise<void> {\r\n const encoded = encodeURIComponent(emoji);\r\n await this.request('PUT', `/channels/${channelId}/messages/${messageId}/reactions/${encoded}/@me`);\r\n }\r\n\r\n async removeReaction(channelId: string, messageId: string, emoji: string): Promise<void> {\r\n const encoded = encodeURIComponent(emoji);\r\n await this.request('DELETE', `/channels/${channelId}/messages/${messageId}/reactions/${encoded}/@me`);\r\n }\r\n\r\n // ── Threads ──\r\n\r\n async createThread(channelId: string, name: string, messageId?: string): Promise<Channel> {\r\n if (messageId) {\r\n return (await this.request('POST', `/channels/${channelId}/messages/${messageId}/threads`, {\r\n name, auto_archive_duration: 1440\r\n })) as Channel;\r\n }\r\n return (await this.request('POST', `/channels/${channelId}/threads`, {\r\n name, type: 11, auto_archive_duration: 1440\r\n })) as Channel;\r\n }\r\n\r\n async deleteMessage(channelId: string, messageId: string): Promise<void> {\r\n await this.request('DELETE', `/channels/${channelId}/messages/${messageId}`);\r\n }\r\n\r\n async pinMessage(channelId: string, messageId: string): Promise<void> {\r\n await this.request('PUT', `/channels/${channelId}/pins/${messageId}`);\r\n }\r\n\r\n async unpinMessage(channelId: string, messageId: string): Promise<void> {\r\n await this.request('DELETE', `/channels/${channelId}/pins/${messageId}`);\r\n }\r\n\r\n async getPinnedMessages(channelId: string): Promise<Message[]> {\r\n return (await this.request('GET', `/channels/${channelId}/pins`)) as Message[];\r\n }\r\n\r\n async deleteChannel(channelId: string): Promise<void> {\r\n await this.request('DELETE', `/channels/${channelId}`);\r\n }\r\n\r\n async modifyChannel(channelId: string, data: Record<string, unknown>): Promise<Channel> {\r\n return (await this.request('PATCH', `/channels/${channelId}`, data)) as Channel;\r\n }\r\n\r\n async getChannel(channelId: string): Promise<Channel> {\r\n return (await this.request('GET', `/channels/${channelId}`)) as Channel;\r\n }\r\n\r\n async editChannelPermission(\r\n channelId: string,\r\n overwriteId: string,\r\n data: { allow: string; deny: string; type: number }\r\n ): Promise<void> {\r\n await this.request('PUT', `/channels/${channelId}/permissions/${overwriteId}`, data);\r\n }\r\n\r\n async deleteChannelPermission(channelId: string, overwriteId: string): Promise<void> {\r\n await this.request('DELETE', `/channels/${channelId}/permissions/${overwriteId}`);\r\n }\r\n\r\n // ── Roles ──\r\n\r\n async listRoles(guildId: string): Promise<Role[]> {\r\n return (await this.request('GET', `/guilds/${guildId}/roles`)) as Role[];\r\n }\r\n\r\n async createRole(guildId: string, data: Record<string, unknown>): Promise<Role> {\r\n return (await this.request('POST', `/guilds/${guildId}/roles`, data)) as Role;\r\n }\r\n\r\n async modifyRole(guildId: string, roleId: string, data: Record<string, unknown>): Promise<Role> {\r\n return (await this.request('PATCH', `/guilds/${guildId}/roles/${roleId}`, data)) as Role;\r\n }\r\n\r\n async reorderRoles(guildId: string, positions: { id: string; position: number }[]): Promise<Role[]> {\r\n return (await this.request('PATCH', `/guilds/${guildId}/roles`, positions)) as Role[];\r\n }\r\n\r\n async deleteRole(guildId: string, roleId: string): Promise<void> {\r\n await this.request('DELETE', `/guilds/${guildId}/roles/${roleId}`);\r\n }\r\n\r\n async addRoleToMember(guildId: string, userId: string, roleId: string): Promise<void> {\r\n await this.request('PUT', `/guilds/${guildId}/members/${userId}/roles/${roleId}`);\r\n }\r\n\r\n async removeRoleFromMember(guildId: string, userId: string, roleId: string): Promise<void> {\r\n await this.request('DELETE', `/guilds/${guildId}/members/${userId}/roles/${roleId}`);\r\n }\r\n\r\n // ── Members ──\r\n\r\n async listMembers(guildId: string, limit = 100): Promise<Member[]> {\r\n return (await this.request('GET', `/guilds/${guildId}/members?limit=${Math.min(limit, 1000)}`)) as Member[];\r\n }\r\n\r\n async getMember(guildId: string, userId: string): Promise<Member> {\r\n return (await this.request('GET', `/guilds/${guildId}/members/${userId}`)) as Member;\r\n }\r\n\r\n async kickMember(guildId: string, userId: string): Promise<void> {\r\n await this.request('DELETE', `/guilds/${guildId}/members/${userId}`);\r\n }\r\n\r\n async banMember(guildId: string, userId: string): Promise<void> {\r\n await this.request('PUT', `/guilds/${guildId}/bans/${userId}`);\r\n }\r\n\r\n async modifyMember(guildId: string, userId: string, data: Record<string, unknown>): Promise<Member> {\r\n return (await this.request('PATCH', `/guilds/${guildId}/members/${userId}`, data)) as Member;\r\n }\r\n}\r\n\r\n// ── Types ──\r\n\r\nexport interface Guild {\r\n id: string;\r\n name: string;\r\n icon: string | null;\r\n owner: boolean;\r\n permissions: string;\r\n}\r\n\r\nexport interface GuildFull extends Guild {\r\n approximate_member_count?: number;\r\n approximate_presence_count?: number;\r\n description: string | null;\r\n premium_tier: number;\r\n premium_subscription_count: number;\r\n}\r\n\r\nexport interface PermissionOverwrite {\r\n id: string;\r\n type: number; // 0 = role, 1 = member\r\n allow: string;\r\n deny: string;\r\n}\r\n\r\nexport interface Channel {\r\n id: string;\r\n name: string;\r\n type: number;\r\n position: number;\r\n parent_id: string | null;\r\n topic?: string | null;\r\n permission_overwrites?: PermissionOverwrite[];\r\n}\r\n\r\nexport interface Role {\r\n id: string;\r\n name: string;\r\n color: number;\r\n position: number;\r\n permissions: string;\r\n managed: boolean;\r\n mentionable: boolean;\r\n}\r\n\r\nexport interface Member {\r\n user?: {\r\n id: string;\r\n username: string;\r\n global_name: string | null;\r\n };\r\n nick: string | null;\r\n roles: string[];\r\n joined_at: string;\r\n}\r\n\r\nexport interface Embed {\r\n title?: string;\r\n description?: string;\r\n url?: string;\r\n color?: number;\r\n timestamp?: string;\r\n footer?: { text: string; icon_url?: string };\r\n image?: { url: string };\r\n thumbnail?: { url: string };\r\n author?: { name: string; url?: string; icon_url?: string };\r\n fields?: { name: string; value: string; inline?: boolean }[];\r\n}\r\n\r\nexport interface MessagePayload {\r\n content?: string;\r\n embeds?: Embed[];\r\n message_reference?: { message_id: string };\r\n}\r\n\r\nexport interface Message {\r\n id: string;\r\n channel_id: string;\r\n content: string;\r\n timestamp: string;\r\n edited_timestamp: string | null;\r\n pinned: boolean;\r\n author: {\r\n id: string;\r\n username: string;\r\n bot?: boolean;\r\n };\r\n embeds?: Embed[];\r\n}\r\n\r\nexport interface AuditLogEntry {\r\n id: string;\r\n user_id: string | null;\r\n target_id: string | null;\r\n action_type: number;\r\n reason?: string;\r\n changes?: { key: string; old_value?: unknown; new_value?: unknown }[];\r\n}\r\n\r\nexport interface AuditLog {\r\n audit_log_entries: AuditLogEntry[];\r\n users: { id: string; username: string }[];\r\n}\r\n\r\nexport const AUDIT_ACTION: Record<string, number> = {\r\n guild_update: 1,\r\n channel_create: 10,\r\n channel_update: 11,\r\n channel_delete: 12,\r\n member_kick: 20,\r\n member_prune: 21,\r\n member_ban_add: 22,\r\n member_ban_remove: 23,\r\n member_update: 24,\r\n member_role_update: 25,\r\n bot_add: 28,\r\n role_create: 30,\r\n role_update: 31,\r\n role_delete: 32,\r\n invite_create: 40,\r\n invite_delete: 42,\r\n webhook_create: 50,\r\n webhook_update: 51,\r\n webhook_delete: 52,\r\n emoji_create: 60,\r\n emoji_delete: 62,\r\n message_delete: 72,\r\n message_bulk_delete: 73,\r\n message_pin: 74,\r\n message_unpin: 75,\r\n thread_create: 110,\r\n thread_update: 111,\r\n thread_delete: 112,\r\n automod_rule_create: 140,\r\n automod_rule_update: 141,\r\n automod_rule_delete: 142,\r\n automod_block_message: 143,\r\n integration_create: 80,\r\n integration_update: 81,\r\n integration_delete: 82,\r\n};\r\n\r\nexport const AUDIT_ACTION_NAME: Record<number, string> = Object.fromEntries(\r\n Object.entries(AUDIT_ACTION).map(([k, v]) => [v, k])\r\n);\r\n","import { Command } from 'commander';\r\nimport { saveToken, setDefaultServer, loadToken } from '../utils/config.js';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { readFileSync } from 'fs';\r\n\r\nexport function registerInit(program: Command): void {\r\n program\r\n .command('init')\r\n .description('Set up discli with your bot token and default server')\r\n .option('--token <token>', 'Bot token (or reads from stdin)')\r\n .action(async (opts) => {\r\n let token = opts.token;\r\n\r\n if (!token) {\r\n // Try reading from stdin if piped\r\n if (!process.stdin.isTTY) {\r\n token = readFileSync(0, 'utf-8').trim();\r\n }\r\n }\r\n\r\n if (!token) {\r\n // Check if already configured\r\n const existing = loadToken();\r\n if (existing) {\r\n console.log('Already configured. Use --token to update.');\r\n token = existing;\r\n } else {\r\n console.error('Usage: discli init --token <your-bot-token>');\r\n console.error(' Get your token from https://discord.com/developers/applications');\r\n process.exit(2);\r\n }\r\n }\r\n\r\n // Validate token\r\n const api = new DiscordAPI(token);\r\n let guilds;\r\n try {\r\n guilds = await api.listGuilds();\r\n } catch {\r\n console.error('Invalid token or cannot connect to Discord.');\r\n process.exit(1);\r\n }\r\n\r\n saveToken(token);\r\n console.log(`Token saved to ~/.discli/.env`);\r\n\r\n if (guilds.length === 0) {\r\n console.log('Bot is not in any servers yet. Add it to a server first.');\r\n return;\r\n }\r\n\r\n console.log('\\nServers:');\r\n guilds.forEach((g, i) => {\r\n console.log(` ${i + 1}. ${g.name} (${g.id})`);\r\n });\r\n\r\n // Auto-select if only one server\r\n if (guilds.length === 1) {\r\n setDefaultServer(guilds[0].id, guilds[0].name);\r\n console.log(`\\nDefault server: ${guilds[0].name}`);\r\n } else {\r\n console.log(`\\nSet default with: discli server select <id>`);\r\n }\r\n\r\n console.log('\\nReady! Try: discli server info');\r\n });\r\n}\r\n","import { stringify as yamlStringify } from 'yaml';\r\n\r\nexport function resolveFormat(explicit: string): string {\r\n if (explicit !== 'auto') return explicit;\r\n return process.stdout.isTTY ? 'table' : 'yaml';\r\n}\r\n\r\nexport function printResult(data: unknown, format: string): void {\r\n const fmt = resolveFormat(format);\r\n\r\n if (fmt === 'json') {\r\n console.log(JSON.stringify(data, null, 2));\r\n return;\r\n }\r\n\r\n if (fmt === 'yaml') {\r\n console.log(yamlStringify(data, { indent: 2 }).trimEnd());\r\n return;\r\n }\r\n\r\n if (Array.isArray(data)) {\r\n if (data.length === 0) {\r\n console.log(' (none)');\r\n return;\r\n }\r\n if (typeof data[0] === 'object') {\r\n printTable(data as Record<string, unknown>[]);\r\n } else {\r\n data.forEach((item) => console.log(` ${item}`));\r\n }\r\n return;\r\n }\r\n\r\n if (typeof data === 'object' && data !== null) {\r\n const obj = data as Record<string, unknown>;\r\n const maxKey = Math.max(...Object.keys(obj).map((k) => k.length));\r\n for (const [k, v] of Object.entries(obj)) {\r\n console.log(` ${k.padEnd(maxKey)} ${v}`);\r\n }\r\n return;\r\n }\r\n\r\n console.log(String(data));\r\n}\r\n\r\nexport function printTable(rows: Record<string, unknown>[], columns?: string[]): void {\r\n if (rows.length === 0) {\r\n console.log(' (none)');\r\n return;\r\n }\r\n\r\n const cols = columns ?? Object.keys(rows[0]);\r\n const widths: Record<string, number> = {};\r\n for (const col of cols) {\r\n widths[col] = col.length;\r\n }\r\n for (const row of rows) {\r\n for (const col of cols) {\r\n widths[col] = Math.max(widths[col], String(row[col] ?? '').length);\r\n }\r\n }\r\n\r\n const header = cols.map((c) => c.toUpperCase().padEnd(widths[c])).join(' ');\r\n const sep = cols.map((c) => '─'.repeat(widths[c])).join(' ');\r\n console.log(` ${header}`);\r\n console.log(` ${sep}`);\r\n\r\n for (const row of rows) {\r\n const line = cols.map((c) => String(row[c] ?? '').padEnd(widths[c])).join(' ');\r\n console.log(` ${line}`);\r\n }\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { requireToken, requireServer, setDefaultServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\n\r\nexport function registerServer(program: Command): void {\r\n const server = program\r\n .command('server')\r\n .description('Manage and inspect servers');\r\n\r\n server\r\n .command('list')\r\n .description('List all servers the bot is in')\r\n .action(async () => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guilds = await api.listGuilds();\r\n\r\n if (fmt !== 'table') {\r\n printResult(guilds, fmt);\r\n return;\r\n }\r\n\r\n const rows = guilds.map((g) => ({\r\n id: g.id,\r\n name: g.name,\r\n owner: g.owner ? 'yes' : 'no',\r\n }));\r\n console.log('\\nServers');\r\n console.log('───────');\r\n printResult(rows, fmt);\r\n });\r\n\r\n server\r\n .command('select')\r\n .description('Set the default server')\r\n .argument('<id>', 'Server ID')\r\n .action(async (id: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guild = await api.getGuild(id);\r\n setDefaultServer(guild.id, guild.name);\r\n console.log(`Default server set to: ${guild.name} (${guild.id})`);\r\n });\r\n\r\n server\r\n .command('info')\r\n .description('Show server details')\r\n .action(async () => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const guild = await api.getGuild(guildId);\r\n\r\n if (fmt !== 'table') {\r\n printResult(guild, fmt);\r\n return;\r\n }\r\n\r\n const info = {\r\n name: guild.name,\r\n id: guild.id,\r\n description: guild.description || '(none)',\r\n members: guild.approximate_member_count ?? '?',\r\n online: guild.approximate_presence_count ?? '?',\r\n boosts: guild.premium_subscription_count,\r\n boost_tier: guild.premium_tier,\r\n };\r\n\r\n console.log(`\\n${guild.name}`);\r\n console.log('─'.repeat(guild.name.length));\r\n printResult(info, fmt);\r\n });\r\n}\r\n","import { DiscordAPI, CHANNEL_TYPE_NAME } from './api.js';\r\nimport type { Channel, Role, Member } from './api.js';\r\n\r\nexport async function resolveChannel(\r\n api: DiscordAPI,\r\n guildId: string,\r\n name: string\r\n): Promise<Channel> {\r\n const channels = await api.listChannels(guildId);\r\n\r\n // Try ID match\r\n const byId = channels.find((c) => c.id === name);\r\n if (byId) return byId;\r\n\r\n // Strip # prefix\r\n const clean = name.replace(/^#/, '');\r\n\r\n const matches = channels.filter((c) => c.name.toLowerCase() === clean.toLowerCase());\r\n if (matches.length === 1) return matches[0];\r\n if (matches.length > 1) {\r\n const names = matches.map((m) => `#${m.name} (${CHANNEL_TYPE_NAME[m.type] ?? '?'})`).join(', ');\r\n console.error(`Ambiguous channel \"${clean}\". Matches: ${names}`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`Channel \"${name}\" not found.`);\r\n process.exit(3);\r\n}\r\n\r\nexport async function resolveCategory(\r\n api: DiscordAPI,\r\n guildId: string,\r\n name: string\r\n): Promise<Channel> {\r\n const channels = await api.listChannels(guildId);\r\n\r\n const byId = channels.find((c) => c.id === name && c.type === 4);\r\n if (byId) return byId;\r\n\r\n const matches = channels.filter(\r\n (c) => c.type === 4 && c.name.toLowerCase() === name.toLowerCase()\r\n );\r\n if (matches.length === 1) return matches[0];\r\n if (matches.length > 1) {\r\n console.error(`Ambiguous category \"${name}\".`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`Category \"${name}\" not found.`);\r\n process.exit(3);\r\n}\r\n\r\nexport async function resolveRole(\r\n api: DiscordAPI,\r\n guildId: string,\r\n name: string\r\n): Promise<Role> {\r\n const roles = await api.listRoles(guildId);\r\n\r\n const byId = roles.find((r) => r.id === name);\r\n if (byId) return byId;\r\n\r\n const clean = name.replace(/^@/, '');\r\n const matches = roles.filter((r) => r.name.toLowerCase() === clean.toLowerCase());\r\n if (matches.length === 1) return matches[0];\r\n if (matches.length > 1) {\r\n const names = matches.map((m) => `@${m.name}`).join(', ');\r\n console.error(`Ambiguous role \"${clean}\". Matches: ${names}`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`Role \"${name}\" not found.`);\r\n process.exit(3);\r\n}\r\n\r\nexport async function resolveMember(\r\n api: DiscordAPI,\r\n guildId: string,\r\n name: string\r\n): Promise<Member> {\r\n // Try as ID\r\n if (/^\\d+$/.test(name)) {\r\n try {\r\n return await api.getMember(guildId, name);\r\n } catch {\r\n // fall through to search\r\n }\r\n }\r\n\r\n const members = await api.listMembers(guildId, 1000);\r\n const clean = name.replace(/^@/, '').toLowerCase();\r\n\r\n const matches = members.filter((m) => {\r\n const username = m.user?.username?.toLowerCase() ?? '';\r\n const globalName = m.user?.global_name?.toLowerCase() ?? '';\r\n const nick = m.nick?.toLowerCase() ?? '';\r\n return username === clean || globalName === clean || nick === clean;\r\n });\r\n\r\n if (matches.length === 1) return matches[0];\r\n if (matches.length > 1) {\r\n const names = matches.map((m) => m.user?.username).join(', ');\r\n console.error(`Ambiguous user \"${name}\". Matches: ${names}`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`Member \"${name}\" not found.`);\r\n process.exit(3);\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI, CHANNEL_TYPE, CHANNEL_TYPE_NAME } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveChannel, resolveCategory } from '../utils/resolve.js';\r\n\r\nexport function registerChannel(program: Command): void {\r\n const channel = program\r\n .command('channel')\r\n .description('Manage server channels');\r\n\r\n channel\r\n .command('list')\r\n .description('List all channels grouped by category')\r\n .option('-n <count>', 'Limit number of channels shown', parseInt)\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n let channels = await api.listChannels(guildId);\r\n if (opts.n) channels = channels.slice(0, opts.n);\r\n\r\n if (fmt !== 'table') {\r\n printResult(channels, fmt);\r\n return;\r\n }\r\n\r\n // Group by category\r\n const categories = channels\r\n .filter((c) => c.type === 4)\r\n .sort((a, b) => a.position - b.position);\r\n const uncategorized = channels.filter(\r\n (c) => c.type !== 4 && !c.parent_id\r\n );\r\n\r\n if (uncategorized.length > 0) {\r\n console.log('\\n (no category)');\r\n for (const ch of uncategorized.sort((a, b) => a.position - b.position)) {\r\n const type = CHANNEL_TYPE_NAME[ch.type] ?? '?';\r\n console.log(` ${type === 'text' ? '#' : '🔊'} ${ch.name}`);\r\n }\r\n }\r\n\r\n for (const cat of categories) {\r\n console.log(`\\n ${cat.name.toUpperCase()}`);\r\n const children = channels\r\n .filter((c) => c.parent_id === cat.id && c.type !== 4)\r\n .sort((a, b) => a.position - b.position);\r\n for (const ch of children) {\r\n const type = CHANNEL_TYPE_NAME[ch.type] ?? '?';\r\n const prefix = type === 'voice' || type === 'stage' ? '🔊' : '#';\r\n const topic = ch.topic ? ` — ${ch.topic}` : '';\r\n console.log(` ${prefix} ${ch.name}${topic}`);\r\n }\r\n }\r\n console.log();\r\n });\r\n\r\n channel\r\n .command('create')\r\n .description('Create a new channel')\r\n .argument('<name>', 'Channel name')\r\n .option('--type <type>', 'Channel type: text, voice, category, announcement, stage, forum', 'text')\r\n .option('--category <name>', 'Parent category name or ID')\r\n .option('--topic <topic>', 'Channel topic')\r\n .option('--dry-run', 'Show what would be created without creating it')\r\n .action(async (name: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n\r\n const channelType = CHANNEL_TYPE[opts.type];\r\n if (channelType === undefined) {\r\n console.error(`Unknown channel type: ${opts.type}. Use: ${Object.keys(CHANNEL_TYPE).join(', ')}`);\r\n process.exit(2);\r\n }\r\n\r\n let parentId: string | undefined;\r\n if (opts.category) {\r\n const cat = await resolveCategory(api, guildId, opts.category);\r\n parentId = cat.id;\r\n }\r\n\r\n if (opts.dryRun) {\r\n const result = { action: 'create_channel', name, type: opts.type, category: opts.category ?? null, topic: opts.topic ?? null };\r\n printResult(result, fmt);\r\n return;\r\n }\r\n\r\n const ch = await api.createChannel(guildId, {\r\n name,\r\n type: channelType,\r\n parent_id: parentId,\r\n topic: opts.topic,\r\n });\r\n\r\n if (fmt !== 'table') {\r\n printResult(ch, fmt);\r\n } else {\r\n console.log(`Created #${ch.name} (${CHANNEL_TYPE_NAME[ch.type] ?? '?'}) — ${ch.id}`);\r\n }\r\n });\r\n\r\n channel\r\n .command('delete')\r\n .description('Delete a channel')\r\n .argument('<name>', 'Channel name or ID')\r\n .option('--confirm', 'Required to actually delete')\r\n .action(async (name: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, name);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will delete #${ch.name} (${ch.id}). Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.deleteChannel(ch.id);\r\n console.log(`Deleted #${ch.name}`);\r\n });\r\n\r\n channel\r\n .command('rename')\r\n .description('Rename a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<new-name>', 'New channel name')\r\n .option('--dry-run', 'Show what would change')\r\n .action(async (channelName: string, newName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n if (opts.dryRun) {\r\n printResult({ action: 'rename_channel', from: ch.name, to: newName, id: ch.id }, fmt);\r\n return;\r\n }\r\n\r\n await api.modifyChannel(ch.id, { name: newName });\r\n console.log(`Renamed #${ch.name} → #${newName}`);\r\n });\r\n\r\n channel\r\n .command('topic')\r\n .description('Set a channel topic')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<topic>', 'New topic text')\r\n .action(async (channelName: string, topic: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const updated = await api.modifyChannel(ch.id, { topic });\r\n if (fmt !== 'table') {\r\n printResult(updated, fmt);\r\n } else {\r\n console.log(`Set topic for #${ch.name}: ${topic}`);\r\n }\r\n });\r\n\r\n channel\r\n .command('move')\r\n .description('Move a channel to a category')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('--category <name>', 'Target category name or ID')\r\n .option('--position <n>', 'Position within category', parseInt)\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const update: Record<string, unknown> = {};\r\n if (opts.category) {\r\n const cat = await resolveCategory(api, guildId, opts.category);\r\n update.parent_id = cat.id;\r\n }\r\n if (opts.position !== undefined) {\r\n update.position = opts.position;\r\n }\r\n\r\n if (Object.keys(update).length === 0) {\r\n console.error('Specify --category and/or --position.');\r\n process.exit(2);\r\n }\r\n\r\n const updated = await api.modifyChannel(ch.id, update);\r\n if (fmt !== 'table') {\r\n printResult(updated, fmt);\r\n } else {\r\n console.log(`Moved #${ch.name}${opts.category ? ` → ${opts.category}` : ''}${opts.position !== undefined ? ` (position ${opts.position})` : ''}`);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveRole, resolveMember } from '../utils/resolve.js';\r\n\r\nexport function registerRole(program: Command): void {\r\n const role = program\r\n .command('role')\r\n .description('Manage server roles');\r\n\r\n role\r\n .command('list')\r\n .description('List all roles')\r\n .option('-n <count>', 'Limit number of roles shown', parseInt)\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const roles = await api.listRoles(guildId);\r\n\r\n const sorted = roles.sort((a, b) => b.position - a.position).slice(0, opts.n ?? roles.length);\r\n\r\n if (fmt !== 'table') {\r\n printResult(sorted, fmt);\r\n return;\r\n }\r\n\r\n const rows = sorted.map((r) => ({\r\n name: r.name,\r\n id: r.id,\r\n color: r.color ? `#${r.color.toString(16).padStart(6, '0')}` : '(none)',\r\n managed: r.managed ? 'bot' : '',\r\n position: r.position,\r\n }));\r\n\r\n console.log('\\nRoles');\r\n console.log('─────');\r\n printResult(rows, fmt);\r\n });\r\n\r\n role\r\n .command('create')\r\n .description('Create a new role')\r\n .argument('<name>', 'Role name')\r\n .option('--color <hex>', 'Color hex (e.g. #ff5733)')\r\n .option('--mentionable', 'Allow anyone to mention this role')\r\n .option('--dry-run', 'Show what would be created')\r\n .action(async (name: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n\r\n const data: Record<string, unknown> = { name };\r\n if (opts.color) {\r\n data.color = parseInt(opts.color.replace('#', ''), 16);\r\n }\r\n if (opts.mentionable) {\r\n data.mentionable = true;\r\n }\r\n\r\n if (opts.dryRun) {\r\n printResult({ action: 'create_role', ...data }, fmt);\r\n return;\r\n }\r\n\r\n const r = await api.createRole(guildId, data);\r\n if (fmt !== 'table') {\r\n printResult(r, fmt);\r\n } else {\r\n console.log(`Created role @${r.name} — ${r.id}`);\r\n }\r\n });\r\n\r\n role\r\n .command('delete')\r\n .description('Delete a role')\r\n .argument('<name>', 'Role name or ID')\r\n .option('--confirm', 'Required to actually delete')\r\n .action(async (name: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const r = await resolveRole(api, guildId, name);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will delete @${r.name} (${r.id}). Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.deleteRole(guildId, r.id);\r\n console.log(`Deleted role @${r.name}`);\r\n });\r\n\r\n role\r\n .command('assign')\r\n .description('Assign a role to a member')\r\n .argument('<role>', 'Role name or ID')\r\n .argument('<user>', 'Username or ID')\r\n .action(async (roleName: string, userName: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const r = await resolveRole(api, guildId, roleName);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n await api.addRoleToMember(guildId, m.user!.id, r.id);\r\n console.log(`Assigned @${r.name} to ${m.user!.username}`);\r\n });\r\n\r\n role\r\n .command('remove')\r\n .description('Remove a role from a member')\r\n .argument('<role>', 'Role name or ID')\r\n .argument('<user>', 'Username or ID')\r\n .action(async (roleName: string, userName: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const r = await resolveRole(api, guildId, roleName);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n await api.removeRoleFromMember(guildId, m.user!.id, r.id);\r\n console.log(`Removed @${r.name} from ${m.user!.username}`);\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveMember } from '../utils/resolve.js';\r\n\r\nexport function registerMember(program: Command): void {\r\n const member = program\r\n .command('member')\r\n .description('Manage server members');\r\n\r\n member\r\n .command('list')\r\n .description('List server members')\r\n .option('-n, --limit <n>', 'Max members to show', '100')\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const members = await api.listMembers(guildId, parseInt(opts.limit));\r\n\r\n if (fmt !== 'table') {\r\n printResult(members, fmt);\r\n return;\r\n }\r\n\r\n const rows = members.map((m) => ({\r\n username: m.user?.username ?? '?',\r\n display: m.user?.global_name ?? m.nick ?? '',\r\n nick: m.nick ?? '',\r\n roles: m.roles.length,\r\n joined: m.joined_at?.slice(0, 10) ?? '?',\r\n }));\r\n\r\n console.log(`\\nMembers (${members.length})`);\r\n console.log('──────────');\r\n printResult(rows, fmt);\r\n });\r\n\r\n member\r\n .command('info')\r\n .description('Show member details')\r\n .argument('<user>', 'Username or ID')\r\n .action(async (userName: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n if (fmt !== 'table') {\r\n printResult(m, fmt);\r\n return;\r\n }\r\n\r\n const roles = await api.listRoles(guildId);\r\n const memberRoles = m.roles\r\n .map((rid) => roles.find((r) => r.id === rid)?.name ?? rid)\r\n .join(', ');\r\n\r\n const info = {\r\n username: m.user?.username ?? '?',\r\n display_name: m.user?.global_name ?? '(none)',\r\n nickname: m.nick ?? '(none)',\r\n id: m.user?.id ?? '?',\r\n roles: memberRoles || '(none)',\r\n joined: m.joined_at?.slice(0, 10) ?? '?',\r\n };\r\n\r\n console.log(`\\n${m.user?.username ?? 'Member'}`);\r\n console.log('─'.repeat((m.user?.username ?? 'Member').length));\r\n printResult(info, fmt);\r\n });\r\n\r\n member\r\n .command('kick')\r\n .description('Kick a member from the server')\r\n .argument('<user>', 'Username or ID')\r\n .option('--reason <text>', 'Reason for kick')\r\n .option('--confirm', 'Required to actually kick')\r\n .action(async (userName: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will kick ${m.user!.username} (${m.user!.id}). Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.kickMember(guildId, m.user!.id);\r\n console.log(`Kicked ${m.user!.username}${opts.reason ? ` — ${opts.reason}` : ''}`);\r\n });\r\n\r\n member\r\n .command('ban')\r\n .description('Ban a member from the server')\r\n .argument('<user>', 'Username or ID')\r\n .option('--reason <text>', 'Reason for ban')\r\n .option('--confirm', 'Required to actually ban')\r\n .action(async (userName: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will BAN ${m.user!.username} (${m.user!.id}). Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.banMember(guildId, m.user!.id);\r\n console.log(`Banned ${m.user!.username}${opts.reason ? ` — ${opts.reason}` : ''}`);\r\n });\r\n\r\n member\r\n .command('nick')\r\n .description('Change a member\\'s nickname')\r\n .argument('<user>', 'Username or ID')\r\n .argument('<nickname>', 'New nickname')\r\n .action(async (userName: string, nickname: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n await api.modifyMember(guildId, m.user!.id, { nick: nickname });\r\n if (fmt !== 'table') {\r\n printResult({ action: 'nick', user: m.user!.username, nick: nickname }, fmt);\r\n } else {\r\n console.log(`Set nickname for ${m.user!.username} → ${nickname}`);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI, PERMISSION } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveChannel, resolveRole } from '../utils/resolve.js';\r\n\r\nfunction parsePermissions(perms: string): bigint {\r\n let bits = 0n;\r\n for (const p of perms.split(',')) {\r\n const name = p.trim().toLowerCase();\r\n const val = PERMISSION[name];\r\n if (val === undefined) {\r\n console.error(`Unknown permission: ${name}`);\r\n console.error(`Available: ${Object.keys(PERMISSION).join(', ')}`);\r\n process.exit(2);\r\n }\r\n bits |= val;\r\n }\r\n return bits;\r\n}\r\n\r\nfunction describePermissions(bitfield: string): string[] {\r\n const bits = BigInt(bitfield);\r\n if (bits === 0n) return [];\r\n return Object.entries(PERMISSION)\r\n .filter(([, val]) => (bits & val) === val)\r\n .map(([name]) => name);\r\n}\r\n\r\nexport function registerPermission(program: Command): void {\r\n const perm = program\r\n .command('permission')\r\n .alias('perm')\r\n .description('Manage channel permissions');\r\n\r\n perm\r\n .command('view')\r\n .description('View permission overwrites for a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .action(async (channelName: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const full = await api.getChannel(ch.id);\r\n const overwrites = full.permission_overwrites ?? [];\r\n const roles = await api.listRoles(guildId);\r\n\r\n if (fmt !== 'table') {\r\n printResult(overwrites, fmt);\r\n return;\r\n }\r\n\r\n if (overwrites.length === 0) {\r\n console.log(`\\n#${ch.name}: no permission overwrites (inherits from category/server)`);\r\n return;\r\n }\r\n\r\n console.log(`\\n#${ch.name} — Permission Overwrites`);\r\n console.log('─'.repeat(40));\r\n\r\n for (const ow of overwrites) {\r\n const target = ow.type === 0\r\n ? roles.find((r) => r.id === ow.id)?.name ?? ow.id\r\n : `member:${ow.id}`;\r\n const allowed = describePermissions(ow.allow);\r\n const denied = describePermissions(ow.deny);\r\n\r\n console.log(`\\n @${target} (${ow.type === 0 ? 'role' : 'member'})`);\r\n if (allowed.length > 0) console.log(` ✅ allow: ${allowed.join(', ')}`);\r\n if (denied.length > 0) console.log(` ❌ deny: ${denied.join(', ')}`);\r\n if (allowed.length === 0 && denied.length === 0) console.log(` (neutral)`);\r\n }\r\n console.log();\r\n });\r\n\r\n perm\r\n .command('set')\r\n .description('Set permission overwrite for a role on a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<role>', 'Role name or ID')\r\n .option('--allow <perms>', 'Comma-separated permissions to allow')\r\n .option('--deny <perms>', 'Comma-separated permissions to deny')\r\n .option('--dry-run', 'Show what would change')\r\n .action(async (channelName: string, roleName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n const role = await resolveRole(api, guildId, roleName);\r\n\r\n if (!opts.allow && !opts.deny) {\r\n console.error('Specify --allow and/or --deny with comma-separated permissions.');\r\n console.error(`Available: ${Object.keys(PERMISSION).join(', ')}`);\r\n process.exit(2);\r\n }\r\n\r\n const allow = opts.allow ? parsePermissions(opts.allow) : 0n;\r\n const deny = opts.deny ? parsePermissions(opts.deny) : 0n;\r\n\r\n if (opts.dryRun) {\r\n printResult({\r\n action: 'set_permission',\r\n channel: ch.name,\r\n role: role.name,\r\n allow: opts.allow ?? '(none)',\r\n deny: opts.deny ?? '(none)',\r\n }, fmt);\r\n return;\r\n }\r\n\r\n await api.editChannelPermission(ch.id, role.id, {\r\n allow: allow.toString(),\r\n deny: deny.toString(),\r\n type: 0, // role\r\n });\r\n\r\n if (fmt !== 'table') {\r\n printResult({ channel: ch.name, role: role.name, allow: allow.toString(), deny: deny.toString() }, fmt);\r\n } else {\r\n console.log(`Set permissions on #${ch.name} for @${role.name}`);\r\n if (opts.allow) console.log(` ✅ allow: ${opts.allow}`);\r\n if (opts.deny) console.log(` ❌ deny: ${opts.deny}`);\r\n }\r\n });\r\n\r\n perm\r\n .command('lock')\r\n .description('Make a channel read-only for @everyone')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('--dry-run', 'Show what would change')\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n // @everyone role ID = guild ID\r\n const deny = PERMISSION.send_messages\r\n | PERMISSION.send_messages_in_threads\r\n | PERMISSION.create_public_threads;\r\n\r\n if (opts.dryRun) {\r\n printResult({ action: 'lock', channel: ch.name, deny_for: '@everyone' }, fmt);\r\n return;\r\n }\r\n\r\n await api.editChannelPermission(ch.id, guildId, {\r\n allow: '0',\r\n deny: deny.toString(),\r\n type: 0,\r\n });\r\n\r\n console.log(`Locked #${ch.name} — read-only for @everyone`);\r\n });\r\n\r\n perm\r\n .command('unlock')\r\n .description('Remove read-only restriction for @everyone')\r\n .argument('<channel>', 'Channel name or ID')\r\n .action(async (channelName: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.deleteChannelPermission(ch.id, guildId);\r\n console.log(`Unlocked #${ch.name} — @everyone can send messages`);\r\n });\r\n\r\n perm\r\n .command('list')\r\n .description('List all available permission names')\r\n .action(() => {\r\n const fmt = resolveFormat(program.opts().format);\r\n if (fmt !== 'table') {\r\n const perms = Object.entries(PERMISSION).map(([name, val]) => ({ name, bit: val.toString() }));\r\n printResult(perms, fmt);\r\n } else {\r\n console.log('\\nAvailable Permissions');\r\n console.log('────────────────────');\r\n for (const name of Object.keys(PERMISSION)) {\r\n console.log(` ${name}`);\r\n }\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport type { Embed, MessagePayload } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveChannel } from '../utils/resolve.js';\r\n\r\nfunction parseColor(color: string): number {\r\n return parseInt(color.replace('#', ''), 16);\r\n}\r\n\r\nexport function registerMessage(program: Command): void {\r\n const message = program\r\n .command('message')\r\n .alias('msg')\r\n .description('Send, read, and manage messages');\r\n\r\n message\r\n .command('send')\r\n .description('Send a message to a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<text>', 'Message content (supports Discord markdown)')\r\n .option('--reply <id>', 'Reply to a message ID')\r\n .action(async (channelName: string, text: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const payload: MessagePayload = { content: text };\r\n if (opts.reply) {\r\n payload.message_reference = { message_id: opts.reply };\r\n }\r\n\r\n const msg = await api.sendMessage(ch.id, payload);\r\n if (fmt !== 'table') {\r\n printResult(msg, fmt);\r\n } else {\r\n console.log(`Sent message to #${ch.name} (${msg.id})`);\r\n }\r\n });\r\n\r\n message\r\n .command('embed')\r\n .description('Send an embed (rich card) to a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('--title <text>', 'Embed title')\r\n .option('--description <text>', 'Embed description (supports markdown)')\r\n .option('--color <hex>', 'Embed color (e.g. #5865F2)')\r\n .option('--url <url>', 'Title link URL')\r\n .option('--image <url>', 'Large image URL')\r\n .option('--thumbnail <url>', 'Small thumbnail URL')\r\n .option('--footer <text>', 'Footer text')\r\n .option('--author <name>', 'Author name')\r\n .option('--field <value...>', 'Add field: \"Name|Value\" or \"Name|Value|inline\"')\r\n .option('--content <text>', 'Text content above the embed')\r\n .option('--reply <id>', 'Reply to a message ID')\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const embed: Embed = {};\r\n if (opts.title) embed.title = opts.title;\r\n if (opts.description) embed.description = opts.description;\r\n if (opts.color) embed.color = parseColor(opts.color);\r\n if (opts.url) embed.url = opts.url;\r\n if (opts.image) embed.image = { url: opts.image };\r\n if (opts.thumbnail) embed.thumbnail = { url: opts.thumbnail };\r\n if (opts.footer) embed.footer = { text: opts.footer };\r\n if (opts.author) embed.author = { name: opts.author };\r\n if (opts.field) {\r\n embed.fields = (opts.field as string[]).map((f: string) => {\r\n const parts = f.split('|');\r\n return {\r\n name: parts[0],\r\n value: parts[1] || '',\r\n inline: parts[2] === 'inline',\r\n };\r\n });\r\n }\r\n\r\n if (!embed.title && !embed.description) {\r\n console.error('Provide at least --title or --description for the embed.');\r\n process.exit(2);\r\n }\r\n\r\n const payload: MessagePayload = { embeds: [embed] };\r\n if (opts.content) payload.content = opts.content;\r\n if (opts.reply) payload.message_reference = { message_id: opts.reply };\r\n\r\n const msg = await api.sendMessage(ch.id, payload);\r\n if (fmt !== 'table') {\r\n printResult(msg, fmt);\r\n } else {\r\n console.log(`Sent embed to #${ch.name} (${msg.id})`);\r\n }\r\n });\r\n\r\n message\r\n .command('read')\r\n .description('Read recent messages from a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('-n <count>', 'Number of messages to fetch', '10')\r\n .option('--before <id>', 'Fetch messages before this message ID')\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const messages = await api.getMessages(ch.id, parseInt(opts.n), opts.before);\r\n\r\n if (fmt !== 'table') {\r\n printResult(messages, fmt);\r\n return;\r\n }\r\n\r\n console.log(`\\n#${ch.name} — last ${messages.length} messages`);\r\n console.log('─'.repeat(40));\r\n\r\n for (const msg of messages.reverse()) {\r\n const time = new Date(msg.timestamp).toLocaleString();\r\n const bot = msg.author.bot ? ' [BOT]' : '';\r\n const edited = msg.edited_timestamp ? ' (edited)' : '';\r\n const pinned = msg.pinned ? ' 📌' : '';\r\n console.log(` ${msg.author.username}${bot} — ${time}${edited}${pinned}`);\r\n if (msg.content) console.log(` ${msg.content}`);\r\n if (msg.embeds && msg.embeds.length > 0) {\r\n for (const e of msg.embeds) {\r\n if (e.title) console.log(` [Embed] ${e.title}`);\r\n if (e.description) console.log(` ${e.description.slice(0, 100)}`);\r\n }\r\n }\r\n console.log();\r\n }\r\n });\r\n\r\n message\r\n .command('edit')\r\n .description('Edit a message sent by the bot')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID to edit')\r\n .argument('<text>', 'New message content')\r\n .action(async (channelName: string, messageId: string, text: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const msg = await api.editMessage(ch.id, messageId, { content: text });\r\n if (fmt !== 'table') {\r\n printResult(msg, fmt);\r\n } else {\r\n console.log(`Edited message ${messageId} in #${ch.name}`);\r\n }\r\n });\r\n\r\n message\r\n .command('delete')\r\n .description('Delete a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID to delete')\r\n .option('--confirm', 'Required to actually delete')\r\n .action(async (channelName: string, messageId: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will delete message ${messageId} in #${ch.name}. Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.deleteMessage(ch.id, messageId);\r\n console.log(`Deleted message ${messageId} from #${ch.name}`);\r\n });\r\n\r\n message\r\n .command('react')\r\n .description('Add a reaction to a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID')\r\n .argument('<emoji>', 'Emoji to react with (e.g. 👍 or :thumbsup:)')\r\n .action(async (channelName: string, messageId: string, emoji: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.addReaction(ch.id, messageId, emoji);\r\n console.log(`Reacted ${emoji} on message ${messageId} in #${ch.name}`);\r\n });\r\n\r\n message\r\n .command('unreact')\r\n .description('Remove bot reaction from a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID')\r\n .argument('<emoji>', 'Emoji to remove')\r\n .action(async (channelName: string, messageId: string, emoji: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.removeReaction(ch.id, messageId, emoji);\r\n console.log(`Removed ${emoji} reaction from message ${messageId}`);\r\n });\r\n\r\n message\r\n .command('pin')\r\n .description('Pin a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID to pin')\r\n .action(async (channelName: string, messageId: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.pinMessage(ch.id, messageId);\r\n console.log(`Pinned message ${messageId} in #${ch.name}`);\r\n });\r\n\r\n message\r\n .command('unpin')\r\n .description('Unpin a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID to unpin')\r\n .action(async (channelName: string, messageId: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.unpinMessage(ch.id, messageId);\r\n console.log(`Unpinned message ${messageId} in #${ch.name}`);\r\n });\r\n\r\n message\r\n .command('pins')\r\n .description('List pinned messages in a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .action(async (channelName: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const pins = await api.getPinnedMessages(ch.id);\r\n\r\n if (fmt !== 'table') {\r\n printResult(pins, fmt);\r\n return;\r\n }\r\n\r\n if (pins.length === 0) {\r\n console.log(`\\n#${ch.name}: no pinned messages`);\r\n return;\r\n }\r\n\r\n console.log(`\\n#${ch.name} — ${pins.length} pinned`);\r\n console.log('─'.repeat(30));\r\n for (const msg of pins) {\r\n const time = new Date(msg.timestamp).toLocaleString();\r\n console.log(` ${msg.author.username} — ${time}`);\r\n if (msg.content) console.log(` ${msg.content}`);\r\n console.log(` ID: ${msg.id}`);\r\n console.log();\r\n }\r\n });\r\n\r\n message\r\n .command('thread')\r\n .description('Create a thread from a message or in a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<name>', 'Thread name')\r\n .option('--message <id>', 'Create thread from this message ID')\r\n .action(async (channelName: string, name: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const thread = await api.createThread(ch.id, name, opts.message);\r\n if (fmt !== 'table') {\r\n printResult(thread, fmt);\r\n } else {\r\n console.log(`Created thread \"${name}\" in #${ch.name} (${thread.id})`);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI, AUDIT_ACTION, AUDIT_ACTION_NAME } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\n\r\nexport function registerAudit(program: Command): void {\r\n const audit = program\r\n .command('audit')\r\n .description('View server audit log');\r\n\r\n audit\r\n .command('log')\r\n .description('View recent audit log entries')\r\n .option('-n <count>', 'Number of entries to fetch', '20')\r\n .option('--type <action>', 'Filter by action type (e.g. member_kick, channel_create)')\r\n .option('--user <id>', 'Filter by user who performed the action')\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n\r\n const queryOpts: { limit?: number; action_type?: number; user_id?: string } = {\r\n limit: parseInt(opts.n),\r\n };\r\n\r\n if (opts.type) {\r\n const actionType = AUDIT_ACTION[opts.type];\r\n if (actionType === undefined) {\r\n console.error(`Unknown action type: ${opts.type}`);\r\n console.error(`Available: ${Object.keys(AUDIT_ACTION).join(', ')}`);\r\n process.exit(2);\r\n }\r\n queryOpts.action_type = actionType;\r\n }\r\n\r\n if (opts.user) {\r\n queryOpts.user_id = opts.user;\r\n }\r\n\r\n const log = await api.getAuditLog(guildId, queryOpts);\r\n\r\n if (fmt !== 'table') {\r\n printResult(log.audit_log_entries, fmt);\r\n return;\r\n }\r\n\r\n const userMap = new Map(log.users.map((u) => [u.id, u.username]));\r\n\r\n console.log('\\nAudit Log');\r\n console.log('─────────');\r\n\r\n if (log.audit_log_entries.length === 0) {\r\n console.log(' (no entries)');\r\n return;\r\n }\r\n\r\n for (const entry of log.audit_log_entries) {\r\n const who = entry.user_id ? userMap.get(entry.user_id) ?? entry.user_id : '(system)';\r\n const action = AUDIT_ACTION_NAME[entry.action_type] ?? `unknown(${entry.action_type})`;\r\n const target = entry.target_id ?? '';\r\n const reason = entry.reason ? ` — \"${entry.reason}\"` : '';\r\n\r\n console.log(` ${who} → ${action} ${target}${reason}`);\r\n\r\n if (entry.changes && entry.changes.length > 0) {\r\n for (const change of entry.changes.slice(0, 3)) {\r\n const old = change.old_value !== undefined ? String(change.old_value).slice(0, 30) : '';\r\n const nw = change.new_value !== undefined ? String(change.new_value).slice(0, 30) : '';\r\n if (old && nw) {\r\n console.log(` ${change.key}: ${old} → ${nw}`);\r\n } else if (nw) {\r\n console.log(` ${change.key}: ${nw}`);\r\n }\r\n }\r\n }\r\n }\r\n console.log();\r\n });\r\n\r\n audit\r\n .command('types')\r\n .description('List available audit log action types')\r\n .action(() => {\r\n const fmt = resolveFormat(program.opts().format);\r\n if (fmt !== 'table') {\r\n const types = Object.entries(AUDIT_ACTION).map(([name, value]) => ({ name, value }));\r\n printResult(types, fmt);\r\n } else {\r\n console.log('\\nAudit Log Action Types');\r\n console.log('─────────────────────');\r\n for (const [name, value] of Object.entries(AUDIT_ACTION)) {\r\n console.log(` ${name.padEnd(25)} ${value}`);\r\n }\r\n }\r\n });\r\n}\r\n"],"mappings":";;;AAAA,SAAS,eAAe;;;ACAxB,SAAS,YAAY,WAAW,cAAc,qBAAqB;AACnE,SAAS,eAAe;AACxB,SAAS,YAAY;AAErB,IAAM,aAAa,KAAK,QAAQ,GAAG,SAAS;AAC5C,IAAM,cAAc,KAAK,YAAY,aAAa;AAClD,IAAM,WAAW,KAAK,YAAY,MAAM;AAOxC,SAAS,kBAAwB;AAC/B,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,cAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AAAA,EAC3C;AACF;AAEO,SAAS,aAAyB;AACvC,MAAI,CAAC,WAAW,WAAW,EAAG,QAAO,CAAC;AACtC,MAAI;AACF,WAAO,KAAK,MAAM,aAAa,aAAa,OAAO,CAAC;AAAA,EACtD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEO,SAAS,WAAW,MAAwB;AACjD,kBAAgB;AAChB,gBAAc,aAAa,KAAK,UAAU,MAAM,MAAM,CAAC,IAAI,IAAI;AACjE;AAEO,SAAS,YAA2B;AACzC,MAAI,CAAC,WAAW,QAAQ,EAAG,QAAO;AAClC,QAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,QAAM,QAAQ,QAAQ,MAAM,mBAAmB;AAC/C,SAAO,QAAQ,MAAM,CAAC,EAAE,KAAK,IAAI;AACnC;AAEO,SAAS,UAAU,OAAqB;AAC7C,kBAAgB;AAChB,gBAAc,UAAU,aAAa,KAAK;AAAA,CAAI;AAChD;AAEO,SAAS,mBAAkC;AAChD,SAAO,WAAW,EAAE,qBAAqB;AAC3C;AAMO,SAAS,iBAAiB,IAAY,MAAoB;AAC/D,QAAM,MAAM,WAAW;AACvB,MAAI,oBAAoB;AACxB,MAAI,sBAAsB;AAC1B,aAAW,GAAG;AAChB;AAEO,SAAS,eAAuB;AACrC,QAAM,QAAQ,UAAU;AACxB,MAAI,CAAC,OAAO;AACV,YAAQ,MAAM,iDAAiD;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,SAAO;AACT;AAEO,SAAS,cAAc,UAA2B;AACvD,QAAM,SAAS,YAAY,iBAAiB;AAC5C,MAAI,CAAC,QAAQ;AACX,YAAQ,MAAM,6EAA6E;AAC3F,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,SAAO;AACT;;;AC5EA,IAAM,OAAO;AAEN,IAAM,aAAqC;AAAA,EAChD,cAAc,MAAM;AAAA,EACpB,eAAe,MAAM;AAAA,EACrB,0BAA0B,MAAM;AAAA,EAChC,uBAAuB,MAAM;AAAA,EAC7B,wBAAwB,MAAM;AAAA,EAC9B,aAAa,MAAM;AAAA,EACnB,cAAc,MAAM;AAAA,EACpB,eAAe,MAAM;AAAA,EACrB,qBAAqB,MAAM;AAAA,EAC3B,sBAAsB,MAAM;AAAA,EAC5B,kBAAkB,MAAM;AAAA,EACxB,iBAAiB,MAAM;AAAA,EACvB,iBAAiB,MAAM;AAAA,EACvB,cAAc,MAAM;AAAA,EACpB,SAAS,MAAM;AAAA,EACf,OAAO,MAAM;AAAA,EACb,cAAc,MAAM;AAAA,EACpB,gBAAgB,MAAM;AAAA,EACtB,cAAc,MAAM;AAAA,EACpB,oBAAoB,MAAM;AAC5B;AAEO,IAAM,eAAuC;AAAA,EAClD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AAAA,EACV,cAAc;AAAA,EACd,OAAO;AAAA,EACP,OAAO;AACT;AAEO,IAAM,oBAA4C,OAAO;AAAA,EAC9D,OAAO,QAAQ,YAAY,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACrD;AAEO,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EAER,YAAY,OAAe;AACzB,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,MAAc,QAAQ,QAAgB,MAAc,MAAkC;AACpF,UAAM,UAAkC;AAAA,MACtC,eAAe,OAAO,KAAK,KAAK;AAAA,IAClC;AACA,QAAI,MAAM;AACR,cAAQ,cAAc,IAAI;AAAA,IAC5B;AAEA,UAAM,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,IAAI,IAAI;AAAA,MACxC;AAAA,MACA;AAAA,MACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACtC,CAAC;AAED,QAAI,IAAI,WAAW,KAAK;AACtB,YAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,cAAQ,MAAM,6BAA6B,KAAK,eAAe,GAAG,IAAI;AACtE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,IAAI,WAAW,KAAK;AACtB,cAAQ,MAAM,2CAAsC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,IAAI,WAAW,KAAK;AACtB,cAAQ,MAAM,gBAAgB;AAC9B,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,IAAI,UAAU,KAAK;AACrB,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,cAAQ,MAAM,qBAAqB,IAAI,MAAM,KAAK,KAAK,MAAM,GAAG,GAAG,CAAC,EAAE;AACtE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA,EAIA,MAAM,aAA+B;AACnC,WAAQ,MAAM,KAAK,QAAQ,OAAO,mBAAmB;AAAA,EACvD;AAAA,EAEA,MAAM,SAAS,SAAqC;AAClD,WAAQ,MAAM,KAAK,QAAQ,OAAO,WAAW,OAAO,mBAAmB;AAAA,EACzE;AAAA;AAAA,EAIA,MAAM,YACJ,SACA,MACmB;AACnB,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,MAAM,QAAS,QAAO,IAAI,WAAW,KAAK,OAAO;AACrD,QAAI,MAAM,gBAAgB,OAAW,QAAO,IAAI,eAAe,OAAO,KAAK,WAAW,CAAC;AACvF,QAAI,MAAM,MAAO,QAAO,IAAI,SAAS,OAAO,KAAK,IAAI,KAAK,OAAO,GAAG,CAAC,CAAC;AACtE,QAAI,MAAM,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AAClD,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAQ,MAAM,KAAK,QAAQ,OAAO,WAAW,OAAO,cAAc,KAAK,MAAM,KAAK,EAAE,EAAE;AAAA,EACxF;AAAA;AAAA,EAIA,MAAM,aAAa,SAAqC;AACtD,WAAQ,MAAM,KAAK,QAAQ,OAAO,WAAW,OAAO,WAAW;AAAA,EACjE;AAAA,EAEA,MAAM,cACJ,SACA,MACkB;AAClB,WAAQ,MAAM,KAAK,QAAQ,QAAQ,WAAW,OAAO,aAAa,IAAI;AAAA,EACxE;AAAA;AAAA,EAIA,MAAM,YAAY,WAAmB,MAAwC;AAC3E,WAAQ,MAAM,KAAK,QAAQ,QAAQ,aAAa,SAAS,aAAa,IAAI;AAAA,EAC5E;AAAA,EAEA,MAAM,YAAY,WAAmB,QAAQ,IAAI,QAAqC;AACpF,QAAI,OAAO,aAAa,SAAS,mBAAmB,KAAK,IAAI,OAAO,GAAG,CAAC;AACxE,QAAI,OAAQ,SAAQ,WAAW,MAAM;AACrC,WAAQ,MAAM,KAAK,QAAQ,OAAO,IAAI;AAAA,EACxC;AAAA,EAEA,MAAM,WAAW,WAAmB,WAAqC;AACvE,WAAQ,MAAM,KAAK,QAAQ,OAAO,aAAa,SAAS,aAAa,SAAS,EAAE;AAAA,EAClF;AAAA,EAEA,MAAM,YAAY,WAAmB,WAAmB,MAAwC;AAC9F,WAAQ,MAAM,KAAK,QAAQ,SAAS,aAAa,SAAS,aAAa,SAAS,IAAI,IAAI;AAAA,EAC1F;AAAA;AAAA,EAIA,MAAM,YAAY,WAAmB,WAAmB,OAA8B;AACpF,UAAM,UAAU,mBAAmB,KAAK;AACxC,UAAM,KAAK,QAAQ,OAAO,aAAa,SAAS,aAAa,SAAS,cAAc,OAAO,MAAM;AAAA,EACnG;AAAA,EAEA,MAAM,eAAe,WAAmB,WAAmB,OAA8B;AACvF,UAAM,UAAU,mBAAmB,KAAK;AACxC,UAAM,KAAK,QAAQ,UAAU,aAAa,SAAS,aAAa,SAAS,cAAc,OAAO,MAAM;AAAA,EACtG;AAAA;AAAA,EAIA,MAAM,aAAa,WAAmB,MAAc,WAAsC;AACxF,QAAI,WAAW;AACb,aAAQ,MAAM,KAAK,QAAQ,QAAQ,aAAa,SAAS,aAAa,SAAS,YAAY;AAAA,QACzF;AAAA,QAAM,uBAAuB;AAAA,MAC/B,CAAC;AAAA,IACH;AACA,WAAQ,MAAM,KAAK,QAAQ,QAAQ,aAAa,SAAS,YAAY;AAAA,MACnE;AAAA,MAAM,MAAM;AAAA,MAAI,uBAAuB;AAAA,IACzC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,cAAc,WAAmB,WAAkC;AACvE,UAAM,KAAK,QAAQ,UAAU,aAAa,SAAS,aAAa,SAAS,EAAE;AAAA,EAC7E;AAAA,EAEA,MAAM,WAAW,WAAmB,WAAkC;AACpE,UAAM,KAAK,QAAQ,OAAO,aAAa,SAAS,SAAS,SAAS,EAAE;AAAA,EACtE;AAAA,EAEA,MAAM,aAAa,WAAmB,WAAkC;AACtE,UAAM,KAAK,QAAQ,UAAU,aAAa,SAAS,SAAS,SAAS,EAAE;AAAA,EACzE;AAAA,EAEA,MAAM,kBAAkB,WAAuC;AAC7D,WAAQ,MAAM,KAAK,QAAQ,OAAO,aAAa,SAAS,OAAO;AAAA,EACjE;AAAA,EAEA,MAAM,cAAc,WAAkC;AACpD,UAAM,KAAK,QAAQ,UAAU,aAAa,SAAS,EAAE;AAAA,EACvD;AAAA,EAEA,MAAM,cAAc,WAAmB,MAAiD;AACtF,WAAQ,MAAM,KAAK,QAAQ,SAAS,aAAa,SAAS,IAAI,IAAI;AAAA,EACpE;AAAA,EAEA,MAAM,WAAW,WAAqC;AACpD,WAAQ,MAAM,KAAK,QAAQ,OAAO,aAAa,SAAS,EAAE;AAAA,EAC5D;AAAA,EAEA,MAAM,sBACJ,WACA,aACA,MACe;AACf,UAAM,KAAK,QAAQ,OAAO,aAAa,SAAS,gBAAgB,WAAW,IAAI,IAAI;AAAA,EACrF;AAAA,EAEA,MAAM,wBAAwB,WAAmB,aAAoC;AACnF,UAAM,KAAK,QAAQ,UAAU,aAAa,SAAS,gBAAgB,WAAW,EAAE;AAAA,EAClF;AAAA;AAAA,EAIA,MAAM,UAAU,SAAkC;AAChD,WAAQ,MAAM,KAAK,QAAQ,OAAO,WAAW,OAAO,QAAQ;AAAA,EAC9D;AAAA,EAEA,MAAM,WAAW,SAAiB,MAA8C;AAC9E,WAAQ,MAAM,KAAK,QAAQ,QAAQ,WAAW,OAAO,UAAU,IAAI;AAAA,EACrE;AAAA,EAEA,MAAM,WAAW,SAAiB,QAAgB,MAA8C;AAC9F,WAAQ,MAAM,KAAK,QAAQ,SAAS,WAAW,OAAO,UAAU,MAAM,IAAI,IAAI;AAAA,EAChF;AAAA,EAEA,MAAM,aAAa,SAAiB,WAAgE;AAClG,WAAQ,MAAM,KAAK,QAAQ,SAAS,WAAW,OAAO,UAAU,SAAS;AAAA,EAC3E;AAAA,EAEA,MAAM,WAAW,SAAiB,QAA+B;AAC/D,UAAM,KAAK,QAAQ,UAAU,WAAW,OAAO,UAAU,MAAM,EAAE;AAAA,EACnE;AAAA,EAEA,MAAM,gBAAgB,SAAiB,QAAgB,QAA+B;AACpF,UAAM,KAAK,QAAQ,OAAO,WAAW,OAAO,YAAY,MAAM,UAAU,MAAM,EAAE;AAAA,EAClF;AAAA,EAEA,MAAM,qBAAqB,SAAiB,QAAgB,QAA+B;AACzF,UAAM,KAAK,QAAQ,UAAU,WAAW,OAAO,YAAY,MAAM,UAAU,MAAM,EAAE;AAAA,EACrF;AAAA;AAAA,EAIA,MAAM,YAAY,SAAiB,QAAQ,KAAwB;AACjE,WAAQ,MAAM,KAAK,QAAQ,OAAO,WAAW,OAAO,kBAAkB,KAAK,IAAI,OAAO,GAAI,CAAC,EAAE;AAAA,EAC/F;AAAA,EAEA,MAAM,UAAU,SAAiB,QAAiC;AAChE,WAAQ,MAAM,KAAK,QAAQ,OAAO,WAAW,OAAO,YAAY,MAAM,EAAE;AAAA,EAC1E;AAAA,EAEA,MAAM,WAAW,SAAiB,QAA+B;AAC/D,UAAM,KAAK,QAAQ,UAAU,WAAW,OAAO,YAAY,MAAM,EAAE;AAAA,EACrE;AAAA,EAEA,MAAM,UAAU,SAAiB,QAA+B;AAC9D,UAAM,KAAK,QAAQ,OAAO,WAAW,OAAO,SAAS,MAAM,EAAE;AAAA,EAC/D;AAAA,EAEA,MAAM,aAAa,SAAiB,QAAgB,MAAgD;AAClG,WAAQ,MAAM,KAAK,QAAQ,SAAS,WAAW,OAAO,YAAY,MAAM,IAAI,IAAI;AAAA,EAClF;AACF;AA0GO,IAAM,eAAuC;AAAA,EAClD,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,eAAe;AAAA,EACf,oBAAoB;AAAA,EACpB,SAAS;AAAA,EACT,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,qBAAqB;AAAA,EACrB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,oBAAoB;AACtB;AAEO,IAAM,oBAA4C,OAAO;AAAA,EAC9D,OAAO,QAAQ,YAAY,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACrD;;;AC/YA,SAAS,gBAAAA,qBAAoB;AAEtB,SAAS,aAAaC,UAAwB;AACnD,EAAAA,SACG,QAAQ,MAAM,EACd,YAAY,sDAAsD,EAClE,OAAO,mBAAmB,iCAAiC,EAC3D,OAAO,OAAO,SAAS;AACtB,QAAI,QAAQ,KAAK;AAEjB,QAAI,CAAC,OAAO;AAEV,UAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,gBAAQD,cAAa,GAAG,OAAO,EAAE,KAAK;AAAA,MACxC;AAAA,IACF;AAEA,QAAI,CAAC,OAAO;AAEV,YAAM,WAAW,UAAU;AAC3B,UAAI,UAAU;AACZ,gBAAQ,IAAI,4CAA4C;AACxD,gBAAQ;AAAA,MACV,OAAO;AACL,gBAAQ,MAAM,6CAA6C;AAC3D,gBAAQ,MAAM,mEAAmE;AACjF,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAGA,UAAM,MAAM,IAAI,WAAW,KAAK;AAChC,QAAI;AACJ,QAAI;AACF,eAAS,MAAM,IAAI,WAAW;AAAA,IAChC,QAAQ;AACN,cAAQ,MAAM,6CAA6C;AAC3D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,cAAU,KAAK;AACf,YAAQ,IAAI,+BAA+B;AAE3C,QAAI,OAAO,WAAW,GAAG;AACvB,cAAQ,IAAI,0DAA0D;AACtE;AAAA,IACF;AAEA,YAAQ,IAAI,YAAY;AACxB,WAAO,QAAQ,CAAC,GAAG,MAAM;AACvB,cAAQ,IAAI,KAAK,IAAI,CAAC,KAAK,EAAE,IAAI,KAAK,EAAE,EAAE,GAAG;AAAA,IAC/C,CAAC;AAGD,QAAI,OAAO,WAAW,GAAG;AACvB,uBAAiB,OAAO,CAAC,EAAE,IAAI,OAAO,CAAC,EAAE,IAAI;AAC7C,cAAQ,IAAI;AAAA,kBAAqB,OAAO,CAAC,EAAE,IAAI,EAAE;AAAA,IACnD,OAAO;AACL,cAAQ,IAAI;AAAA,4CAA+C;AAAA,IAC7D;AAEA,YAAQ,IAAI,kCAAkC;AAAA,EAChD,CAAC;AACL;;;AClEA,SAAS,aAAa,qBAAqB;AAEpC,SAAS,cAAc,UAA0B;AACtD,MAAI,aAAa,OAAQ,QAAO;AAChC,SAAO,QAAQ,OAAO,QAAQ,UAAU;AAC1C;AAEO,SAAS,YAAY,MAAe,QAAsB;AAC/D,QAAM,MAAM,cAAc,MAAM;AAEhC,MAAI,QAAQ,QAAQ;AAClB,YAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AACzC;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ;AAClB,YAAQ,IAAI,cAAc,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,CAAC;AACxD;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,QAAI,KAAK,WAAW,GAAG;AACrB,cAAQ,IAAI,UAAU;AACtB;AAAA,IACF;AACA,QAAI,OAAO,KAAK,CAAC,MAAM,UAAU;AAC/B,iBAAW,IAAiC;AAAA,IAC9C,OAAO;AACL,WAAK,QAAQ,CAAC,SAAS,QAAQ,IAAI,KAAK,IAAI,EAAE,CAAC;AAAA,IACjD;AACA;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,UAAM,MAAM;AACZ,UAAM,SAAS,KAAK,IAAI,GAAG,OAAO,KAAK,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AAChE,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AACxC,cAAQ,IAAI,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,CAAC,EAAE;AAAA,IAC3C;AACA;AAAA,EACF;AAEA,UAAQ,IAAI,OAAO,IAAI,CAAC;AAC1B;AAEO,SAAS,WAAW,MAAiC,SAA0B;AACpF,MAAI,KAAK,WAAW,GAAG;AACrB,YAAQ,IAAI,UAAU;AACtB;AAAA,EACF;AAEA,QAAM,OAAO,WAAW,OAAO,KAAK,KAAK,CAAC,CAAC;AAC3C,QAAM,SAAiC,CAAC;AACxC,aAAW,OAAO,MAAM;AACtB,WAAO,GAAG,IAAI,IAAI;AAAA,EACpB;AACA,aAAW,OAAO,MAAM;AACtB,eAAW,OAAO,MAAM;AACtB,aAAO,GAAG,IAAI,KAAK,IAAI,OAAO,GAAG,GAAG,OAAO,IAAI,GAAG,KAAK,EAAE,EAAE,MAAM;AAAA,IACnE;AAAA,EACF;AAEA,QAAM,SAAS,KAAK,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAC3E,QAAM,MAAM,KAAK,IAAI,CAAC,MAAM,SAAI,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAC5D,UAAQ,IAAI,KAAK,MAAM,EAAE;AACzB,UAAQ,IAAI,KAAK,GAAG,EAAE;AAEtB,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,KAAK,IAAI,CAAC,MAAM,OAAO,IAAI,CAAC,KAAK,EAAE,EAAE,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI;AAC9E,YAAQ,IAAI,KAAK,IAAI,EAAE;AAAA,EACzB;AACF;;;AClEO,SAAS,eAAeE,UAAwB;AACrD,QAAM,SAASA,SACZ,QAAQ,QAAQ,EAChB,YAAY,4BAA4B;AAE3C,SACG,QAAQ,MAAM,EACd,YAAY,gCAAgC,EAC5C,OAAO,YAAY;AAClB,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,SAAS,MAAM,IAAI,WAAW;AAEpC,QAAI,QAAQ,SAAS;AACnB,kBAAY,QAAQ,GAAG;AACvB;AAAA,IACF;AAEA,UAAM,OAAO,OAAO,IAAI,CAAC,OAAO;AAAA,MAC9B,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,OAAO,EAAE,QAAQ,QAAQ;AAAA,IAC3B,EAAE;AACF,YAAQ,IAAI,WAAW;AACvB,YAAQ,IAAI,4CAAS;AACrB,gBAAY,MAAM,GAAG;AAAA,EACvB,CAAC;AAEH,SACG,QAAQ,QAAQ,EAChB,YAAY,wBAAwB,EACpC,SAAS,QAAQ,WAAW,EAC5B,OAAO,OAAO,OAAe;AAC5B,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,QAAQ,MAAM,IAAI,SAAS,EAAE;AACnC,qBAAiB,MAAM,IAAI,MAAM,IAAI;AACrC,YAAQ,IAAI,0BAA0B,MAAM,IAAI,KAAK,MAAM,EAAE,GAAG;AAAA,EAClE,CAAC;AAEH,SACG,QAAQ,MAAM,EACd,YAAY,qBAAqB,EACjC,OAAO,YAAY;AAClB,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,QAAQ,MAAM,IAAI,SAAS,OAAO;AAExC,QAAI,QAAQ,SAAS;AACnB,kBAAY,OAAO,GAAG;AACtB;AAAA,IACF;AAEA,UAAM,OAAO;AAAA,MACX,MAAM,MAAM;AAAA,MACZ,IAAI,MAAM;AAAA,MACV,aAAa,MAAM,eAAe;AAAA,MAClC,SAAS,MAAM,4BAA4B;AAAA,MAC3C,QAAQ,MAAM,8BAA8B;AAAA,MAC5C,QAAQ,MAAM;AAAA,MACd,YAAY,MAAM;AAAA,IACpB;AAEA,YAAQ,IAAI;AAAA,EAAK,MAAM,IAAI,EAAE;AAC7B,YAAQ,IAAI,SAAI,OAAO,MAAM,KAAK,MAAM,CAAC;AACzC,gBAAY,MAAM,GAAG;AAAA,EACvB,CAAC;AACL;;;ACrEA,eAAsB,eACpB,KACA,SACA,MACkB;AAClB,QAAM,WAAW,MAAM,IAAI,aAAa,OAAO;AAG/C,QAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI;AAC/C,MAAI,KAAM,QAAO;AAGjB,QAAM,QAAQ,KAAK,QAAQ,MAAM,EAAE;AAEnC,QAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,MAAM,YAAY,CAAC;AACnF,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAC1C,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,KAAK,kBAAkB,EAAE,IAAI,KAAK,GAAG,GAAG,EAAE,KAAK,IAAI;AAC9F,YAAQ,MAAM,sBAAsB,KAAK,eAAe,KAAK,EAAE;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,MAAM,YAAY,IAAI,cAAc;AAC5C,UAAQ,KAAK,CAAC;AAChB;AAEA,eAAsB,gBACpB,KACA,SACA,MACkB;AAClB,QAAM,WAAW,MAAM,IAAI,aAAa,OAAO;AAE/C,QAAM,OAAO,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE,SAAS,CAAC;AAC/D,MAAI,KAAM,QAAO;AAEjB,QAAM,UAAU,SAAS;AAAA,IACvB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,KAAK,YAAY,MAAM,KAAK,YAAY;AAAA,EACnE;AACA,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAC1C,MAAI,QAAQ,SAAS,GAAG;AACtB,YAAQ,MAAM,uBAAuB,IAAI,IAAI;AAC7C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,MAAM,aAAa,IAAI,cAAc;AAC7C,UAAQ,KAAK,CAAC;AAChB;AAEA,eAAsB,YACpB,KACA,SACA,MACe;AACf,QAAM,QAAQ,MAAM,IAAI,UAAU,OAAO;AAEzC,QAAM,OAAO,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,IAAI;AAC5C,MAAI,KAAM,QAAO;AAEjB,QAAM,QAAQ,KAAK,QAAQ,MAAM,EAAE;AACnC,QAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,MAAM,YAAY,CAAC;AAChF,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAC1C,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI;AACxD,YAAQ,MAAM,mBAAmB,KAAK,eAAe,KAAK,EAAE;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,MAAM,SAAS,IAAI,cAAc;AACzC,UAAQ,KAAK,CAAC;AAChB;AAEA,eAAsB,cACpB,KACA,SACA,MACiB;AAEjB,MAAI,QAAQ,KAAK,IAAI,GAAG;AACtB,QAAI;AACF,aAAO,MAAM,IAAI,UAAU,SAAS,IAAI;AAAA,IAC1C,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,UAAU,MAAM,IAAI,YAAY,SAAS,GAAI;AACnD,QAAM,QAAQ,KAAK,QAAQ,MAAM,EAAE,EAAE,YAAY;AAEjD,QAAM,UAAU,QAAQ,OAAO,CAAC,MAAM;AACpC,UAAM,WAAW,EAAE,MAAM,UAAU,YAAY,KAAK;AACpD,UAAM,aAAa,EAAE,MAAM,aAAa,YAAY,KAAK;AACzD,UAAM,OAAO,EAAE,MAAM,YAAY,KAAK;AACtC,WAAO,aAAa,SAAS,eAAe,SAAS,SAAS;AAAA,EAChE,CAAC;AAED,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAC1C,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,QAAQ,QAAQ,IAAI,CAAC,MAAM,EAAE,MAAM,QAAQ,EAAE,KAAK,IAAI;AAC5D,YAAQ,MAAM,mBAAmB,IAAI,eAAe,KAAK,EAAE;AAC3D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,MAAM,WAAW,IAAI,cAAc;AAC3C,UAAQ,KAAK,CAAC;AAChB;;;ACtGO,SAAS,gBAAgBC,UAAwB;AACtD,QAAM,UAAUA,SACb,QAAQ,SAAS,EACjB,YAAY,wBAAwB;AAEvC,UACG,QAAQ,MAAM,EACd,YAAY,uCAAuC,EACnD,OAAO,cAAc,kCAAkC,QAAQ,EAC/D,OAAO,OAAO,SAAS;AACtB,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,QAAI,WAAW,MAAM,IAAI,aAAa,OAAO;AAC7C,QAAI,KAAK,EAAG,YAAW,SAAS,MAAM,GAAG,KAAK,CAAC;AAE/C,QAAI,QAAQ,SAAS;AACnB,kBAAY,UAAU,GAAG;AACzB;AAAA,IACF;AAGA,UAAM,aAAa,SAChB,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAC1B,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AACzC,UAAM,gBAAgB,SAAS;AAAA,MAC7B,CAAC,MAAM,EAAE,SAAS,KAAK,CAAC,EAAE;AAAA,IAC5B;AAEA,QAAI,cAAc,SAAS,GAAG;AAC5B,cAAQ,IAAI,mBAAmB;AAC/B,iBAAW,MAAM,cAAc,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,GAAG;AACtE,cAAM,OAAO,kBAAkB,GAAG,IAAI,KAAK;AAC3C,gBAAQ,IAAI,OAAO,SAAS,SAAS,MAAM,WAAI,IAAI,GAAG,IAAI,EAAE;AAAA,MAC9D;AAAA,IACF;AAEA,eAAW,OAAO,YAAY;AAC5B,cAAQ,IAAI;AAAA,IAAO,IAAI,KAAK,YAAY,CAAC,EAAE;AAC3C,YAAM,WAAW,SACd,OAAO,CAAC,MAAM,EAAE,cAAc,IAAI,MAAM,EAAE,SAAS,CAAC,EACpD,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;AACzC,iBAAW,MAAM,UAAU;AACzB,cAAM,OAAO,kBAAkB,GAAG,IAAI,KAAK;AAC3C,cAAM,SAAS,SAAS,WAAW,SAAS,UAAU,cAAO;AAC7D,cAAM,QAAQ,GAAG,QAAQ,WAAM,GAAG,KAAK,KAAK;AAC5C,gBAAQ,IAAI,OAAO,MAAM,IAAI,GAAG,IAAI,GAAG,KAAK,EAAE;AAAA,MAChD;AAAA,IACF;AACA,YAAQ,IAAI;AAAA,EACd,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,sBAAsB,EAClC,SAAS,UAAU,cAAc,EACjC,OAAO,iBAAiB,mEAAmE,MAAM,EACjG,OAAO,qBAAqB,4BAA4B,EACxD,OAAO,mBAAmB,eAAe,EACzC,OAAO,aAAa,gDAAgD,EACpE,OAAO,OAAO,MAAc,SAAS;AACpC,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAEnD,UAAM,cAAc,aAAa,KAAK,IAAI;AAC1C,QAAI,gBAAgB,QAAW;AAC7B,cAAQ,MAAM,yBAAyB,KAAK,IAAI,UAAU,OAAO,KAAK,YAAY,EAAE,KAAK,IAAI,CAAC,EAAE;AAChG,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI;AACJ,QAAI,KAAK,UAAU;AACjB,YAAM,MAAM,MAAM,gBAAgB,KAAK,SAAS,KAAK,QAAQ;AAC7D,iBAAW,IAAI;AAAA,IACjB;AAEA,QAAI,KAAK,QAAQ;AACf,YAAM,SAAS,EAAE,QAAQ,kBAAkB,MAAM,MAAM,KAAK,MAAM,UAAU,KAAK,YAAY,MAAM,OAAO,KAAK,SAAS,KAAK;AAC7H,kBAAY,QAAQ,GAAG;AACvB;AAAA,IACF;AAEA,UAAM,KAAK,MAAM,IAAI,cAAc,SAAS;AAAA,MAC1C;AAAA,MACA,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,KAAK;AAAA,IACd,CAAC;AAED,QAAI,QAAQ,SAAS;AACnB,kBAAY,IAAI,GAAG;AAAA,IACrB,OAAO;AACL,cAAQ,IAAI,YAAY,GAAG,IAAI,KAAK,kBAAkB,GAAG,IAAI,KAAK,GAAG,YAAO,GAAG,EAAE,EAAE;AAAA,IACrF;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,kBAAkB,EAC9B,SAAS,UAAU,oBAAoB,EACvC,OAAO,aAAa,6BAA6B,EACjD,OAAO,OAAO,MAAc,SAAS;AACpC,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,IAAI;AAElD,QAAI,CAAC,KAAK,SAAS;AACjB,cAAQ,MAAM,qBAAqB,GAAG,IAAI,KAAK,GAAG,EAAE,8BAA8B;AAClF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,IAAI,cAAc,GAAG,EAAE;AAC7B,YAAQ,IAAI,YAAY,GAAG,IAAI,EAAE;AAAA,EACnC,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,kBAAkB,EAC9B,SAAS,aAAa,oBAAoB,EAC1C,SAAS,cAAc,kBAAkB,EACzC,OAAO,aAAa,wBAAwB,EAC5C,OAAO,OAAO,aAAqB,SAAiB,SAAS;AAC5D,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,QAAI,KAAK,QAAQ;AACf,kBAAY,EAAE,QAAQ,kBAAkB,MAAM,GAAG,MAAM,IAAI,SAAS,IAAI,GAAG,GAAG,GAAG,GAAG;AACpF;AAAA,IACF;AAEA,UAAM,IAAI,cAAc,GAAG,IAAI,EAAE,MAAM,QAAQ,CAAC;AAChD,YAAQ,IAAI,YAAY,GAAG,IAAI,YAAO,OAAO,EAAE;AAAA,EACjD,CAAC;AAEH,UACG,QAAQ,OAAO,EACf,YAAY,qBAAqB,EACjC,SAAS,aAAa,oBAAoB,EAC1C,SAAS,WAAW,gBAAgB,EACpC,OAAO,OAAO,aAAqB,UAAkB;AACpD,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,UAAU,MAAM,IAAI,cAAc,GAAG,IAAI,EAAE,MAAM,CAAC;AACxD,QAAI,QAAQ,SAAS;AACnB,kBAAY,SAAS,GAAG;AAAA,IAC1B,OAAO;AACL,cAAQ,IAAI,kBAAkB,GAAG,IAAI,KAAK,KAAK,EAAE;AAAA,IACnD;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,MAAM,EACd,YAAY,8BAA8B,EAC1C,SAAS,aAAa,oBAAoB,EAC1C,OAAO,qBAAqB,4BAA4B,EACxD,OAAO,kBAAkB,4BAA4B,QAAQ,EAC7D,OAAO,OAAO,aAAqB,SAAS;AAC3C,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,SAAkC,CAAC;AACzC,QAAI,KAAK,UAAU;AACjB,YAAM,MAAM,MAAM,gBAAgB,KAAK,SAAS,KAAK,QAAQ;AAC7D,aAAO,YAAY,IAAI;AAAA,IACzB;AACA,QAAI,KAAK,aAAa,QAAW;AAC/B,aAAO,WAAW,KAAK;AAAA,IACzB;AAEA,QAAI,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AACpC,cAAQ,MAAM,uCAAuC;AACrD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,UAAU,MAAM,IAAI,cAAc,GAAG,IAAI,MAAM;AACrD,QAAI,QAAQ,SAAS;AACnB,kBAAY,SAAS,GAAG;AAAA,IAC1B,OAAO;AACL,cAAQ,IAAI,UAAU,GAAG,IAAI,GAAG,KAAK,WAAW,WAAM,KAAK,QAAQ,KAAK,EAAE,GAAG,KAAK,aAAa,SAAY,cAAc,KAAK,QAAQ,MAAM,EAAE,EAAE;AAAA,IAClJ;AAAA,EACF,CAAC;AACL;;;AC7LO,SAAS,aAAaC,UAAwB;AACnD,QAAM,OAAOA,SACV,QAAQ,MAAM,EACd,YAAY,qBAAqB;AAEpC,OACG,QAAQ,MAAM,EACd,YAAY,gBAAgB,EAC5B,OAAO,cAAc,+BAA+B,QAAQ,EAC5D,OAAO,OAAO,SAAS;AACtB,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,QAAQ,MAAM,IAAI,UAAU,OAAO;AAEzC,UAAM,SAAS,MAAM,KAAK,CAAC,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,KAAK,MAAM,MAAM;AAE5F,QAAI,QAAQ,SAAS;AACnB,kBAAY,QAAQ,GAAG;AACvB;AAAA,IACF;AAEA,UAAM,OAAO,OAAO,IAAI,CAAC,OAAO;AAAA,MAC9B,MAAM,EAAE;AAAA,MACR,IAAI,EAAE;AAAA,MACN,OAAO,EAAE,QAAQ,IAAI,EAAE,MAAM,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,KAAK;AAAA,MAC/D,SAAS,EAAE,UAAU,QAAQ;AAAA,MAC7B,UAAU,EAAE;AAAA,IACd,EAAE;AAEF,YAAQ,IAAI,SAAS;AACrB,YAAQ,IAAI,gCAAO;AACnB,gBAAY,MAAM,GAAG;AAAA,EACvB,CAAC;AAEH,OACG,QAAQ,QAAQ,EAChB,YAAY,mBAAmB,EAC/B,SAAS,UAAU,WAAW,EAC9B,OAAO,iBAAiB,0BAA0B,EAClD,OAAO,iBAAiB,mCAAmC,EAC3D,OAAO,aAAa,4BAA4B,EAChD,OAAO,OAAO,MAAc,SAAS;AACpC,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAEnD,UAAM,OAAgC,EAAE,KAAK;AAC7C,QAAI,KAAK,OAAO;AACd,WAAK,QAAQ,SAAS,KAAK,MAAM,QAAQ,KAAK,EAAE,GAAG,EAAE;AAAA,IACvD;AACA,QAAI,KAAK,aAAa;AACpB,WAAK,cAAc;AAAA,IACrB;AAEA,QAAI,KAAK,QAAQ;AACf,kBAAY,EAAE,QAAQ,eAAe,GAAG,KAAK,GAAG,GAAG;AACnD;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,IAAI,WAAW,SAAS,IAAI;AAC5C,QAAI,QAAQ,SAAS;AACnB,kBAAY,GAAG,GAAG;AAAA,IACpB,OAAO;AACL,cAAQ,IAAI,iBAAiB,EAAE,IAAI,WAAM,EAAE,EAAE,EAAE;AAAA,IACjD;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,QAAQ,EAChB,YAAY,eAAe,EAC3B,SAAS,UAAU,iBAAiB,EACpC,OAAO,aAAa,6BAA6B,EACjD,OAAO,OAAO,MAAc,SAAS;AACpC,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,IAAI,MAAM,YAAY,KAAK,SAAS,IAAI;AAE9C,QAAI,CAAC,KAAK,SAAS;AACjB,cAAQ,MAAM,qBAAqB,EAAE,IAAI,KAAK,EAAE,EAAE,8BAA8B;AAChF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,IAAI,WAAW,SAAS,EAAE,EAAE;AAClC,YAAQ,IAAI,iBAAiB,EAAE,IAAI,EAAE;AAAA,EACvC,CAAC;AAEH,OACG,QAAQ,QAAQ,EAChB,YAAY,2BAA2B,EACvC,SAAS,UAAU,iBAAiB,EACpC,SAAS,UAAU,gBAAgB,EACnC,OAAO,OAAO,UAAkB,aAAqB;AACpD,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,IAAI,MAAM,YAAY,KAAK,SAAS,QAAQ;AAClD,UAAM,IAAI,MAAM,cAAc,KAAK,SAAS,QAAQ;AAEpD,UAAM,IAAI,gBAAgB,SAAS,EAAE,KAAM,IAAI,EAAE,EAAE;AACnD,YAAQ,IAAI,aAAa,EAAE,IAAI,OAAO,EAAE,KAAM,QAAQ,EAAE;AAAA,EAC1D,CAAC;AAEH,OACG,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC,SAAS,UAAU,iBAAiB,EACpC,SAAS,UAAU,gBAAgB,EACnC,OAAO,OAAO,UAAkB,aAAqB;AACpD,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,IAAI,MAAM,YAAY,KAAK,SAAS,QAAQ;AAClD,UAAM,IAAI,MAAM,cAAc,KAAK,SAAS,QAAQ;AAEpD,UAAM,IAAI,qBAAqB,SAAS,EAAE,KAAM,IAAI,EAAE,EAAE;AACxD,YAAQ,IAAI,YAAY,EAAE,IAAI,SAAS,EAAE,KAAM,QAAQ,EAAE;AAAA,EAC3D,CAAC;AACL;;;ACpHO,SAAS,eAAeC,UAAwB;AACrD,QAAM,SAASA,SACZ,QAAQ,QAAQ,EAChB,YAAY,uBAAuB;AAEtC,SACG,QAAQ,MAAM,EACd,YAAY,qBAAqB,EACjC,OAAO,mBAAmB,uBAAuB,KAAK,EACtD,OAAO,OAAO,SAAS;AACtB,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,UAAU,MAAM,IAAI,YAAY,SAAS,SAAS,KAAK,KAAK,CAAC;AAEnE,QAAI,QAAQ,SAAS;AACnB,kBAAY,SAAS,GAAG;AACxB;AAAA,IACF;AAEA,UAAM,OAAO,QAAQ,IAAI,CAAC,OAAO;AAAA,MAC/B,UAAU,EAAE,MAAM,YAAY;AAAA,MAC9B,SAAS,EAAE,MAAM,eAAe,EAAE,QAAQ;AAAA,MAC1C,MAAM,EAAE,QAAQ;AAAA,MAChB,OAAO,EAAE,MAAM;AAAA,MACf,QAAQ,EAAE,WAAW,MAAM,GAAG,EAAE,KAAK;AAAA,IACvC,EAAE;AAEF,YAAQ,IAAI;AAAA,WAAc,QAAQ,MAAM,GAAG;AAC3C,YAAQ,IAAI,8DAAY;AACxB,gBAAY,MAAM,GAAG;AAAA,EACvB,CAAC;AAEH,SACG,QAAQ,MAAM,EACd,YAAY,qBAAqB,EACjC,SAAS,UAAU,gBAAgB,EACnC,OAAO,OAAO,aAAqB;AAClC,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,IAAI,MAAM,cAAc,KAAK,SAAS,QAAQ;AAEpD,QAAI,QAAQ,SAAS;AACnB,kBAAY,GAAG,GAAG;AAClB;AAAA,IACF;AAEA,UAAM,QAAQ,MAAM,IAAI,UAAU,OAAO;AACzC,UAAM,cAAc,EAAE,MACnB,IAAI,CAAC,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,GAAG,QAAQ,GAAG,EACzD,KAAK,IAAI;AAEZ,UAAM,OAAO;AAAA,MACX,UAAU,EAAE,MAAM,YAAY;AAAA,MAC9B,cAAc,EAAE,MAAM,eAAe;AAAA,MACrC,UAAU,EAAE,QAAQ;AAAA,MACpB,IAAI,EAAE,MAAM,MAAM;AAAA,MAClB,OAAO,eAAe;AAAA,MACtB,QAAQ,EAAE,WAAW,MAAM,GAAG,EAAE,KAAK;AAAA,IACvC;AAEA,YAAQ,IAAI;AAAA,EAAK,EAAE,MAAM,YAAY,QAAQ,EAAE;AAC/C,YAAQ,IAAI,SAAI,QAAQ,EAAE,MAAM,YAAY,UAAU,MAAM,CAAC;AAC7D,gBAAY,MAAM,GAAG;AAAA,EACvB,CAAC;AAEH,SACG,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,SAAS,UAAU,gBAAgB,EACnC,OAAO,mBAAmB,iBAAiB,EAC3C,OAAO,aAAa,2BAA2B,EAC/C,OAAO,OAAO,UAAkB,SAAS;AACxC,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,IAAI,MAAM,cAAc,KAAK,SAAS,QAAQ;AAEpD,QAAI,CAAC,KAAK,SAAS;AACjB,cAAQ,MAAM,kBAAkB,EAAE,KAAM,QAAQ,KAAK,EAAE,KAAM,EAAE,8BAA8B;AAC7F,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,IAAI,WAAW,SAAS,EAAE,KAAM,EAAE;AACxC,YAAQ,IAAI,UAAU,EAAE,KAAM,QAAQ,GAAG,KAAK,SAAS,WAAM,KAAK,MAAM,KAAK,EAAE,EAAE;AAAA,EACnF,CAAC;AAEH,SACG,QAAQ,KAAK,EACb,YAAY,8BAA8B,EAC1C,SAAS,UAAU,gBAAgB,EACnC,OAAO,mBAAmB,gBAAgB,EAC1C,OAAO,aAAa,0BAA0B,EAC9C,OAAO,OAAO,UAAkB,SAAS;AACxC,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,IAAI,MAAM,cAAc,KAAK,SAAS,QAAQ;AAEpD,QAAI,CAAC,KAAK,SAAS;AACjB,cAAQ,MAAM,iBAAiB,EAAE,KAAM,QAAQ,KAAK,EAAE,KAAM,EAAE,8BAA8B;AAC5F,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,IAAI,UAAU,SAAS,EAAE,KAAM,EAAE;AACvC,YAAQ,IAAI,UAAU,EAAE,KAAM,QAAQ,GAAG,KAAK,SAAS,WAAM,KAAK,MAAM,KAAK,EAAE,EAAE;AAAA,EACnF,CAAC;AAEH,SACG,QAAQ,MAAM,EACd,YAAY,4BAA6B,EACzC,SAAS,UAAU,gBAAgB,EACnC,SAAS,cAAc,cAAc,EACrC,OAAO,OAAO,UAAkB,aAAqB;AACpD,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,IAAI,MAAM,cAAc,KAAK,SAAS,QAAQ;AAEpD,UAAM,IAAI,aAAa,SAAS,EAAE,KAAM,IAAI,EAAE,MAAM,SAAS,CAAC;AAC9D,QAAI,QAAQ,SAAS;AACnB,kBAAY,EAAE,QAAQ,QAAQ,MAAM,EAAE,KAAM,UAAU,MAAM,SAAS,GAAG,GAAG;AAAA,IAC7E,OAAO;AACL,cAAQ,IAAI,oBAAoB,EAAE,KAAM,QAAQ,WAAM,QAAQ,EAAE;AAAA,IAClE;AAAA,EACF,CAAC;AACL;;;AC7HA,SAAS,iBAAiB,OAAuB;AAC/C,MAAI,OAAO;AACX,aAAW,KAAK,MAAM,MAAM,GAAG,GAAG;AAChC,UAAM,OAAO,EAAE,KAAK,EAAE,YAAY;AAClC,UAAM,MAAM,WAAW,IAAI;AAC3B,QAAI,QAAQ,QAAW;AACrB,cAAQ,MAAM,uBAAuB,IAAI,EAAE;AAC3C,cAAQ,MAAM,cAAc,OAAO,KAAK,UAAU,EAAE,KAAK,IAAI,CAAC,EAAE;AAChE,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,YAAQ;AAAA,EACV;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,UAA4B;AACvD,QAAM,OAAO,OAAO,QAAQ;AAC5B,MAAI,SAAS,GAAI,QAAO,CAAC;AACzB,SAAO,OAAO,QAAQ,UAAU,EAC7B,OAAO,CAAC,CAAC,EAAE,GAAG,OAAO,OAAO,SAAS,GAAG,EACxC,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AACzB;AAEO,SAAS,mBAAmBC,UAAwB;AACzD,QAAM,OAAOA,SACV,QAAQ,YAAY,EACpB,MAAM,MAAM,EACZ,YAAY,4BAA4B;AAE3C,OACG,QAAQ,MAAM,EACd,YAAY,0CAA0C,EACtD,SAAS,aAAa,oBAAoB,EAC1C,OAAO,OAAO,gBAAwB;AACrC,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,OAAO,MAAM,IAAI,WAAW,GAAG,EAAE;AACvC,UAAM,aAAa,KAAK,yBAAyB,CAAC;AAClD,UAAM,QAAQ,MAAM,IAAI,UAAU,OAAO;AAEzC,QAAI,QAAQ,SAAS;AACnB,kBAAY,YAAY,GAAG;AAC3B;AAAA,IACF;AAEA,QAAI,WAAW,WAAW,GAAG;AAC3B,cAAQ,IAAI;AAAA,GAAM,GAAG,IAAI,4DAA4D;AACrF;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,GAAM,GAAG,IAAI,+BAA0B;AACnD,YAAQ,IAAI,SAAI,OAAO,EAAE,CAAC;AAE1B,eAAW,MAAM,YAAY;AAC3B,YAAM,SAAS,GAAG,SAAS,IACvB,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,EAAE,GAAG,QAAQ,GAAG,KAC9C,UAAU,GAAG,EAAE;AACnB,YAAM,UAAU,oBAAoB,GAAG,KAAK;AAC5C,YAAM,SAAS,oBAAoB,GAAG,IAAI;AAE1C,cAAQ,IAAI;AAAA,KAAQ,MAAM,KAAK,GAAG,SAAS,IAAI,SAAS,QAAQ,GAAG;AACnE,UAAI,QAAQ,SAAS,EAAG,SAAQ,IAAI,qBAAgB,QAAQ,KAAK,IAAI,CAAC,EAAE;AACxE,UAAI,OAAO,SAAS,EAAG,SAAQ,IAAI,qBAAgB,OAAO,KAAK,IAAI,CAAC,EAAE;AACtE,UAAI,QAAQ,WAAW,KAAK,OAAO,WAAW,EAAG,SAAQ,IAAI,eAAe;AAAA,IAC9E;AACA,YAAQ,IAAI;AAAA,EACd,CAAC;AAEH,OACG,QAAQ,KAAK,EACb,YAAY,kDAAkD,EAC9D,SAAS,aAAa,oBAAoB,EAC1C,SAAS,UAAU,iBAAiB,EACpC,OAAO,mBAAmB,sCAAsC,EAChE,OAAO,kBAAkB,qCAAqC,EAC9D,OAAO,aAAa,wBAAwB,EAC5C,OAAO,OAAO,aAAqB,UAAkB,SAAS;AAC7D,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AACzD,UAAM,OAAO,MAAM,YAAY,KAAK,SAAS,QAAQ;AAErD,QAAI,CAAC,KAAK,SAAS,CAAC,KAAK,MAAM;AAC7B,cAAQ,MAAM,iEAAiE;AAC/E,cAAQ,MAAM,cAAc,OAAO,KAAK,UAAU,EAAE,KAAK,IAAI,CAAC,EAAE;AAChE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,QAAQ,KAAK,QAAQ,iBAAiB,KAAK,KAAK,IAAI;AAC1D,UAAM,OAAO,KAAK,OAAO,iBAAiB,KAAK,IAAI,IAAI;AAEvD,QAAI,KAAK,QAAQ;AACf,kBAAY;AAAA,QACV,QAAQ;AAAA,QACR,SAAS,GAAG;AAAA,QACZ,MAAM,KAAK;AAAA,QACX,OAAO,KAAK,SAAS;AAAA,QACrB,MAAM,KAAK,QAAQ;AAAA,MACrB,GAAG,GAAG;AACN;AAAA,IACF;AAEA,UAAM,IAAI,sBAAsB,GAAG,IAAI,KAAK,IAAI;AAAA,MAC9C,OAAO,MAAM,SAAS;AAAA,MACtB,MAAM,KAAK,SAAS;AAAA,MACpB,MAAM;AAAA;AAAA,IACR,CAAC;AAED,QAAI,QAAQ,SAAS;AACnB,kBAAY,EAAE,SAAS,GAAG,MAAM,MAAM,KAAK,MAAM,OAAO,MAAM,SAAS,GAAG,MAAM,KAAK,SAAS,EAAE,GAAG,GAAG;AAAA,IACxG,OAAO;AACL,cAAQ,IAAI,uBAAuB,GAAG,IAAI,SAAS,KAAK,IAAI,EAAE;AAC9D,UAAI,KAAK,MAAO,SAAQ,IAAI,mBAAc,KAAK,KAAK,EAAE;AACtD,UAAI,KAAK,KAAM,SAAQ,IAAI,mBAAc,KAAK,IAAI,EAAE;AAAA,IACtD;AAAA,EACF,CAAC;AAEH,OACG,QAAQ,MAAM,EACd,YAAY,wCAAwC,EACpD,SAAS,aAAa,oBAAoB,EAC1C,OAAO,aAAa,wBAAwB,EAC5C,OAAO,OAAO,aAAqB,SAAS;AAC3C,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAGzD,UAAM,OAAO,WAAW,gBACpB,WAAW,2BACX,WAAW;AAEf,QAAI,KAAK,QAAQ;AACf,kBAAY,EAAE,QAAQ,QAAQ,SAAS,GAAG,MAAM,UAAU,YAAY,GAAG,GAAG;AAC5E;AAAA,IACF;AAEA,UAAM,IAAI,sBAAsB,GAAG,IAAI,SAAS;AAAA,MAC9C,OAAO;AAAA,MACP,MAAM,KAAK,SAAS;AAAA,MACpB,MAAM;AAAA,IACR,CAAC;AAED,YAAQ,IAAI,WAAW,GAAG,IAAI,iCAA4B;AAAA,EAC5D,CAAC;AAEH,OACG,QAAQ,QAAQ,EAChB,YAAY,4CAA4C,EACxD,SAAS,aAAa,oBAAoB,EAC1C,OAAO,OAAO,gBAAwB;AACrC,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,IAAI,wBAAwB,GAAG,IAAI,OAAO;AAChD,YAAQ,IAAI,aAAa,GAAG,IAAI,qCAAgC;AAAA,EAClE,CAAC;AAEH,OACG,QAAQ,MAAM,EACd,YAAY,qCAAqC,EACjD,OAAO,MAAM;AACZ,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,QAAI,QAAQ,SAAS;AACnB,YAAM,QAAQ,OAAO,QAAQ,UAAU,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,OAAO,EAAE,MAAM,KAAK,IAAI,SAAS,EAAE,EAAE;AAC7F,kBAAY,OAAO,GAAG;AAAA,IACxB,OAAO;AACL,cAAQ,IAAI,yBAAyB;AACrC,cAAQ,IAAI,0HAAsB;AAClC,iBAAW,QAAQ,OAAO,KAAK,UAAU,GAAG;AAC1C,gBAAQ,IAAI,KAAK,IAAI,EAAE;AAAA,MACzB;AAAA,IACF;AAAA,EACF,CAAC;AACL;;;ACnLA,SAAS,WAAW,OAAuB;AACzC,SAAO,SAAS,MAAM,QAAQ,KAAK,EAAE,GAAG,EAAE;AAC5C;AAEO,SAAS,gBAAgBC,UAAwB;AACtD,QAAM,UAAUA,SACb,QAAQ,SAAS,EACjB,MAAM,KAAK,EACX,YAAY,iCAAiC;AAEhD,UACG,QAAQ,MAAM,EACd,YAAY,6BAA6B,EACzC,SAAS,aAAa,oBAAoB,EAC1C,SAAS,UAAU,6CAA6C,EAChE,OAAO,gBAAgB,uBAAuB,EAC9C,OAAO,OAAO,aAAqB,MAAc,SAAS;AACzD,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,UAA0B,EAAE,SAAS,KAAK;AAChD,QAAI,KAAK,OAAO;AACd,cAAQ,oBAAoB,EAAE,YAAY,KAAK,MAAM;AAAA,IACvD;AAEA,UAAM,MAAM,MAAM,IAAI,YAAY,GAAG,IAAI,OAAO;AAChD,QAAI,QAAQ,SAAS;AACnB,kBAAY,KAAK,GAAG;AAAA,IACtB,OAAO;AACL,cAAQ,IAAI,oBAAoB,GAAG,IAAI,KAAK,IAAI,EAAE,GAAG;AAAA,IACvD;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,OAAO,EACf,YAAY,wCAAwC,EACpD,SAAS,aAAa,oBAAoB,EAC1C,OAAO,kBAAkB,aAAa,EACtC,OAAO,wBAAwB,uCAAuC,EACtE,OAAO,iBAAiB,4BAA4B,EACpD,OAAO,eAAe,gBAAgB,EACtC,OAAO,iBAAiB,iBAAiB,EACzC,OAAO,qBAAqB,qBAAqB,EACjD,OAAO,mBAAmB,aAAa,EACvC,OAAO,mBAAmB,aAAa,EACvC,OAAO,sBAAsB,gDAAgD,EAC7E,OAAO,oBAAoB,8BAA8B,EACzD,OAAO,gBAAgB,uBAAuB,EAC9C,OAAO,OAAO,aAAqB,SAAS;AAC3C,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,QAAe,CAAC;AACtB,QAAI,KAAK,MAAO,OAAM,QAAQ,KAAK;AACnC,QAAI,KAAK,YAAa,OAAM,cAAc,KAAK;AAC/C,QAAI,KAAK,MAAO,OAAM,QAAQ,WAAW,KAAK,KAAK;AACnD,QAAI,KAAK,IAAK,OAAM,MAAM,KAAK;AAC/B,QAAI,KAAK,MAAO,OAAM,QAAQ,EAAE,KAAK,KAAK,MAAM;AAChD,QAAI,KAAK,UAAW,OAAM,YAAY,EAAE,KAAK,KAAK,UAAU;AAC5D,QAAI,KAAK,OAAQ,OAAM,SAAS,EAAE,MAAM,KAAK,OAAO;AACpD,QAAI,KAAK,OAAQ,OAAM,SAAS,EAAE,MAAM,KAAK,OAAO;AACpD,QAAI,KAAK,OAAO;AACd,YAAM,SAAU,KAAK,MAAmB,IAAI,CAAC,MAAc;AACzD,cAAM,QAAQ,EAAE,MAAM,GAAG;AACzB,eAAO;AAAA,UACL,MAAM,MAAM,CAAC;AAAA,UACb,OAAO,MAAM,CAAC,KAAK;AAAA,UACnB,QAAQ,MAAM,CAAC,MAAM;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,CAAC,MAAM,SAAS,CAAC,MAAM,aAAa;AACtC,cAAQ,MAAM,0DAA0D;AACxE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,UAA0B,EAAE,QAAQ,CAAC,KAAK,EAAE;AAClD,QAAI,KAAK,QAAS,SAAQ,UAAU,KAAK;AACzC,QAAI,KAAK,MAAO,SAAQ,oBAAoB,EAAE,YAAY,KAAK,MAAM;AAErE,UAAM,MAAM,MAAM,IAAI,YAAY,GAAG,IAAI,OAAO;AAChD,QAAI,QAAQ,SAAS;AACnB,kBAAY,KAAK,GAAG;AAAA,IACtB,OAAO;AACL,cAAQ,IAAI,kBAAkB,GAAG,IAAI,KAAK,IAAI,EAAE,GAAG;AAAA,IACrD;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,MAAM,EACd,YAAY,qCAAqC,EACjD,SAAS,aAAa,oBAAoB,EAC1C,OAAO,cAAc,+BAA+B,IAAI,EACxD,OAAO,iBAAiB,uCAAuC,EAC/D,OAAO,OAAO,aAAqB,SAAS;AAC3C,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,WAAW,MAAM,IAAI,YAAY,GAAG,IAAI,SAAS,KAAK,CAAC,GAAG,KAAK,MAAM;AAE3E,QAAI,QAAQ,SAAS;AACnB,kBAAY,UAAU,GAAG;AACzB;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,GAAM,GAAG,IAAI,gBAAW,SAAS,MAAM,WAAW;AAC9D,YAAQ,IAAI,SAAI,OAAO,EAAE,CAAC;AAE1B,eAAW,OAAO,SAAS,QAAQ,GAAG;AACpC,YAAM,OAAO,IAAI,KAAK,IAAI,SAAS,EAAE,eAAe;AACpD,YAAM,MAAM,IAAI,OAAO,MAAM,WAAW;AACxC,YAAM,SAAS,IAAI,mBAAmB,cAAc;AACpD,YAAM,SAAS,IAAI,SAAS,eAAQ;AACpC,cAAQ,IAAI,KAAK,IAAI,OAAO,QAAQ,GAAG,GAAG,WAAM,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE;AACxE,UAAI,IAAI,QAAS,SAAQ,IAAI,OAAO,IAAI,OAAO,EAAE;AACjD,UAAI,IAAI,UAAU,IAAI,OAAO,SAAS,GAAG;AACvC,mBAAW,KAAK,IAAI,QAAQ;AAC1B,cAAI,EAAE,MAAO,SAAQ,IAAI,eAAe,EAAE,KAAK,EAAE;AACjD,cAAI,EAAE,YAAa,SAAQ,IAAI,OAAO,EAAE,YAAY,MAAM,GAAG,GAAG,CAAC,EAAE;AAAA,QACrE;AAAA,MACF;AACA,cAAQ,IAAI;AAAA,IACd;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,MAAM,EACd,YAAY,gCAAgC,EAC5C,SAAS,aAAa,oBAAoB,EAC1C,SAAS,gBAAgB,oBAAoB,EAC7C,SAAS,UAAU,qBAAqB,EACxC,OAAO,OAAO,aAAqB,WAAmB,SAAiB;AACtE,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,MAAM,MAAM,IAAI,YAAY,GAAG,IAAI,WAAW,EAAE,SAAS,KAAK,CAAC;AACrE,QAAI,QAAQ,SAAS;AACnB,kBAAY,KAAK,GAAG;AAAA,IACtB,OAAO;AACL,cAAQ,IAAI,kBAAkB,SAAS,QAAQ,GAAG,IAAI,EAAE;AAAA,IAC1D;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,kBAAkB,EAC9B,SAAS,aAAa,oBAAoB,EAC1C,SAAS,gBAAgB,sBAAsB,EAC/C,OAAO,aAAa,6BAA6B,EACjD,OAAO,OAAO,aAAqB,WAAmB,SAAS;AAC9D,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,QAAI,CAAC,KAAK,SAAS;AACjB,cAAQ,MAAM,4BAA4B,SAAS,QAAQ,GAAG,IAAI,6BAA6B;AAC/F,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,IAAI,cAAc,GAAG,IAAI,SAAS;AACxC,YAAQ,IAAI,mBAAmB,SAAS,UAAU,GAAG,IAAI,EAAE;AAAA,EAC7D,CAAC;AAEH,UACG,QAAQ,OAAO,EACf,YAAY,6BAA6B,EACzC,SAAS,aAAa,oBAAoB,EAC1C,SAAS,gBAAgB,YAAY,EACrC,SAAS,WAAW,oDAA6C,EACjE,OAAO,OAAO,aAAqB,WAAmB,UAAkB;AACvE,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,IAAI,YAAY,GAAG,IAAI,WAAW,KAAK;AAC7C,YAAQ,IAAI,WAAW,KAAK,eAAe,SAAS,QAAQ,GAAG,IAAI,EAAE;AAAA,EACvE,CAAC;AAEH,UACG,QAAQ,SAAS,EACjB,YAAY,oCAAoC,EAChD,SAAS,aAAa,oBAAoB,EAC1C,SAAS,gBAAgB,YAAY,EACrC,SAAS,WAAW,iBAAiB,EACrC,OAAO,OAAO,aAAqB,WAAmB,UAAkB;AACvE,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,IAAI,eAAe,GAAG,IAAI,WAAW,KAAK;AAChD,YAAQ,IAAI,WAAW,KAAK,0BAA0B,SAAS,EAAE;AAAA,EACnE,CAAC;AAEH,UACG,QAAQ,KAAK,EACb,YAAY,eAAe,EAC3B,SAAS,aAAa,oBAAoB,EAC1C,SAAS,gBAAgB,mBAAmB,EAC5C,OAAO,OAAO,aAAqB,cAAsB;AACxD,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,IAAI,WAAW,GAAG,IAAI,SAAS;AACrC,YAAQ,IAAI,kBAAkB,SAAS,QAAQ,GAAG,IAAI,EAAE;AAAA,EAC1D,CAAC;AAEH,UACG,QAAQ,OAAO,EACf,YAAY,iBAAiB,EAC7B,SAAS,aAAa,oBAAoB,EAC1C,SAAS,gBAAgB,qBAAqB,EAC9C,OAAO,OAAO,aAAqB,cAAsB;AACxD,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,IAAI,aAAa,GAAG,IAAI,SAAS;AACvC,YAAQ,IAAI,oBAAoB,SAAS,QAAQ,GAAG,IAAI,EAAE;AAAA,EAC5D,CAAC;AAEH,UACG,QAAQ,MAAM,EACd,YAAY,mCAAmC,EAC/C,SAAS,aAAa,oBAAoB,EAC1C,OAAO,OAAO,gBAAwB;AACrC,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,OAAO,MAAM,IAAI,kBAAkB,GAAG,EAAE;AAE9C,QAAI,QAAQ,SAAS;AACnB,kBAAY,MAAM,GAAG;AACrB;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,GAAG;AACrB,cAAQ,IAAI;AAAA,GAAM,GAAG,IAAI,sBAAsB;AAC/C;AAAA,IACF;AAEA,YAAQ,IAAI;AAAA,GAAM,GAAG,IAAI,WAAM,KAAK,MAAM,SAAS;AACnD,YAAQ,IAAI,SAAI,OAAO,EAAE,CAAC;AAC1B,eAAW,OAAO,MAAM;AACtB,YAAM,OAAO,IAAI,KAAK,IAAI,SAAS,EAAE,eAAe;AACpD,cAAQ,IAAI,KAAK,IAAI,OAAO,QAAQ,WAAM,IAAI,EAAE;AAChD,UAAI,IAAI,QAAS,SAAQ,IAAI,OAAO,IAAI,OAAO,EAAE;AACjD,cAAQ,IAAI,WAAW,IAAI,EAAE,EAAE;AAC/B,cAAQ,IAAI;AAAA,IACd;AAAA,EACF,CAAC;AAEH,UACG,QAAQ,QAAQ,EAChB,YAAY,gDAAgD,EAC5D,SAAS,aAAa,oBAAoB,EAC1C,SAAS,UAAU,aAAa,EAChC,OAAO,kBAAkB,oCAAoC,EAC7D,OAAO,OAAO,aAAqB,MAAc,SAAS;AACzD,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AACnD,UAAM,KAAK,MAAM,eAAe,KAAK,SAAS,WAAW;AAEzD,UAAM,SAAS,MAAM,IAAI,aAAa,GAAG,IAAI,MAAM,KAAK,OAAO;AAC/D,QAAI,QAAQ,SAAS;AACnB,kBAAY,QAAQ,GAAG;AAAA,IACzB,OAAO;AACL,cAAQ,IAAI,mBAAmB,IAAI,SAAS,GAAG,IAAI,KAAK,OAAO,EAAE,GAAG;AAAA,IACtE;AAAA,EACF,CAAC;AACL;;;AC5RO,SAAS,cAAcC,UAAwB;AACpD,QAAM,QAAQA,SACX,QAAQ,OAAO,EACf,YAAY,uBAAuB;AAEtC,QACG,QAAQ,KAAK,EACb,YAAY,+BAA+B,EAC3C,OAAO,cAAc,8BAA8B,IAAI,EACvD,OAAO,mBAAmB,0DAA0D,EACpF,OAAO,eAAe,yCAAyC,EAC/D,OAAO,OAAO,SAAS;AACtB,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,UAAM,MAAM,IAAI,WAAW,aAAa,CAAC;AACzC,UAAM,UAAU,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAEnD,UAAM,YAAwE;AAAA,MAC5E,OAAO,SAAS,KAAK,CAAC;AAAA,IACxB;AAEA,QAAI,KAAK,MAAM;AACb,YAAM,aAAa,aAAa,KAAK,IAAI;AACzC,UAAI,eAAe,QAAW;AAC5B,gBAAQ,MAAM,wBAAwB,KAAK,IAAI,EAAE;AACjD,gBAAQ,MAAM,cAAc,OAAO,KAAK,YAAY,EAAE,KAAK,IAAI,CAAC,EAAE;AAClE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,gBAAU,cAAc;AAAA,IAC1B;AAEA,QAAI,KAAK,MAAM;AACb,gBAAU,UAAU,KAAK;AAAA,IAC3B;AAEA,UAAM,MAAM,MAAM,IAAI,YAAY,SAAS,SAAS;AAEpD,QAAI,QAAQ,SAAS;AACnB,kBAAY,IAAI,mBAAmB,GAAG;AACtC;AAAA,IACF;AAEA,UAAM,UAAU,IAAI,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAEhE,YAAQ,IAAI,aAAa;AACzB,YAAQ,IAAI,wDAAW;AAEvB,QAAI,IAAI,kBAAkB,WAAW,GAAG;AACtC,cAAQ,IAAI,gBAAgB;AAC5B;AAAA,IACF;AAEA,eAAW,SAAS,IAAI,mBAAmB;AACzC,YAAM,MAAM,MAAM,UAAU,QAAQ,IAAI,MAAM,OAAO,KAAK,MAAM,UAAU;AAC1E,YAAM,SAAS,kBAAkB,MAAM,WAAW,KAAK,WAAW,MAAM,WAAW;AACnF,YAAM,SAAS,MAAM,aAAa;AAClC,YAAM,SAAS,MAAM,SAAS,YAAO,MAAM,MAAM,MAAM;AAEvD,cAAQ,IAAI,KAAK,GAAG,WAAM,MAAM,IAAI,MAAM,GAAG,MAAM,EAAE;AAErD,UAAI,MAAM,WAAW,MAAM,QAAQ,SAAS,GAAG;AAC7C,mBAAW,UAAU,MAAM,QAAQ,MAAM,GAAG,CAAC,GAAG;AAC9C,gBAAM,MAAM,OAAO,cAAc,SAAY,OAAO,OAAO,SAAS,EAAE,MAAM,GAAG,EAAE,IAAI;AACrF,gBAAM,KAAK,OAAO,cAAc,SAAY,OAAO,OAAO,SAAS,EAAE,MAAM,GAAG,EAAE,IAAI;AACpF,cAAI,OAAO,IAAI;AACb,oBAAQ,IAAI,OAAO,OAAO,GAAG,KAAK,GAAG,WAAM,EAAE,EAAE;AAAA,UACjD,WAAW,IAAI;AACb,oBAAQ,IAAI,OAAO,OAAO,GAAG,KAAK,EAAE,EAAE;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,YAAQ,IAAI;AAAA,EACd,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,uCAAuC,EACnD,OAAO,MAAM;AACZ,UAAM,MAAM,cAAcA,SAAQ,KAAK,EAAE,MAAM;AAC/C,QAAI,QAAQ,SAAS;AACnB,YAAM,QAAQ,OAAO,QAAQ,YAAY,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,EAAE,MAAM,MAAM,EAAE;AACnF,kBAAY,OAAO,GAAG;AAAA,IACxB,OAAO;AACL,cAAQ,IAAI,0BAA0B;AACtC,cAAQ,IAAI,gIAAuB;AACnC,iBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACxD,gBAAQ,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC,IAAI,KAAK,EAAE;AAAA,MAC7C;AAAA,IACF;AAAA,EACF,CAAC;AACL;;;AZrFA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,QAAQ,EACb,YAAY,6CAAwC,EACpD,QAAQ,OAAO,EACf,OAAO,kBAAkB,sFAAsF,MAAM,EACrH,OAAO,iBAAiB,oBAAoB;AAE/C,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,aAAa,OAAO;AACpB,eAAe,OAAO;AACtB,mBAAmB,OAAO;AAC1B,gBAAgB,OAAO;AACvB,cAAc,OAAO;AAErB,QAAQ,MAAM;","names":["readFileSync","program","program","program","program","program","program","program","program"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/utils/config.ts","../src/utils/api.ts","../src/commands/init.ts","../src/utils/output.ts","../src/commands/server.ts","../src/utils/resolve.ts","../src/commands/channel.ts","../src/commands/role.ts","../src/commands/member.ts","../src/commands/permission.ts","../src/commands/message.ts","../src/commands/audit.ts","../src/commands/invite.ts"],"sourcesContent":["import { Command } from 'commander';\r\nimport { registerInit } from './commands/init.js';\r\nimport { registerServer } from './commands/server.js';\r\nimport { registerChannel } from './commands/channel.js';\r\nimport { registerRole } from './commands/role.js';\r\nimport { registerMember } from './commands/member.js';\r\nimport { registerPermission } from './commands/permission.js';\r\nimport { registerMessage } from './commands/message.js';\r\nimport { registerAudit } from './commands/audit.js';\r\nimport { registerInvite } from './commands/invite.js';\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name('discli')\r\n .description('discli — Discord server management CLI')\r\n .version('0.5.0')\r\n .option('--format <fmt>', 'Output format: json, yaml, table, auto (auto = yaml when piped, table in terminal)', 'auto')\r\n .option('--server <id>', 'Server ID override');\r\n\r\nregisterInit(program);\r\nregisterServer(program);\r\nregisterChannel(program);\r\nregisterRole(program);\r\nregisterMember(program);\r\nregisterPermission(program);\r\nregisterMessage(program);\r\nregisterAudit(program);\r\nregisterInvite(program);\r\n\r\nprogram.parse();\r\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\r\nimport { homedir } from 'os';\r\nimport { join } from 'path';\r\n\r\nconst CONFIG_DIR = join(homedir(), '.discli');\r\nconst CONFIG_FILE = join(CONFIG_DIR, 'config.json');\r\nconst ENV_FILE = join(CONFIG_DIR, '.env');\r\n\r\ninterface DctlConfig {\r\n default_server_id?: string;\r\n default_server_name?: string;\r\n}\r\n\r\nfunction ensureConfigDir(): void {\r\n if (!existsSync(CONFIG_DIR)) {\r\n mkdirSync(CONFIG_DIR, { recursive: true });\r\n }\r\n}\r\n\r\nexport function loadConfig(): DctlConfig {\r\n if (!existsSync(CONFIG_FILE)) return {};\r\n try {\r\n return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));\r\n } catch {\r\n return {};\r\n }\r\n}\r\n\r\nexport function saveConfig(data: DctlConfig): void {\r\n ensureConfigDir();\r\n writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2) + '\\n');\r\n}\r\n\r\nexport function loadToken(): string | null {\r\n if (!existsSync(ENV_FILE)) return null;\r\n const content = readFileSync(ENV_FILE, 'utf-8');\r\n const match = content.match(/^BOT_TOKEN=(.+)$/m);\r\n return match ? match[1].trim() : null;\r\n}\r\n\r\nexport function saveToken(token: string): void {\r\n ensureConfigDir();\r\n writeFileSync(ENV_FILE, `BOT_TOKEN=${token}\\n`);\r\n}\r\n\r\nexport function getDefaultServer(): string | null {\r\n return loadConfig().default_server_id ?? null;\r\n}\r\n\r\nexport function getDefaultServerName(): string | null {\r\n return loadConfig().default_server_name ?? null;\r\n}\r\n\r\nexport function setDefaultServer(id: string, name: string): void {\r\n const cfg = loadConfig();\r\n cfg.default_server_id = id;\r\n cfg.default_server_name = name;\r\n saveConfig(cfg);\r\n}\r\n\r\nexport function requireToken(): string {\r\n const token = loadToken();\r\n if (!token) {\r\n console.error('Error: Not configured. Run \"discli init\" first.');\r\n process.exit(1);\r\n }\r\n return token;\r\n}\r\n\r\nexport function requireServer(override?: string): string {\r\n const server = override || getDefaultServer();\r\n if (!server) {\r\n console.error('Error: No server selected. Run \"discli server select\" or use --server <id>.');\r\n process.exit(1);\r\n }\r\n return server;\r\n}\r\n","const BASE = 'https://discord.com/api/v10';\r\n\r\nexport const PERMISSION: Record<string, bigint> = {\r\n view_channel: 1n << 10n,\r\n send_messages: 1n << 11n,\r\n send_messages_in_threads: 1n << 38n,\r\n create_public_threads: 1n << 35n,\r\n create_private_threads: 1n << 36n,\r\n embed_links: 1n << 14n,\r\n attach_files: 1n << 15n,\r\n add_reactions: 1n << 6n,\r\n use_external_emojis: 1n << 18n,\r\n read_message_history: 1n << 16n,\r\n mention_everyone: 1n << 17n,\r\n manage_messages: 1n << 13n,\r\n manage_channels: 1n << 4n,\r\n manage_roles: 1n << 28n,\r\n connect: 1n << 20n,\r\n speak: 1n << 21n,\r\n mute_members: 1n << 22n,\r\n deafen_members: 1n << 23n,\r\n move_members: 1n << 24n,\r\n use_voice_activity: 1n << 25n,\r\n};\r\n\r\nexport const CHANNEL_TYPE: Record<string, number> = {\r\n text: 0,\r\n voice: 2,\r\n category: 4,\r\n announcement: 5,\r\n stage: 13,\r\n forum: 15,\r\n};\r\n\r\nexport const CHANNEL_TYPE_NAME: Record<number, string> = Object.fromEntries(\r\n Object.entries(CHANNEL_TYPE).map(([k, v]) => [v, k])\r\n);\r\n\r\nexport class DiscordAPI {\r\n private token: string;\r\n\r\n constructor(token: string) {\r\n this.token = token;\r\n }\r\n\r\n private async request(method: string, path: string, body?: unknown): Promise<unknown> {\r\n const headers: Record<string, string> = {\r\n Authorization: `Bot ${this.token}`,\r\n };\r\n if (body) {\r\n headers['Content-Type'] = 'application/json';\r\n }\r\n\r\n const res = await fetch(`${BASE}${path}`, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (res.status === 429) {\r\n const data = (await res.json()) as { retry_after?: number };\r\n console.error(`Rate limited. Retry after ${data.retry_after ?? '?'}s.`);\r\n process.exit(1);\r\n }\r\n if (res.status === 403) {\r\n console.error('403 Forbidden — missing permissions.');\r\n process.exit(4);\r\n }\r\n if (res.status === 404) {\r\n console.error('404 Not found.');\r\n process.exit(3);\r\n }\r\n if (res.status >= 400) {\r\n const text = await res.text();\r\n console.error(`Discord API error ${res.status}: ${text.slice(0, 200)}`);\r\n process.exit(1);\r\n }\r\n\r\n if (res.status === 204) return null;\r\n return res.json();\r\n }\r\n\r\n // ── Guilds ──\r\n\r\n async listGuilds(): Promise<Guild[]> {\r\n return (await this.request('GET', '/users/@me/guilds')) as Guild[];\r\n }\r\n\r\n async getGuild(guildId: string): Promise<GuildFull> {\r\n return (await this.request('GET', `/guilds/${guildId}?with_counts=true`)) as GuildFull;\r\n }\r\n\r\n async modifyGuild(guildId: string, data: Record<string, unknown>): Promise<GuildFull> {\r\n return (await this.request('PATCH', `/guilds/${guildId}`, data)) as GuildFull;\r\n }\r\n\r\n // ── Invites ──\r\n\r\n async getGuildInvites(guildId: string): Promise<Invite[]> {\r\n return (await this.request('GET', `/guilds/${guildId}/invites`)) as Invite[];\r\n }\r\n\r\n async createChannelInvite(\r\n channelId: string,\r\n opts?: { max_age?: number; max_uses?: number; temporary?: boolean; unique?: boolean }\r\n ): Promise<Invite> {\r\n return (await this.request('POST', `/channels/${channelId}/invites`, opts ?? {})) as Invite;\r\n }\r\n\r\n async deleteInvite(code: string): Promise<void> {\r\n await this.request('DELETE', `/invites/${code}`);\r\n }\r\n\r\n // ── Audit Log ──\r\n\r\n async getAuditLog(\r\n guildId: string,\r\n opts?: { user_id?: string; action_type?: number; limit?: number; before?: string }\r\n ): Promise<AuditLog> {\r\n const params = new URLSearchParams();\r\n if (opts?.user_id) params.set('user_id', opts.user_id);\r\n if (opts?.action_type !== undefined) params.set('action_type', String(opts.action_type));\r\n if (opts?.limit) params.set('limit', String(Math.min(opts.limit, 100)));\r\n if (opts?.before) params.set('before', opts.before);\r\n const qs = params.toString();\r\n return (await this.request('GET', `/guilds/${guildId}/audit-logs${qs ? '?' + qs : ''}`)) as AuditLog;\r\n }\r\n\r\n // ── Channels ──\r\n\r\n async listChannels(guildId: string): Promise<Channel[]> {\r\n return (await this.request('GET', `/guilds/${guildId}/channels`)) as Channel[];\r\n }\r\n\r\n async createChannel(\r\n guildId: string,\r\n opts: { name: string; type?: number; parent_id?: string; topic?: string }\r\n ): Promise<Channel> {\r\n return (await this.request('POST', `/guilds/${guildId}/channels`, opts)) as Channel;\r\n }\r\n\r\n // ── Messages ──\r\n\r\n async sendMessage(channelId: string, data: MessagePayload): Promise<Message> {\r\n return (await this.request('POST', `/channels/${channelId}/messages`, data)) as Message;\r\n }\r\n\r\n async getMessages(channelId: string, limit = 50, before?: string): Promise<Message[]> {\r\n let path = `/channels/${channelId}/messages?limit=${Math.min(limit, 100)}`;\r\n if (before) path += `&before=${before}`;\r\n return (await this.request('GET', path)) as Message[];\r\n }\r\n\r\n async getMessage(channelId: string, messageId: string): Promise<Message> {\r\n return (await this.request('GET', `/channels/${channelId}/messages/${messageId}`)) as Message;\r\n }\r\n\r\n async editMessage(channelId: string, messageId: string, data: MessagePayload): Promise<Message> {\r\n return (await this.request('PATCH', `/channels/${channelId}/messages/${messageId}`, data)) as Message;\r\n }\r\n\r\n // ── Reactions ──\r\n\r\n async addReaction(channelId: string, messageId: string, emoji: string): Promise<void> {\r\n const encoded = encodeURIComponent(emoji);\r\n await this.request('PUT', `/channels/${channelId}/messages/${messageId}/reactions/${encoded}/@me`);\r\n }\r\n\r\n async removeReaction(channelId: string, messageId: string, emoji: string): Promise<void> {\r\n const encoded = encodeURIComponent(emoji);\r\n await this.request('DELETE', `/channels/${channelId}/messages/${messageId}/reactions/${encoded}/@me`);\r\n }\r\n\r\n // ── Threads ──\r\n\r\n async createThread(channelId: string, name: string, messageId?: string): Promise<Channel> {\r\n if (messageId) {\r\n return (await this.request('POST', `/channels/${channelId}/messages/${messageId}/threads`, {\r\n name, auto_archive_duration: 1440\r\n })) as Channel;\r\n }\r\n return (await this.request('POST', `/channels/${channelId}/threads`, {\r\n name, type: 11, auto_archive_duration: 1440\r\n })) as Channel;\r\n }\r\n\r\n async deleteMessage(channelId: string, messageId: string): Promise<void> {\r\n await this.request('DELETE', `/channels/${channelId}/messages/${messageId}`);\r\n }\r\n\r\n async pinMessage(channelId: string, messageId: string): Promise<void> {\r\n await this.request('PUT', `/channels/${channelId}/pins/${messageId}`);\r\n }\r\n\r\n async unpinMessage(channelId: string, messageId: string): Promise<void> {\r\n await this.request('DELETE', `/channels/${channelId}/pins/${messageId}`);\r\n }\r\n\r\n async getPinnedMessages(channelId: string): Promise<Message[]> {\r\n return (await this.request('GET', `/channels/${channelId}/pins`)) as Message[];\r\n }\r\n\r\n async deleteChannel(channelId: string): Promise<void> {\r\n await this.request('DELETE', `/channels/${channelId}`);\r\n }\r\n\r\n async modifyChannel(channelId: string, data: Record<string, unknown>): Promise<Channel> {\r\n return (await this.request('PATCH', `/channels/${channelId}`, data)) as Channel;\r\n }\r\n\r\n async getChannel(channelId: string): Promise<Channel> {\r\n return (await this.request('GET', `/channels/${channelId}`)) as Channel;\r\n }\r\n\r\n async editChannelPermission(\r\n channelId: string,\r\n overwriteId: string,\r\n data: { allow: string; deny: string; type: number }\r\n ): Promise<void> {\r\n await this.request('PUT', `/channels/${channelId}/permissions/${overwriteId}`, data);\r\n }\r\n\r\n async deleteChannelPermission(channelId: string, overwriteId: string): Promise<void> {\r\n await this.request('DELETE', `/channels/${channelId}/permissions/${overwriteId}`);\r\n }\r\n\r\n // ── Roles ──\r\n\r\n async listRoles(guildId: string): Promise<Role[]> {\r\n return (await this.request('GET', `/guilds/${guildId}/roles`)) as Role[];\r\n }\r\n\r\n async createRole(guildId: string, data: Record<string, unknown>): Promise<Role> {\r\n return (await this.request('POST', `/guilds/${guildId}/roles`, data)) as Role;\r\n }\r\n\r\n async modifyRole(guildId: string, roleId: string, data: Record<string, unknown>): Promise<Role> {\r\n return (await this.request('PATCH', `/guilds/${guildId}/roles/${roleId}`, data)) as Role;\r\n }\r\n\r\n async reorderRoles(guildId: string, positions: { id: string; position: number }[]): Promise<Role[]> {\r\n return (await this.request('PATCH', `/guilds/${guildId}/roles`, positions)) as Role[];\r\n }\r\n\r\n async deleteRole(guildId: string, roleId: string): Promise<void> {\r\n await this.request('DELETE', `/guilds/${guildId}/roles/${roleId}`);\r\n }\r\n\r\n async addRoleToMember(guildId: string, userId: string, roleId: string): Promise<void> {\r\n await this.request('PUT', `/guilds/${guildId}/members/${userId}/roles/${roleId}`);\r\n }\r\n\r\n async removeRoleFromMember(guildId: string, userId: string, roleId: string): Promise<void> {\r\n await this.request('DELETE', `/guilds/${guildId}/members/${userId}/roles/${roleId}`);\r\n }\r\n\r\n // ── Members ──\r\n\r\n async listMembers(guildId: string, limit = 100): Promise<Member[]> {\r\n return (await this.request('GET', `/guilds/${guildId}/members?limit=${Math.min(limit, 1000)}`)) as Member[];\r\n }\r\n\r\n async getMember(guildId: string, userId: string): Promise<Member> {\r\n return (await this.request('GET', `/guilds/${guildId}/members/${userId}`)) as Member;\r\n }\r\n\r\n async kickMember(guildId: string, userId: string): Promise<void> {\r\n await this.request('DELETE', `/guilds/${guildId}/members/${userId}`);\r\n }\r\n\r\n async banMember(guildId: string, userId: string): Promise<void> {\r\n await this.request('PUT', `/guilds/${guildId}/bans/${userId}`);\r\n }\r\n\r\n async modifyMember(guildId: string, userId: string, data: Record<string, unknown>): Promise<Member> {\r\n return (await this.request('PATCH', `/guilds/${guildId}/members/${userId}`, data)) as Member;\r\n }\r\n}\r\n\r\n// ── Types ──\r\n\r\nexport interface Guild {\r\n id: string;\r\n name: string;\r\n icon: string | null;\r\n owner: boolean;\r\n permissions: string;\r\n}\r\n\r\nexport interface GuildFull extends Guild {\r\n approximate_member_count?: number;\r\n approximate_presence_count?: number;\r\n description: string | null;\r\n premium_tier: number;\r\n premium_subscription_count: number;\r\n}\r\n\r\nexport interface PermissionOverwrite {\r\n id: string;\r\n type: number; // 0 = role, 1 = member\r\n allow: string;\r\n deny: string;\r\n}\r\n\r\nexport interface Channel {\r\n id: string;\r\n name: string;\r\n type: number;\r\n position: number;\r\n parent_id: string | null;\r\n topic?: string | null;\r\n permission_overwrites?: PermissionOverwrite[];\r\n}\r\n\r\nexport interface Role {\r\n id: string;\r\n name: string;\r\n color: number;\r\n position: number;\r\n permissions: string;\r\n managed: boolean;\r\n mentionable: boolean;\r\n}\r\n\r\nexport interface Member {\r\n user?: {\r\n id: string;\r\n username: string;\r\n global_name: string | null;\r\n };\r\n nick: string | null;\r\n roles: string[];\r\n joined_at: string;\r\n}\r\n\r\nexport interface Embed {\r\n title?: string;\r\n description?: string;\r\n url?: string;\r\n color?: number;\r\n timestamp?: string;\r\n footer?: { text: string; icon_url?: string };\r\n image?: { url: string };\r\n thumbnail?: { url: string };\r\n author?: { name: string; url?: string; icon_url?: string };\r\n fields?: { name: string; value: string; inline?: boolean }[];\r\n}\r\n\r\nexport interface MessagePayload {\r\n content?: string;\r\n embeds?: Embed[];\r\n message_reference?: { message_id: string };\r\n}\r\n\r\nexport interface Message {\r\n id: string;\r\n channel_id: string;\r\n content: string;\r\n timestamp: string;\r\n edited_timestamp: string | null;\r\n pinned: boolean;\r\n author: {\r\n id: string;\r\n username: string;\r\n bot?: boolean;\r\n };\r\n embeds?: Embed[];\r\n}\r\n\r\nexport interface Invite {\r\n code: string;\r\n channel: { id: string; name: string } | null;\r\n inviter?: { id: string; username: string };\r\n uses: number;\r\n max_uses: number;\r\n max_age: number;\r\n temporary: boolean;\r\n created_at: string;\r\n}\r\n\r\nexport interface AuditLogEntry {\r\n id: string;\r\n user_id: string | null;\r\n target_id: string | null;\r\n action_type: number;\r\n reason?: string;\r\n changes?: { key: string; old_value?: unknown; new_value?: unknown }[];\r\n}\r\n\r\nexport interface AuditLog {\r\n audit_log_entries: AuditLogEntry[];\r\n users: { id: string; username: string }[];\r\n}\r\n\r\nexport const AUDIT_ACTION: Record<string, number> = {\r\n guild_update: 1,\r\n channel_create: 10,\r\n channel_update: 11,\r\n channel_delete: 12,\r\n member_kick: 20,\r\n member_prune: 21,\r\n member_ban_add: 22,\r\n member_ban_remove: 23,\r\n member_update: 24,\r\n member_role_update: 25,\r\n bot_add: 28,\r\n role_create: 30,\r\n role_update: 31,\r\n role_delete: 32,\r\n invite_create: 40,\r\n invite_delete: 42,\r\n webhook_create: 50,\r\n webhook_update: 51,\r\n webhook_delete: 52,\r\n emoji_create: 60,\r\n emoji_delete: 62,\r\n message_delete: 72,\r\n message_bulk_delete: 73,\r\n message_pin: 74,\r\n message_unpin: 75,\r\n thread_create: 110,\r\n thread_update: 111,\r\n thread_delete: 112,\r\n automod_rule_create: 140,\r\n automod_rule_update: 141,\r\n automod_rule_delete: 142,\r\n automod_block_message: 143,\r\n integration_create: 80,\r\n integration_update: 81,\r\n integration_delete: 82,\r\n};\r\n\r\nexport const AUDIT_ACTION_NAME: Record<number, string> = Object.fromEntries(\r\n Object.entries(AUDIT_ACTION).map(([k, v]) => [v, k])\r\n);\r\n","import { Command } from 'commander';\r\nimport { saveToken, setDefaultServer, loadToken } from '../utils/config.js';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { readFileSync } from 'fs';\r\n\r\nexport function registerInit(program: Command): void {\r\n program\r\n .command('init')\r\n .description('Set up discli with your bot token and default server')\r\n .option('--token <token>', 'Bot token (or reads from stdin)')\r\n .action(async (opts) => {\r\n let token = opts.token;\r\n\r\n if (!token) {\r\n // Try reading from stdin if piped\r\n if (!process.stdin.isTTY) {\r\n token = readFileSync(0, 'utf-8').trim();\r\n }\r\n }\r\n\r\n if (!token) {\r\n // Check if already configured\r\n const existing = loadToken();\r\n if (existing) {\r\n console.log('Already configured. Use --token to update.');\r\n token = existing;\r\n } else {\r\n console.error('Usage: discli init --token <your-bot-token>');\r\n console.error(' Get your token from https://discord.com/developers/applications');\r\n process.exit(2);\r\n }\r\n }\r\n\r\n // Validate token\r\n const api = new DiscordAPI(token);\r\n let guilds;\r\n try {\r\n guilds = await api.listGuilds();\r\n } catch {\r\n console.error('Invalid token or cannot connect to Discord.');\r\n process.exit(1);\r\n }\r\n\r\n saveToken(token);\r\n console.log(`Token saved to ~/.discli/.env`);\r\n\r\n if (guilds.length === 0) {\r\n console.log('Bot is not in any servers yet. Add it to a server first.');\r\n return;\r\n }\r\n\r\n console.log('\\nServers:');\r\n guilds.forEach((g, i) => {\r\n console.log(` ${i + 1}. ${g.name} (${g.id})`);\r\n });\r\n\r\n // Auto-select if only one server\r\n if (guilds.length === 1) {\r\n setDefaultServer(guilds[0].id, guilds[0].name);\r\n console.log(`\\nDefault server: ${guilds[0].name}`);\r\n } else {\r\n console.log(`\\nSet default with: discli server select <id>`);\r\n }\r\n\r\n console.log('\\nReady! Try: discli server info');\r\n });\r\n}\r\n","import { stringify as yamlStringify } from 'yaml';\r\n\r\nexport function resolveFormat(explicit: string): string {\r\n if (explicit !== 'auto') return explicit;\r\n return process.stdout.isTTY ? 'table' : 'yaml';\r\n}\r\n\r\nexport function printResult(data: unknown, format: string): void {\r\n const fmt = resolveFormat(format);\r\n\r\n if (fmt === 'json') {\r\n console.log(JSON.stringify(data, null, 2));\r\n return;\r\n }\r\n\r\n if (fmt === 'yaml') {\r\n console.log(yamlStringify(data, { indent: 2 }).trimEnd());\r\n return;\r\n }\r\n\r\n if (Array.isArray(data)) {\r\n if (data.length === 0) {\r\n console.log(' (none)');\r\n return;\r\n }\r\n if (typeof data[0] === 'object') {\r\n printTable(data as Record<string, unknown>[]);\r\n } else {\r\n data.forEach((item) => console.log(` ${item}`));\r\n }\r\n return;\r\n }\r\n\r\n if (typeof data === 'object' && data !== null) {\r\n const obj = data as Record<string, unknown>;\r\n const maxKey = Math.max(...Object.keys(obj).map((k) => k.length));\r\n for (const [k, v] of Object.entries(obj)) {\r\n console.log(` ${k.padEnd(maxKey)} ${v}`);\r\n }\r\n return;\r\n }\r\n\r\n console.log(String(data));\r\n}\r\n\r\nexport function printTable(rows: Record<string, unknown>[], columns?: string[]): void {\r\n if (rows.length === 0) {\r\n console.log(' (none)');\r\n return;\r\n }\r\n\r\n const cols = columns ?? Object.keys(rows[0]);\r\n const widths: Record<string, number> = {};\r\n for (const col of cols) {\r\n widths[col] = col.length;\r\n }\r\n for (const row of rows) {\r\n for (const col of cols) {\r\n widths[col] = Math.max(widths[col], String(row[col] ?? '').length);\r\n }\r\n }\r\n\r\n const header = cols.map((c) => c.toUpperCase().padEnd(widths[c])).join(' ');\r\n const sep = cols.map((c) => '─'.repeat(widths[c])).join(' ');\r\n console.log(` ${header}`);\r\n console.log(` ${sep}`);\r\n\r\n for (const row of rows) {\r\n const line = cols.map((c) => String(row[c] ?? '').padEnd(widths[c])).join(' ');\r\n console.log(` ${line}`);\r\n }\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { requireToken, requireServer, setDefaultServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\n\r\nconst VERIFICATION_LEVELS: Record<string, number> = {\r\n none: 0,\r\n low: 1,\r\n medium: 2,\r\n high: 3,\r\n very_high: 4,\r\n};\r\n\r\nconst NOTIFICATION_LEVELS: Record<string, number> = {\r\n all_messages: 0,\r\n only_mentions: 1,\r\n};\r\n\r\nconst CONTENT_FILTER_LEVELS: Record<string, number> = {\r\n disabled: 0,\r\n members_without_roles: 1,\r\n all_members: 2,\r\n};\r\n\r\nexport function registerServer(program: Command): void {\r\n const server = program\r\n .command('server')\r\n .description('Manage and inspect servers');\r\n\r\n server\r\n .command('list')\r\n .description('List all servers the bot is in')\r\n .action(async () => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guilds = await api.listGuilds();\r\n\r\n if (fmt !== 'table') {\r\n printResult(guilds, fmt);\r\n return;\r\n }\r\n\r\n const rows = guilds.map((g) => ({\r\n id: g.id,\r\n name: g.name,\r\n owner: g.owner ? 'yes' : 'no',\r\n }));\r\n console.log('\\nServers');\r\n console.log('───────');\r\n printResult(rows, fmt);\r\n });\r\n\r\n server\r\n .command('select')\r\n .description('Set the default server')\r\n .argument('<id>', 'Server ID')\r\n .action(async (id: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guild = await api.getGuild(id);\r\n setDefaultServer(guild.id, guild.name);\r\n console.log(`Default server set to: ${guild.name} (${guild.id})`);\r\n });\r\n\r\n server\r\n .command('info')\r\n .description('Show server details')\r\n .action(async () => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const guild = await api.getGuild(guildId);\r\n\r\n if (fmt !== 'table') {\r\n printResult(guild, fmt);\r\n return;\r\n }\r\n\r\n const info = {\r\n name: guild.name,\r\n id: guild.id,\r\n description: guild.description || '(none)',\r\n members: guild.approximate_member_count ?? '?',\r\n online: guild.approximate_presence_count ?? '?',\r\n boosts: guild.premium_subscription_count,\r\n boost_tier: guild.premium_tier,\r\n };\r\n\r\n console.log(`\\n${guild.name}`);\r\n console.log('─'.repeat(guild.name.length));\r\n printResult(info, fmt);\r\n });\r\n\r\n server\r\n .command('set')\r\n .description('Modify server settings')\r\n .option('--name <name>', 'Server name')\r\n .option('--description <text>', 'Server description')\r\n .option('--verification <level>', 'Verification level: none, low, medium, high, very_high')\r\n .option('--notifications <level>', 'Default notifications: all_messages, only_mentions')\r\n .option('--content-filter <level>', 'Content filter: disabled, members_without_roles, all_members')\r\n .option('--afk-timeout <seconds>', 'AFK timeout: 60, 300, 900, 1800, 3600', parseInt)\r\n .option('--system-channel <id>', 'System message channel ID')\r\n .option('--rules-channel <id>', 'Rules channel ID')\r\n .option('--boost-bar', 'Enable boost progress bar')\r\n .option('--no-boost-bar', 'Disable boost progress bar')\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n\r\n const data: Record<string, unknown> = {};\r\n\r\n if (opts.name) data.name = opts.name;\r\n if (opts.description) data.description = opts.description;\r\n if (opts.verification) {\r\n const level = VERIFICATION_LEVELS[opts.verification];\r\n if (level === undefined) {\r\n console.error(`Invalid verification level. Use: ${Object.keys(VERIFICATION_LEVELS).join(', ')}`);\r\n process.exit(2);\r\n }\r\n data.verification_level = level;\r\n }\r\n if (opts.notifications) {\r\n const level = NOTIFICATION_LEVELS[opts.notifications];\r\n if (level === undefined) {\r\n console.error(`Invalid notification level. Use: ${Object.keys(NOTIFICATION_LEVELS).join(', ')}`);\r\n process.exit(2);\r\n }\r\n data.default_message_notifications = level;\r\n }\r\n if (opts.contentFilter) {\r\n const level = CONTENT_FILTER_LEVELS[opts.contentFilter];\r\n if (level === undefined) {\r\n console.error(`Invalid content filter level. Use: ${Object.keys(CONTENT_FILTER_LEVELS).join(', ')}`);\r\n process.exit(2);\r\n }\r\n data.explicit_content_filter = level;\r\n }\r\n if (opts.afkTimeout) data.afk_timeout = opts.afkTimeout;\r\n if (opts.systemChannel) data.system_channel_id = opts.systemChannel;\r\n if (opts.rulesChannel) data.rules_channel_id = opts.rulesChannel;\r\n if (opts.boostBar === true) data.premium_progress_bar_enabled = true;\r\n if (opts.boostBar === false) data.premium_progress_bar_enabled = false;\r\n\r\n if (Object.keys(data).length === 0) {\r\n console.error('Specify at least one setting to change.');\r\n console.error('Options: --name, --description, --verification, --notifications, --content-filter, --afk-timeout, --system-channel, --rules-channel, --boost-bar');\r\n process.exit(2);\r\n }\r\n\r\n const guild = await api.modifyGuild(guildId, data);\r\n if (fmt !== 'table') {\r\n printResult(guild, fmt);\r\n } else {\r\n console.log(`Updated server settings for ${guild.name}`);\r\n for (const [key, value] of Object.entries(data)) {\r\n console.log(` ${key}: ${value}`);\r\n }\r\n }\r\n });\r\n}\r\n","import { DiscordAPI, CHANNEL_TYPE_NAME } from './api.js';\r\nimport type { Channel, Role, Member } from './api.js';\r\n\r\nexport async function resolveChannel(\r\n api: DiscordAPI,\r\n guildId: string,\r\n name: string\r\n): Promise<Channel> {\r\n const channels = await api.listChannels(guildId);\r\n\r\n // Try ID match\r\n const byId = channels.find((c) => c.id === name);\r\n if (byId) return byId;\r\n\r\n // Strip # prefix\r\n const clean = name.replace(/^#/, '');\r\n\r\n const matches = channels.filter((c) => c.name.toLowerCase() === clean.toLowerCase());\r\n if (matches.length === 1) return matches[0];\r\n if (matches.length > 1) {\r\n const names = matches.map((m) => `#${m.name} (${CHANNEL_TYPE_NAME[m.type] ?? '?'})`).join(', ');\r\n console.error(`Ambiguous channel \"${clean}\". Matches: ${names}`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`Channel \"${name}\" not found.`);\r\n process.exit(3);\r\n}\r\n\r\nexport async function resolveCategory(\r\n api: DiscordAPI,\r\n guildId: string,\r\n name: string\r\n): Promise<Channel> {\r\n const channels = await api.listChannels(guildId);\r\n\r\n const byId = channels.find((c) => c.id === name && c.type === 4);\r\n if (byId) return byId;\r\n\r\n const matches = channels.filter(\r\n (c) => c.type === 4 && c.name.toLowerCase() === name.toLowerCase()\r\n );\r\n if (matches.length === 1) return matches[0];\r\n if (matches.length > 1) {\r\n console.error(`Ambiguous category \"${name}\".`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`Category \"${name}\" not found.`);\r\n process.exit(3);\r\n}\r\n\r\nexport async function resolveRole(\r\n api: DiscordAPI,\r\n guildId: string,\r\n name: string\r\n): Promise<Role> {\r\n const roles = await api.listRoles(guildId);\r\n\r\n const byId = roles.find((r) => r.id === name);\r\n if (byId) return byId;\r\n\r\n const clean = name.replace(/^@/, '');\r\n const matches = roles.filter((r) => r.name.toLowerCase() === clean.toLowerCase());\r\n if (matches.length === 1) return matches[0];\r\n if (matches.length > 1) {\r\n const names = matches.map((m) => `@${m.name}`).join(', ');\r\n console.error(`Ambiguous role \"${clean}\". Matches: ${names}`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`Role \"${name}\" not found.`);\r\n process.exit(3);\r\n}\r\n\r\nexport async function resolveMember(\r\n api: DiscordAPI,\r\n guildId: string,\r\n name: string\r\n): Promise<Member> {\r\n // Try as ID\r\n if (/^\\d+$/.test(name)) {\r\n try {\r\n return await api.getMember(guildId, name);\r\n } catch {\r\n // fall through to search\r\n }\r\n }\r\n\r\n const members = await api.listMembers(guildId, 1000);\r\n const clean = name.replace(/^@/, '').toLowerCase();\r\n\r\n const matches = members.filter((m) => {\r\n const username = m.user?.username?.toLowerCase() ?? '';\r\n const globalName = m.user?.global_name?.toLowerCase() ?? '';\r\n const nick = m.nick?.toLowerCase() ?? '';\r\n return username === clean || globalName === clean || nick === clean;\r\n });\r\n\r\n if (matches.length === 1) return matches[0];\r\n if (matches.length > 1) {\r\n const names = matches.map((m) => m.user?.username).join(', ');\r\n console.error(`Ambiguous user \"${name}\". Matches: ${names}`);\r\n process.exit(1);\r\n }\r\n\r\n console.error(`Member \"${name}\" not found.`);\r\n process.exit(3);\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI, CHANNEL_TYPE, CHANNEL_TYPE_NAME } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveChannel, resolveCategory } from '../utils/resolve.js';\r\n\r\nexport function registerChannel(program: Command): void {\r\n const channel = program\r\n .command('channel')\r\n .description('Manage server channels');\r\n\r\n channel\r\n .command('list')\r\n .description('List all channels grouped by category')\r\n .option('-n <count>', 'Limit number of channels shown', parseInt)\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n let channels = await api.listChannels(guildId);\r\n if (opts.n) channels = channels.slice(0, opts.n);\r\n\r\n if (fmt !== 'table') {\r\n printResult(channels, fmt);\r\n return;\r\n }\r\n\r\n // Group by category\r\n const categories = channels\r\n .filter((c) => c.type === 4)\r\n .sort((a, b) => a.position - b.position);\r\n const uncategorized = channels.filter(\r\n (c) => c.type !== 4 && !c.parent_id\r\n );\r\n\r\n if (uncategorized.length > 0) {\r\n console.log('\\n (no category)');\r\n for (const ch of uncategorized.sort((a, b) => a.position - b.position)) {\r\n const type = CHANNEL_TYPE_NAME[ch.type] ?? '?';\r\n console.log(` ${type === 'text' ? '#' : '🔊'} ${ch.name}`);\r\n }\r\n }\r\n\r\n for (const cat of categories) {\r\n console.log(`\\n ${cat.name.toUpperCase()}`);\r\n const children = channels\r\n .filter((c) => c.parent_id === cat.id && c.type !== 4)\r\n .sort((a, b) => a.position - b.position);\r\n for (const ch of children) {\r\n const type = CHANNEL_TYPE_NAME[ch.type] ?? '?';\r\n const prefix = type === 'voice' || type === 'stage' ? '🔊' : '#';\r\n const topic = ch.topic ? ` — ${ch.topic}` : '';\r\n console.log(` ${prefix} ${ch.name}${topic}`);\r\n }\r\n }\r\n console.log();\r\n });\r\n\r\n channel\r\n .command('create')\r\n .description('Create a new channel')\r\n .argument('<name>', 'Channel name')\r\n .option('--type <type>', 'Channel type: text, voice, category, announcement, stage, forum', 'text')\r\n .option('--category <name>', 'Parent category name or ID')\r\n .option('--topic <topic>', 'Channel topic')\r\n .option('--dry-run', 'Show what would be created without creating it')\r\n .action(async (name: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n\r\n const channelType = CHANNEL_TYPE[opts.type];\r\n if (channelType === undefined) {\r\n console.error(`Unknown channel type: ${opts.type}. Use: ${Object.keys(CHANNEL_TYPE).join(', ')}`);\r\n process.exit(2);\r\n }\r\n\r\n let parentId: string | undefined;\r\n if (opts.category) {\r\n const cat = await resolveCategory(api, guildId, opts.category);\r\n parentId = cat.id;\r\n }\r\n\r\n if (opts.dryRun) {\r\n const result = { action: 'create_channel', name, type: opts.type, category: opts.category ?? null, topic: opts.topic ?? null };\r\n printResult(result, fmt);\r\n return;\r\n }\r\n\r\n const ch = await api.createChannel(guildId, {\r\n name,\r\n type: channelType,\r\n parent_id: parentId,\r\n topic: opts.topic,\r\n });\r\n\r\n if (fmt !== 'table') {\r\n printResult(ch, fmt);\r\n } else {\r\n console.log(`Created #${ch.name} (${CHANNEL_TYPE_NAME[ch.type] ?? '?'}) — ${ch.id}`);\r\n }\r\n });\r\n\r\n channel\r\n .command('delete')\r\n .description('Delete a channel')\r\n .argument('<name>', 'Channel name or ID')\r\n .option('--confirm', 'Required to actually delete')\r\n .action(async (name: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, name);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will delete #${ch.name} (${ch.id}). Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.deleteChannel(ch.id);\r\n console.log(`Deleted #${ch.name}`);\r\n });\r\n\r\n channel\r\n .command('rename')\r\n .description('Rename a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<new-name>', 'New channel name')\r\n .option('--dry-run', 'Show what would change')\r\n .action(async (channelName: string, newName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n if (opts.dryRun) {\r\n printResult({ action: 'rename_channel', from: ch.name, to: newName, id: ch.id }, fmt);\r\n return;\r\n }\r\n\r\n await api.modifyChannel(ch.id, { name: newName });\r\n console.log(`Renamed #${ch.name} → #${newName}`);\r\n });\r\n\r\n channel\r\n .command('topic')\r\n .description('Set a channel topic')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<topic>', 'New topic text')\r\n .action(async (channelName: string, topic: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const updated = await api.modifyChannel(ch.id, { topic });\r\n if (fmt !== 'table') {\r\n printResult(updated, fmt);\r\n } else {\r\n console.log(`Set topic for #${ch.name}: ${topic}`);\r\n }\r\n });\r\n\r\n channel\r\n .command('move')\r\n .description('Move a channel to a category')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('--category <name>', 'Target category name or ID')\r\n .option('--position <n>', 'Position within category', parseInt)\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const update: Record<string, unknown> = {};\r\n if (opts.category) {\r\n const cat = await resolveCategory(api, guildId, opts.category);\r\n update.parent_id = cat.id;\r\n }\r\n if (opts.position !== undefined) {\r\n update.position = opts.position;\r\n }\r\n\r\n if (Object.keys(update).length === 0) {\r\n console.error('Specify --category and/or --position.');\r\n process.exit(2);\r\n }\r\n\r\n const updated = await api.modifyChannel(ch.id, update);\r\n if (fmt !== 'table') {\r\n printResult(updated, fmt);\r\n } else {\r\n console.log(`Moved #${ch.name}${opts.category ? ` → ${opts.category}` : ''}${opts.position !== undefined ? ` (position ${opts.position})` : ''}`);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveRole, resolveMember } from '../utils/resolve.js';\r\n\r\nexport function registerRole(program: Command): void {\r\n const role = program\r\n .command('role')\r\n .description('Manage server roles');\r\n\r\n role\r\n .command('list')\r\n .description('List all roles')\r\n .option('-n <count>', 'Limit number of roles shown', parseInt)\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const roles = await api.listRoles(guildId);\r\n\r\n const sorted = roles.sort((a, b) => b.position - a.position).slice(0, opts.n ?? roles.length);\r\n\r\n if (fmt !== 'table') {\r\n printResult(sorted, fmt);\r\n return;\r\n }\r\n\r\n const rows = sorted.map((r) => ({\r\n name: r.name,\r\n id: r.id,\r\n color: r.color ? `#${r.color.toString(16).padStart(6, '0')}` : '(none)',\r\n managed: r.managed ? 'bot' : '',\r\n position: r.position,\r\n }));\r\n\r\n console.log('\\nRoles');\r\n console.log('─────');\r\n printResult(rows, fmt);\r\n });\r\n\r\n role\r\n .command('create')\r\n .description('Create a new role')\r\n .argument('<name>', 'Role name')\r\n .option('--color <hex>', 'Color hex (e.g. #ff5733)')\r\n .option('--mentionable', 'Allow anyone to mention this role')\r\n .option('--dry-run', 'Show what would be created')\r\n .action(async (name: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n\r\n const data: Record<string, unknown> = { name };\r\n if (opts.color) {\r\n data.color = parseInt(opts.color.replace('#', ''), 16);\r\n }\r\n if (opts.mentionable) {\r\n data.mentionable = true;\r\n }\r\n\r\n if (opts.dryRun) {\r\n printResult({ action: 'create_role', ...data }, fmt);\r\n return;\r\n }\r\n\r\n const r = await api.createRole(guildId, data);\r\n if (fmt !== 'table') {\r\n printResult(r, fmt);\r\n } else {\r\n console.log(`Created role @${r.name} — ${r.id}`);\r\n }\r\n });\r\n\r\n role\r\n .command('delete')\r\n .description('Delete a role')\r\n .argument('<name>', 'Role name or ID')\r\n .option('--confirm', 'Required to actually delete')\r\n .action(async (name: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const r = await resolveRole(api, guildId, name);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will delete @${r.name} (${r.id}). Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.deleteRole(guildId, r.id);\r\n console.log(`Deleted role @${r.name}`);\r\n });\r\n\r\n role\r\n .command('assign')\r\n .description('Assign a role to a member')\r\n .argument('<role>', 'Role name or ID')\r\n .argument('<user>', 'Username or ID')\r\n .action(async (roleName: string, userName: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const r = await resolveRole(api, guildId, roleName);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n await api.addRoleToMember(guildId, m.user!.id, r.id);\r\n console.log(`Assigned @${r.name} to ${m.user!.username}`);\r\n });\r\n\r\n role\r\n .command('remove')\r\n .description('Remove a role from a member')\r\n .argument('<role>', 'Role name or ID')\r\n .argument('<user>', 'Username or ID')\r\n .action(async (roleName: string, userName: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const r = await resolveRole(api, guildId, roleName);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n await api.removeRoleFromMember(guildId, m.user!.id, r.id);\r\n console.log(`Removed @${r.name} from ${m.user!.username}`);\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveMember } from '../utils/resolve.js';\r\n\r\nexport function registerMember(program: Command): void {\r\n const member = program\r\n .command('member')\r\n .description('Manage server members');\r\n\r\n member\r\n .command('list')\r\n .description('List server members')\r\n .option('-n, --limit <n>', 'Max members to show', '100')\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const members = await api.listMembers(guildId, parseInt(opts.limit));\r\n\r\n if (fmt !== 'table') {\r\n printResult(members, fmt);\r\n return;\r\n }\r\n\r\n const rows = members.map((m) => ({\r\n username: m.user?.username ?? '?',\r\n display: m.user?.global_name ?? m.nick ?? '',\r\n nick: m.nick ?? '',\r\n roles: m.roles.length,\r\n joined: m.joined_at?.slice(0, 10) ?? '?',\r\n }));\r\n\r\n console.log(`\\nMembers (${members.length})`);\r\n console.log('──────────');\r\n printResult(rows, fmt);\r\n });\r\n\r\n member\r\n .command('info')\r\n .description('Show member details')\r\n .argument('<user>', 'Username or ID')\r\n .action(async (userName: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n if (fmt !== 'table') {\r\n printResult(m, fmt);\r\n return;\r\n }\r\n\r\n const roles = await api.listRoles(guildId);\r\n const memberRoles = m.roles\r\n .map((rid) => roles.find((r) => r.id === rid)?.name ?? rid)\r\n .join(', ');\r\n\r\n const info = {\r\n username: m.user?.username ?? '?',\r\n display_name: m.user?.global_name ?? '(none)',\r\n nickname: m.nick ?? '(none)',\r\n id: m.user?.id ?? '?',\r\n roles: memberRoles || '(none)',\r\n joined: m.joined_at?.slice(0, 10) ?? '?',\r\n };\r\n\r\n console.log(`\\n${m.user?.username ?? 'Member'}`);\r\n console.log('─'.repeat((m.user?.username ?? 'Member').length));\r\n printResult(info, fmt);\r\n });\r\n\r\n member\r\n .command('kick')\r\n .description('Kick a member from the server')\r\n .argument('<user>', 'Username or ID')\r\n .option('--reason <text>', 'Reason for kick')\r\n .option('--confirm', 'Required to actually kick')\r\n .action(async (userName: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will kick ${m.user!.username} (${m.user!.id}). Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.kickMember(guildId, m.user!.id);\r\n console.log(`Kicked ${m.user!.username}${opts.reason ? ` — ${opts.reason}` : ''}`);\r\n });\r\n\r\n member\r\n .command('ban')\r\n .description('Ban a member from the server')\r\n .argument('<user>', 'Username or ID')\r\n .option('--reason <text>', 'Reason for ban')\r\n .option('--confirm', 'Required to actually ban')\r\n .action(async (userName: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will BAN ${m.user!.username} (${m.user!.id}). Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.banMember(guildId, m.user!.id);\r\n console.log(`Banned ${m.user!.username}${opts.reason ? ` — ${opts.reason}` : ''}`);\r\n });\r\n\r\n member\r\n .command('nick')\r\n .description('Change a member\\'s nickname')\r\n .argument('<user>', 'Username or ID')\r\n .argument('<nickname>', 'New nickname')\r\n .action(async (userName: string, nickname: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const m = await resolveMember(api, guildId, userName);\r\n\r\n await api.modifyMember(guildId, m.user!.id, { nick: nickname });\r\n if (fmt !== 'table') {\r\n printResult({ action: 'nick', user: m.user!.username, nick: nickname }, fmt);\r\n } else {\r\n console.log(`Set nickname for ${m.user!.username} → ${nickname}`);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI, PERMISSION } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveChannel, resolveRole } from '../utils/resolve.js';\r\n\r\nfunction parsePermissions(perms: string): bigint {\r\n let bits = 0n;\r\n for (const p of perms.split(',')) {\r\n const name = p.trim().toLowerCase();\r\n const val = PERMISSION[name];\r\n if (val === undefined) {\r\n console.error(`Unknown permission: ${name}`);\r\n console.error(`Available: ${Object.keys(PERMISSION).join(', ')}`);\r\n process.exit(2);\r\n }\r\n bits |= val;\r\n }\r\n return bits;\r\n}\r\n\r\nfunction describePermissions(bitfield: string): string[] {\r\n const bits = BigInt(bitfield);\r\n if (bits === 0n) return [];\r\n return Object.entries(PERMISSION)\r\n .filter(([, val]) => (bits & val) === val)\r\n .map(([name]) => name);\r\n}\r\n\r\nexport function registerPermission(program: Command): void {\r\n const perm = program\r\n .command('permission')\r\n .alias('perm')\r\n .description('Manage channel permissions');\r\n\r\n perm\r\n .command('view')\r\n .description('View permission overwrites for a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .action(async (channelName: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const full = await api.getChannel(ch.id);\r\n const overwrites = full.permission_overwrites ?? [];\r\n const roles = await api.listRoles(guildId);\r\n\r\n if (fmt !== 'table') {\r\n printResult(overwrites, fmt);\r\n return;\r\n }\r\n\r\n if (overwrites.length === 0) {\r\n console.log(`\\n#${ch.name}: no permission overwrites (inherits from category/server)`);\r\n return;\r\n }\r\n\r\n console.log(`\\n#${ch.name} — Permission Overwrites`);\r\n console.log('─'.repeat(40));\r\n\r\n for (const ow of overwrites) {\r\n const target = ow.type === 0\r\n ? roles.find((r) => r.id === ow.id)?.name ?? ow.id\r\n : `member:${ow.id}`;\r\n const allowed = describePermissions(ow.allow);\r\n const denied = describePermissions(ow.deny);\r\n\r\n console.log(`\\n @${target} (${ow.type === 0 ? 'role' : 'member'})`);\r\n if (allowed.length > 0) console.log(` ✅ allow: ${allowed.join(', ')}`);\r\n if (denied.length > 0) console.log(` ❌ deny: ${denied.join(', ')}`);\r\n if (allowed.length === 0 && denied.length === 0) console.log(` (neutral)`);\r\n }\r\n console.log();\r\n });\r\n\r\n perm\r\n .command('set')\r\n .description('Set permission overwrite for a role on a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<role>', 'Role name or ID')\r\n .option('--allow <perms>', 'Comma-separated permissions to allow')\r\n .option('--deny <perms>', 'Comma-separated permissions to deny')\r\n .option('--dry-run', 'Show what would change')\r\n .action(async (channelName: string, roleName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n const role = await resolveRole(api, guildId, roleName);\r\n\r\n if (!opts.allow && !opts.deny) {\r\n console.error('Specify --allow and/or --deny with comma-separated permissions.');\r\n console.error(`Available: ${Object.keys(PERMISSION).join(', ')}`);\r\n process.exit(2);\r\n }\r\n\r\n const allow = opts.allow ? parsePermissions(opts.allow) : 0n;\r\n const deny = opts.deny ? parsePermissions(opts.deny) : 0n;\r\n\r\n if (opts.dryRun) {\r\n printResult({\r\n action: 'set_permission',\r\n channel: ch.name,\r\n role: role.name,\r\n allow: opts.allow ?? '(none)',\r\n deny: opts.deny ?? '(none)',\r\n }, fmt);\r\n return;\r\n }\r\n\r\n await api.editChannelPermission(ch.id, role.id, {\r\n allow: allow.toString(),\r\n deny: deny.toString(),\r\n type: 0, // role\r\n });\r\n\r\n if (fmt !== 'table') {\r\n printResult({ channel: ch.name, role: role.name, allow: allow.toString(), deny: deny.toString() }, fmt);\r\n } else {\r\n console.log(`Set permissions on #${ch.name} for @${role.name}`);\r\n if (opts.allow) console.log(` ✅ allow: ${opts.allow}`);\r\n if (opts.deny) console.log(` ❌ deny: ${opts.deny}`);\r\n }\r\n });\r\n\r\n perm\r\n .command('lock')\r\n .description('Make a channel read-only for @everyone')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('--dry-run', 'Show what would change')\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n // @everyone role ID = guild ID\r\n const deny = PERMISSION.send_messages\r\n | PERMISSION.send_messages_in_threads\r\n | PERMISSION.create_public_threads;\r\n\r\n if (opts.dryRun) {\r\n printResult({ action: 'lock', channel: ch.name, deny_for: '@everyone' }, fmt);\r\n return;\r\n }\r\n\r\n await api.editChannelPermission(ch.id, guildId, {\r\n allow: '0',\r\n deny: deny.toString(),\r\n type: 0,\r\n });\r\n\r\n console.log(`Locked #${ch.name} — read-only for @everyone`);\r\n });\r\n\r\n perm\r\n .command('unlock')\r\n .description('Remove read-only restriction for @everyone')\r\n .argument('<channel>', 'Channel name or ID')\r\n .action(async (channelName: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.deleteChannelPermission(ch.id, guildId);\r\n console.log(`Unlocked #${ch.name} — @everyone can send messages`);\r\n });\r\n\r\n perm\r\n .command('list')\r\n .description('List all available permission names')\r\n .action(() => {\r\n const fmt = resolveFormat(program.opts().format);\r\n if (fmt !== 'table') {\r\n const perms = Object.entries(PERMISSION).map(([name, val]) => ({ name, bit: val.toString() }));\r\n printResult(perms, fmt);\r\n } else {\r\n console.log('\\nAvailable Permissions');\r\n console.log('────────────────────');\r\n for (const name of Object.keys(PERMISSION)) {\r\n console.log(` ${name}`);\r\n }\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport type { Embed, MessagePayload } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveChannel } from '../utils/resolve.js';\r\n\r\nfunction parseColor(color: string): number {\r\n return parseInt(color.replace('#', ''), 16);\r\n}\r\n\r\nexport function registerMessage(program: Command): void {\r\n const message = program\r\n .command('message')\r\n .alias('msg')\r\n .description('Send, read, and manage messages');\r\n\r\n message\r\n .command('send')\r\n .description('Send a message to a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<text>', 'Message content (supports Discord markdown)')\r\n .option('--reply <id>', 'Reply to a message ID')\r\n .action(async (channelName: string, text: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const payload: MessagePayload = { content: text };\r\n if (opts.reply) {\r\n payload.message_reference = { message_id: opts.reply };\r\n }\r\n\r\n const msg = await api.sendMessage(ch.id, payload);\r\n if (fmt !== 'table') {\r\n printResult(msg, fmt);\r\n } else {\r\n console.log(`Sent message to #${ch.name} (${msg.id})`);\r\n }\r\n });\r\n\r\n message\r\n .command('embed')\r\n .description('Send an embed (rich card) to a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('--title <text>', 'Embed title')\r\n .option('--description <text>', 'Embed description (supports markdown)')\r\n .option('--color <hex>', 'Embed color (e.g. #5865F2)')\r\n .option('--url <url>', 'Title link URL')\r\n .option('--image <url>', 'Large image URL')\r\n .option('--thumbnail <url>', 'Small thumbnail URL')\r\n .option('--footer <text>', 'Footer text')\r\n .option('--author <name>', 'Author name')\r\n .option('--field <value...>', 'Add field: \"Name|Value\" or \"Name|Value|inline\"')\r\n .option('--content <text>', 'Text content above the embed')\r\n .option('--reply <id>', 'Reply to a message ID')\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const embed: Embed = {};\r\n if (opts.title) embed.title = opts.title;\r\n if (opts.description) embed.description = opts.description;\r\n if (opts.color) embed.color = parseColor(opts.color);\r\n if (opts.url) embed.url = opts.url;\r\n if (opts.image) embed.image = { url: opts.image };\r\n if (opts.thumbnail) embed.thumbnail = { url: opts.thumbnail };\r\n if (opts.footer) embed.footer = { text: opts.footer };\r\n if (opts.author) embed.author = { name: opts.author };\r\n if (opts.field) {\r\n embed.fields = (opts.field as string[]).map((f: string) => {\r\n const parts = f.split('|');\r\n return {\r\n name: parts[0],\r\n value: parts[1] || '',\r\n inline: parts[2] === 'inline',\r\n };\r\n });\r\n }\r\n\r\n if (!embed.title && !embed.description) {\r\n console.error('Provide at least --title or --description for the embed.');\r\n process.exit(2);\r\n }\r\n\r\n const payload: MessagePayload = { embeds: [embed] };\r\n if (opts.content) payload.content = opts.content;\r\n if (opts.reply) payload.message_reference = { message_id: opts.reply };\r\n\r\n const msg = await api.sendMessage(ch.id, payload);\r\n if (fmt !== 'table') {\r\n printResult(msg, fmt);\r\n } else {\r\n console.log(`Sent embed to #${ch.name} (${msg.id})`);\r\n }\r\n });\r\n\r\n message\r\n .command('read')\r\n .description('Read recent messages from a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('-n <count>', 'Number of messages to fetch', '10')\r\n .option('--before <id>', 'Fetch messages before this message ID')\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const messages = await api.getMessages(ch.id, parseInt(opts.n), opts.before);\r\n\r\n if (fmt !== 'table') {\r\n printResult(messages, fmt);\r\n return;\r\n }\r\n\r\n console.log(`\\n#${ch.name} — last ${messages.length} messages`);\r\n console.log('─'.repeat(40));\r\n\r\n for (const msg of messages.reverse()) {\r\n const time = new Date(msg.timestamp).toLocaleString();\r\n const bot = msg.author.bot ? ' [BOT]' : '';\r\n const edited = msg.edited_timestamp ? ' (edited)' : '';\r\n const pinned = msg.pinned ? ' 📌' : '';\r\n console.log(` ${msg.author.username}${bot} — ${time}${edited}${pinned}`);\r\n if (msg.content) console.log(` ${msg.content}`);\r\n if (msg.embeds && msg.embeds.length > 0) {\r\n for (const e of msg.embeds) {\r\n if (e.title) console.log(` [Embed] ${e.title}`);\r\n if (e.description) console.log(` ${e.description.slice(0, 100)}`);\r\n }\r\n }\r\n console.log();\r\n }\r\n });\r\n\r\n message\r\n .command('edit')\r\n .description('Edit a message sent by the bot')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID to edit')\r\n .argument('<text>', 'New message content')\r\n .action(async (channelName: string, messageId: string, text: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const msg = await api.editMessage(ch.id, messageId, { content: text });\r\n if (fmt !== 'table') {\r\n printResult(msg, fmt);\r\n } else {\r\n console.log(`Edited message ${messageId} in #${ch.name}`);\r\n }\r\n });\r\n\r\n message\r\n .command('delete')\r\n .description('Delete a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID to delete')\r\n .option('--confirm', 'Required to actually delete')\r\n .action(async (channelName: string, messageId: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will delete message ${messageId} in #${ch.name}. Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.deleteMessage(ch.id, messageId);\r\n console.log(`Deleted message ${messageId} from #${ch.name}`);\r\n });\r\n\r\n message\r\n .command('react')\r\n .description('Add a reaction to a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID')\r\n .argument('<emoji>', 'Emoji to react with (e.g. 👍 or :thumbsup:)')\r\n .action(async (channelName: string, messageId: string, emoji: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.addReaction(ch.id, messageId, emoji);\r\n console.log(`Reacted ${emoji} on message ${messageId} in #${ch.name}`);\r\n });\r\n\r\n message\r\n .command('unreact')\r\n .description('Remove bot reaction from a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID')\r\n .argument('<emoji>', 'Emoji to remove')\r\n .action(async (channelName: string, messageId: string, emoji: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.removeReaction(ch.id, messageId, emoji);\r\n console.log(`Removed ${emoji} reaction from message ${messageId}`);\r\n });\r\n\r\n message\r\n .command('pin')\r\n .description('Pin a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID to pin')\r\n .action(async (channelName: string, messageId: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.pinMessage(ch.id, messageId);\r\n console.log(`Pinned message ${messageId} in #${ch.name}`);\r\n });\r\n\r\n message\r\n .command('unpin')\r\n .description('Unpin a message')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<message-id>', 'Message ID to unpin')\r\n .action(async (channelName: string, messageId: string) => {\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n await api.unpinMessage(ch.id, messageId);\r\n console.log(`Unpinned message ${messageId} in #${ch.name}`);\r\n });\r\n\r\n message\r\n .command('pins')\r\n .description('List pinned messages in a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .action(async (channelName: string) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const pins = await api.getPinnedMessages(ch.id);\r\n\r\n if (fmt !== 'table') {\r\n printResult(pins, fmt);\r\n return;\r\n }\r\n\r\n if (pins.length === 0) {\r\n console.log(`\\n#${ch.name}: no pinned messages`);\r\n return;\r\n }\r\n\r\n console.log(`\\n#${ch.name} — ${pins.length} pinned`);\r\n console.log('─'.repeat(30));\r\n for (const msg of pins) {\r\n const time = new Date(msg.timestamp).toLocaleString();\r\n console.log(` ${msg.author.username} — ${time}`);\r\n if (msg.content) console.log(` ${msg.content}`);\r\n console.log(` ID: ${msg.id}`);\r\n console.log();\r\n }\r\n });\r\n\r\n message\r\n .command('thread')\r\n .description('Create a thread from a message or in a channel')\r\n .argument('<channel>', 'Channel name or ID')\r\n .argument('<name>', 'Thread name')\r\n .option('--message <id>', 'Create thread from this message ID')\r\n .action(async (channelName: string, name: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const thread = await api.createThread(ch.id, name, opts.message);\r\n if (fmt !== 'table') {\r\n printResult(thread, fmt);\r\n } else {\r\n console.log(`Created thread \"${name}\" in #${ch.name} (${thread.id})`);\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI, AUDIT_ACTION, AUDIT_ACTION_NAME } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\n\r\nexport function registerAudit(program: Command): void {\r\n const audit = program\r\n .command('audit')\r\n .description('View server audit log');\r\n\r\n audit\r\n .command('log')\r\n .description('View recent audit log entries')\r\n .option('-n <count>', 'Number of entries to fetch', '20')\r\n .option('--type <action>', 'Filter by action type (e.g. member_kick, channel_create)')\r\n .option('--user <id>', 'Filter by user who performed the action')\r\n .action(async (opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n\r\n const queryOpts: { limit?: number; action_type?: number; user_id?: string } = {\r\n limit: parseInt(opts.n),\r\n };\r\n\r\n if (opts.type) {\r\n const actionType = AUDIT_ACTION[opts.type];\r\n if (actionType === undefined) {\r\n console.error(`Unknown action type: ${opts.type}`);\r\n console.error(`Available: ${Object.keys(AUDIT_ACTION).join(', ')}`);\r\n process.exit(2);\r\n }\r\n queryOpts.action_type = actionType;\r\n }\r\n\r\n if (opts.user) {\r\n queryOpts.user_id = opts.user;\r\n }\r\n\r\n const log = await api.getAuditLog(guildId, queryOpts);\r\n\r\n if (fmt !== 'table') {\r\n printResult(log.audit_log_entries, fmt);\r\n return;\r\n }\r\n\r\n const userMap = new Map(log.users.map((u) => [u.id, u.username]));\r\n\r\n console.log('\\nAudit Log');\r\n console.log('─────────');\r\n\r\n if (log.audit_log_entries.length === 0) {\r\n console.log(' (no entries)');\r\n return;\r\n }\r\n\r\n for (const entry of log.audit_log_entries) {\r\n const who = entry.user_id ? userMap.get(entry.user_id) ?? entry.user_id : '(system)';\r\n const action = AUDIT_ACTION_NAME[entry.action_type] ?? `unknown(${entry.action_type})`;\r\n const target = entry.target_id ?? '';\r\n const reason = entry.reason ? ` — \"${entry.reason}\"` : '';\r\n\r\n console.log(` ${who} → ${action} ${target}${reason}`);\r\n\r\n if (entry.changes && entry.changes.length > 0) {\r\n for (const change of entry.changes.slice(0, 3)) {\r\n const old = change.old_value !== undefined ? String(change.old_value).slice(0, 30) : '';\r\n const nw = change.new_value !== undefined ? String(change.new_value).slice(0, 30) : '';\r\n if (old && nw) {\r\n console.log(` ${change.key}: ${old} → ${nw}`);\r\n } else if (nw) {\r\n console.log(` ${change.key}: ${nw}`);\r\n }\r\n }\r\n }\r\n }\r\n console.log();\r\n });\r\n\r\n audit\r\n .command('types')\r\n .description('List available audit log action types')\r\n .action(() => {\r\n const fmt = resolveFormat(program.opts().format);\r\n if (fmt !== 'table') {\r\n const types = Object.entries(AUDIT_ACTION).map(([name, value]) => ({ name, value }));\r\n printResult(types, fmt);\r\n } else {\r\n console.log('\\nAudit Log Action Types');\r\n console.log('─────────────────────');\r\n for (const [name, value] of Object.entries(AUDIT_ACTION)) {\r\n console.log(` ${name.padEnd(25)} ${value}`);\r\n }\r\n }\r\n });\r\n}\r\n","import { Command } from 'commander';\r\nimport { DiscordAPI } from '../utils/api.js';\r\nimport { requireToken, requireServer } from '../utils/config.js';\r\nimport { printResult, resolveFormat } from '../utils/output.js';\r\nimport { resolveChannel } from '../utils/resolve.js';\r\n\r\nexport function registerInvite(program: Command): void {\r\n const invite = program\r\n .command('invite')\r\n .description('Manage server invites');\r\n\r\n invite\r\n .command('list')\r\n .description('List all server invites')\r\n .action(async () => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const invites = await api.getGuildInvites(guildId);\r\n\r\n if (fmt !== 'table') {\r\n printResult(invites, fmt);\r\n return;\r\n }\r\n\r\n if (invites.length === 0) {\r\n console.log('\\n No active invites');\r\n return;\r\n }\r\n\r\n const rows = invites.map((inv) => ({\r\n code: inv.code,\r\n channel: inv.channel?.name ?? '?',\r\n inviter: inv.inviter?.username ?? '?',\r\n uses: `${inv.uses}/${inv.max_uses || '∞'}`,\r\n max_age: inv.max_age === 0 ? 'never' : `${inv.max_age}s`,\r\n temp: inv.temporary ? 'yes' : 'no',\r\n }));\r\n\r\n console.log('\\nInvites');\r\n console.log('───────');\r\n printResult(rows, fmt);\r\n });\r\n\r\n invite\r\n .command('create')\r\n .description('Create an invite link')\r\n .argument('<channel>', 'Channel name or ID')\r\n .option('--max-age <seconds>', 'Expire after seconds (0 = never)', parseInt)\r\n .option('--max-uses <count>', 'Max uses (0 = unlimited)', parseInt)\r\n .option('--temporary', 'Grant temporary membership')\r\n .action(async (channelName: string, opts) => {\r\n const fmt = resolveFormat(program.opts().format);\r\n const api = new DiscordAPI(requireToken());\r\n const guildId = requireServer(program.opts().server);\r\n const ch = await resolveChannel(api, guildId, channelName);\r\n\r\n const inviteOpts: Record<string, unknown> = { unique: true };\r\n if (opts.maxAge !== undefined) inviteOpts.max_age = opts.maxAge;\r\n if (opts.maxUses !== undefined) inviteOpts.max_uses = opts.maxUses;\r\n if (opts.temporary) inviteOpts.temporary = true;\r\n\r\n const inv = await api.createChannelInvite(ch.id, inviteOpts as any);\r\n\r\n if (fmt !== 'table') {\r\n printResult(inv, fmt);\r\n } else {\r\n console.log(`Created invite: https://discord.gg/${inv.code}`);\r\n console.log(` Channel: #${ch.name}`);\r\n console.log(` Max uses: ${inv.max_uses || 'unlimited'}`);\r\n console.log(` Expires: ${inv.max_age === 0 ? 'never' : `${inv.max_age}s`}`);\r\n }\r\n });\r\n\r\n invite\r\n .command('delete')\r\n .description('Delete an invite')\r\n .argument('<code>', 'Invite code')\r\n .option('--confirm', 'Required to actually delete')\r\n .action(async (code: string, opts) => {\r\n const api = new DiscordAPI(requireToken());\r\n\r\n if (!opts.confirm) {\r\n console.error(`This will delete invite ${code}. Add --confirm to proceed.`);\r\n process.exit(2);\r\n }\r\n\r\n await api.deleteInvite(code);\r\n console.log(`Deleted invite ${code}`);\r\n });\r\n}\r\n"],"mappings":"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","names":["readFileSync","program","program","program","program","program","program","program","program","program"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibbybuilds/discli",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "discli — Discord server management CLI. Control your servers from the terminal. Built for humans and AI agents.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,7 +19,11 @@
19
19
  "build": "tsup",
20
20
  "dev": "tsup --watch",
21
21
  "start": "node dist/cli.js",
22
- "typecheck": "tsc --noEmit"
22
+ "typecheck": "tsc --noEmit",
23
+ "test": "node --test test/*.test.js",
24
+ "release:patch": "npm run typecheck && npm run build && npm version patch && npm publish --access=public && git push && git push --tags",
25
+ "release:minor": "npm run typecheck && npm run build && npm version minor && npm publish --access=public && git push && git push --tags",
26
+ "release:major": "npm run typecheck && npm run build && npm version major && npm publish --access=public && git push && git push --tags"
23
27
  },
24
28
  "keywords": [
25
29
  "discord",
package/skills/SKILL.md CHANGED
@@ -27,6 +27,15 @@ discli init --token <token> # First-time setup
27
27
  discli server list # List servers
28
28
  discli server select <id> # Set default server
29
29
  discli server info # Server overview
30
+ discli server set --name "X" # Change server name
31
+ discli server set --description "X" # Set description
32
+ discli server set --verification medium # Verification level
33
+ discli server set --notifications only_mentions # Notification default
34
+
35
+ discli invite list # List all invites
36
+ discli invite create <channel> # Create invite
37
+ discli invite create <ch> --max-age 3600 --max-uses 10 # With limits
38
+ discli invite delete <code> --confirm # Delete invite
30
39
 
31
40
  discli channel list # List channels
32
41
  discli channel create <name> # Create channel (--type, --category, --topic)