@chojs23/concord 2.1.11

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 ADDED
@@ -0,0 +1,644 @@
1
+ # Concord
2
+
3
+ <img width="1613" height="848" alt="concord - a feature-rich TUI client for
4
+ Discord" src="./docs/example.png" />
5
+
6
+ Concord is a feature-rich TUI (terminal user interface) client for Discord, written in Rust with ratatui. Full Discord experience, right in your terminal.
7
+
8
+ ## Table of contents
9
+
10
+ - [Installation](#installation)
11
+ - [Features](#features)
12
+ - [Configuration](#configuration)
13
+ - [Performance](#performance)
14
+ - [FAQ](#faq)
15
+ - [Security](#security)
16
+ - [Contributing](#contributing)
17
+ - [License](#license)
18
+
19
+ ## Installation
20
+
21
+ ### Homebrew
22
+
23
+ ```sh
24
+ brew install chojs23/tap/concord
25
+ ```
26
+
27
+ ### npm
28
+
29
+ ```sh
30
+ npm install -g @chojs23/concord
31
+ ```
32
+
33
+ You can also run Concord without a global install:
34
+
35
+ ```sh
36
+ npx @chojs23/concord
37
+ ```
38
+
39
+ The npm package installs a prebuilt binary from the GitHub Release artifacts.
40
+
41
+ ### Cargo
42
+
43
+ Install native audio dependencies first. On macOS with Homebrew:
44
+
45
+ ```sh
46
+ brew install opus pkg-config
47
+ ```
48
+
49
+ On Fedora:
50
+
51
+ ```sh
52
+ sudo dnf install opus-devel alsa-lib-devel pkgconf-pkg-config
53
+ ```
54
+
55
+ On Debian or Ubuntu:
56
+
57
+ ```sh
58
+ sudo apt install libopus-dev libasound2-dev pkg-config
59
+ ```
60
+
61
+ On macOS with Homebrew:
62
+
63
+ ```sh
64
+ brew install opus pkg-config
65
+ ```
66
+
67
+ ```sh
68
+ cargo install concord
69
+ ```
70
+
71
+ To install without local voice playback and microphone support:
72
+
73
+ ```sh
74
+ cargo install concord --no-default-features
75
+ ```
76
+
77
+ To install the latest unreleased version directly from the Git repository:
78
+
79
+ ```sh
80
+ cargo install --git https://github.com/chojs23/concord
81
+ ```
82
+
83
+ ### Nix
84
+
85
+ Run without installing (requires flakes enabled):
86
+
87
+ ```sh
88
+ nix run github:chojs23/concord
89
+ ```
90
+
91
+ Install into your profile:
92
+
93
+ ```sh
94
+ nix profile install github:chojs23/concord
95
+ ```
96
+
97
+ Or add the flake as an input in your own `flake.nix`:
98
+
99
+ ```nix
100
+ {
101
+ inputs.concord.url = "github:chojs23/concord";
102
+ }
103
+ ```
104
+
105
+ ### GitHub Release installer
106
+
107
+ Install the latest release with the cargo-dist shell installer:
108
+
109
+ ```sh
110
+ curl --proto '=https' --tlsv1.2 -LsSf https://github.com/chojs23/concord/releases/latest/download/concord-installer.sh | sh
111
+ ```
112
+
113
+ On Windows, use the PowerShell installer instead:
114
+
115
+ ```powershell
116
+ powershell -ExecutionPolicy Bypass -c "irm https://github.com/chojs23/concord/releases/latest/download/concord-installer.ps1 | iex"
117
+ ```
118
+
119
+ The installer places `concord` under `$CARGO_HOME/bin`, which is usually
120
+ `~/.cargo/bin` on Unix and `%USERPROFILE%\.cargo\bin` on Windows.
121
+
122
+ ### Build from source
123
+
124
+ You need the Rust stable toolchain, Cargo, and the native dependencies listed in
125
+ the Cargo install section.
126
+
127
+ ```sh
128
+ git clone https://github.com/chojs23/concord.git
129
+ cd concord
130
+ cargo build --release
131
+ ```
132
+
133
+ The release binary is produced at:
134
+
135
+ ```sh
136
+ target/release/concord
137
+ ```
138
+
139
+ To build without local voice playback and microphone support, disable default features:
140
+
141
+ ```sh
142
+ cargo build --release --no-default-features
143
+ ```
144
+
145
+ On WSLg, audio is usually exposed through PulseAudio instead of a real ALSA
146
+ sound card. If playback does not start, check that PulseAudio and ALSA routing
147
+ work before debugging Discord voice itself:
148
+
149
+ ```sh
150
+ pactl info
151
+ paplay /usr/share/sounds/alsa/Front_Center.wav
152
+ aplay -D pulse /usr/share/sounds/alsa/Front_Center.wav
153
+ ```
154
+
155
+ ## Features
156
+
157
+ ### Authentication
158
+
159
+ - **Token** : paste an existing Discord token.
160
+ - **Email / Password** : login with credentials. MFA (TOTP, SMS) is fully supported.
161
+ - **QR Code** : scan the code from the Discord mobile app.
162
+
163
+ Email and QR code logins may trigger a CAPTCHA challenge on Discord's side. We cannot solve that, so I strongly recommend using token authentication.
164
+
165
+ Tokens are saved under Concord's config directory in plain text. See the Security section below for details.
166
+
167
+ ### Guilds & Channels
168
+
169
+ - Browse servers with guild folder grouping
170
+ - Navigate text channels, threads, and forum channels
171
+ - View and filter forum posts (active / archived)
172
+ - Load pinned messages per channel
173
+ - Open channel actions for pinned messages, thread lists, and mark-as-read
174
+ - Join and leave voice channels
175
+ - Highlight active voice speakers in voice channel participant rows
176
+ - Track unread messages and mention counts per channel
177
+ - Mute and unmute channels and servers
178
+ - Leave the selected server after confirmation
179
+
180
+ ### Messaging
181
+
182
+ - Send, edit, and delete messages
183
+ - Upload / Download attachments
184
+ - Search messages with filters with `/`
185
+ - Use @mention autocomplete
186
+ - Use custom emoji from other servers when your account supports it
187
+ - Send custom emoji your account cannot use directly as image links when enabled
188
+ - View full message history
189
+ - Rich content display (embeds, attachments, stickers, and mentions)
190
+ - Detect URLs in message bodies and markdown links, then open them in your default browser
191
+ - Direct message shortcuts for copy, reply, edit, delete, reactions, URL opening,
192
+ and image viewing. More message actions are available from the action menu.
193
+
194
+ #### Markdown Rendering
195
+
196
+ ![Markdown rendering example](./docs/markdown-example.png)
197
+
198
+ Concord renders a practical subset of Discord-style Markdown in message bodies:
199
+
200
+ - Headings: `# H1`, `## H2`, `### H3`
201
+ - Quotes: `> quoted text`
202
+ - Bullets: `- item` and `* item`
203
+ - Inline styles: `**bold**`, `*italic*`, and `` `inline code` ``
204
+ - Fenced code blocks with optional language labels, rendered as compact boxes
205
+ - Raw URLs and markdown link destinations are underlined and can be opened from message actions
206
+
207
+ ### Reactions & Polls
208
+
209
+ - View, add, and remove emoji reactions (Unicode and custom server emoji)
210
+ - Use custom emoji from other servers as reactions when your account supports it
211
+ - Browse who reacted with a specific emoji
212
+ - View and vote on polls
213
+
214
+ ### Media & Images
215
+
216
+ Image rendering is powered by [ratatui-image](https://github.com/benjajaja/ratatui-image). On startup, Concord queries the terminal to detect the best available graphics protocol. Supported protocols:
217
+
218
+ - **Kitty Graphics Protocol** - Kitty, WezTerm, Ghostty, etc.
219
+ - **iTerm2 Inline Images** - iTerm2, WezTerm, mintty, etc.
220
+ - **Sixel** - foot, mlterm, xterm (if compiled with Sixel support), etc.
221
+ - **Halfblocks** (fallback) - works on any terminal, but uses block characters instead of true pixels.
222
+
223
+ If your terminal does not support any graphics protocol, images will be rendered as halfblock approximations. For the best experience, use a terminal that supports the Kitty or iTerm2 protocol.
224
+
225
+ You can toggle image viewing on or off in the configuration file. When image viewing is off, attachments and emojis will be shown as text placeholders.
226
+
227
+ ### Members & Profiles
228
+
229
+ - Member list with grouping
230
+ - Presence indicators (Online, Idle, DND, Offline)
231
+ - View User profile
232
+
233
+ ### Typing Indicators & Read State
234
+
235
+ - Live "user is typing..." indicators
236
+ - Unread message tracking with mention counts
237
+ - Mark server, channel as read
238
+
239
+ ### Notifications
240
+
241
+ - Desktop notifications for Discord messages that pass your Discord
242
+ notification settings
243
+ - Active channel notifications are suppressed so Concord does not notify for
244
+ the conversation you are already viewing
245
+ - Voice join and leave notification sounds while you are connected to voice.
246
+ You can keep the built-in tones or configure custom WAV files.
247
+
248
+ ### Navigation & Keyboard shortcuts
249
+
250
+ > ⚠️ Keymap action names and default bindings may have breaking changes between releases.
251
+
252
+ All default key settings in this section can be customized. See
253
+ [Keymap options](./docs/keymap-options.md) for the config format and supported
254
+ actions.
255
+
256
+ Concord has a four-pane.
257
+ **Guilds (1)**, **Channels (2)**, **Messages (3)**, **Members (4)**
258
+
259
+ With default vim-style navigation:
260
+
261
+ | Key | Action |
262
+ | ----------------------------------------- | ----------------------------------------------- |
263
+ | `1` `2` `3` `4` | Focus pane |
264
+ | `Tab` / `Shift+Tab` | Cycle focus forward / backward |
265
+ | `h` / `l`, `←` / `→` | Move focus left / right |
266
+ | `j` / `k`, `↑` / `↓`, `Ctrl+n` / `Ctrl+p` | Move down / up |
267
+ | `J`, `K` / `H`, `L` | Scroll viewport |
268
+ | `Ctrl+d` / `Ctrl+u` | Half-page scroll |
269
+ | `Alt+h/l/←/→` | Resize focused pane width |
270
+ | `gg` / `G` | Jump or scroll to top / bottom |
271
+ | `Enter` | Open or activate the selected item |
272
+ | `/` | Filter Guilds/Channels, search Messages/Members |
273
+ | `Space` | Open leader shortcut window |
274
+ | `i` | Text insert mode |
275
+ | `Esc` | Close popup, cancel mode, or go back |
276
+ | `q` | Quit Concord |
277
+
278
+ `Ctrl+n` and `Ctrl+p` are fixed row movement keys. The default `j` and `k`
279
+ row movement keys are `SelectNext` and `SelectPrevious` and can be changed in
280
+ `keymap.toml`.
281
+
282
+ #### Leader key
283
+
284
+ Press `Space` to open the leader shortcut window.
285
+
286
+ | Key sequence | Action |
287
+ | ---------------- | --------------------------------- |
288
+ | `Space`, `1` | Toggle the Servers pane |
289
+ | `Space`, `2` | Toggle the Channels pane |
290
+ | `Space`, `4` | Toggle the Members pane |
291
+ | `Space`, `a` | Open actions for the focused pane |
292
+ | `Space`, `p` | Open my profile settings |
293
+ | `Space`, `o` | Choose concord option category |
294
+ | `Space`, `v` | Voice command prefix |
295
+ | `Space`, `Space` | Open the fuzzy channel switcher |
296
+
297
+ #### Action menus
298
+
299
+ Focus a pane, then press `Space`, `a` to open actions for that pane. Action
300
+ shortcuts are shown inside the leader popup and only run when the action is
301
+ enabled. In the Messages pane, the selected message also supports these direct
302
+ shortcuts:
303
+
304
+ Message shortcuts:
305
+
306
+ | Shortcut | Action | Description |
307
+ | -------- | ------------------- | ----------------------------------------------------------- |
308
+ | `y` | Copy | Copy the selected message text and show a short toast |
309
+ | `r` | Add/remove reaction | Open the reaction picker for the selected message |
310
+ | `R` | Reply | Start a reply to the selected message |
311
+ | `d` | Delete | Open a delete confirmation before deleting the message |
312
+ | `e` | Edit | Start editing the selected message when editing is allowed |
313
+ | `o` | Open URL | Open the selected message URL, or choose from multiple URLs |
314
+ | `v` | View attachment | Open the selected message's attachment viewer |
315
+
316
+ Message action menu shortcuts:
317
+
318
+ | Shortcut | Action | Description |
319
+ | -------- | --------------------------- | ----------------------------------------------------------- |
320
+ | `y` | Copy | Copy the selected message text and show a short toast |
321
+ | `r` | Add/remove reaction | Open the reaction picker for the selected message |
322
+ | `R` | Reply | Start a reply to the selected message |
323
+ | `d` | Delete | Open a delete confirmation before deleting the message |
324
+ | `e` | Edit | Start editing the selected message when editing is allowed |
325
+ | `o` | Open URL | Open the selected message URL, or choose from multiple URLs |
326
+ | `v` | View attachment | Open the selected message's attachment viewer |
327
+ | `g` | Go to referenced message | Go to the replied or forwarded message |
328
+ | `p` | show message sender profile | Open the selected message author's profile |
329
+ | `P` | Pin / unpin | Open a pin or unpin confirmation for the selected message |
330
+ | `t` | Open thread | Open the selected message's thread |
331
+ | `u` | Show reacted users | Show users who reacted to the selected message |
332
+ | `c` | Choose poll votes | Choose poll votes for the selected message |
333
+
334
+ When the attachment viewer is open, press `d` to download the current attachment directly.
335
+
336
+ Server actions:
337
+
338
+ | Shortcut | Action | Description |
339
+ | -------- | ------------------- | ----------------------------------------------------- |
340
+ | `m` | Mark server as read | Mark all unread viewable channels in this server read |
341
+ | `u` | Mute / unmute | Toggle server notification mute |
342
+ | `l` | Leave server | Open a confirmation before leaving this server |
343
+
344
+ Channel actions:
345
+
346
+ | Shortcut | Action | Description |
347
+ | -------- | -------------------- | -------------------------------------------- |
348
+ | `j` | Join voice | Join the selected voice channel |
349
+ | `l` | Leave voice | Leave the current voice channel |
350
+ | `p` | Show pinned messages | Open the selected channel's pinned messages |
351
+ | `t` | Show threads | List threads for the selected channel |
352
+ | `m` | Mark as read | Mark the selected channel read |
353
+ | `u` | Mute / unmute | Toggle channel or category notification mute |
354
+
355
+ Voice commands:
356
+
357
+ | Sequence | Action | Description |
358
+ | ----------------- | ------------ | ----------------------------------------- |
359
+ | `Space`, `v`, `d` | Deafen voice | Toggle Concord's Discord voice deaf state |
360
+ | `Space`, `v`, `m` | Mute voice | Toggle Concord's Discord voice mute state |
361
+ | `Space`, `v`, `l` | Leave voice | Leave the current Concord voice channel |
362
+
363
+ #### Composer
364
+
365
+ You can paste copied files into the composer to attach them. Pending uploads
366
+ are shown above the input before sending.
367
+
368
+ | Shortcut | Action | Description |
369
+ | -------------------------- | ----------------- | ---------------------------------------------------------------- |
370
+ | `Ctrl+v` | paste clipboard | Attach copied files or images when present, otherwise paste text |
371
+ | `Ctrl+e` | open $EDITOR | Open $EDITOR on the current draft for long editing |
372
+ | `Ctrl+c` | clear | Clear current draft |
373
+ | `Ctrl+Left`/ `Ctrl+Right` | Jump word | Jump the cursor by word |
374
+ | `Ctrl+Backspace`/ `Ctrl+w` | Delete word | Delete the word before the cursor |
375
+ | `Delete` | Detach attachment | Removes the last pending attachment |
376
+
377
+ #### Mention picker
378
+
379
+ When the @mention picker is open, use `Up` / `Down`,
380
+ `Ctrl+p` / `Ctrl+n`, `Tab`, or `Enter` to choose a mention.
381
+
382
+ #### Emoji picker
383
+
384
+ Type `:` plus at least two letters, such as `:he`, to pick Unicode, server, or
385
+ cross-server custom emoji while writing a message.
386
+
387
+ When `emojis_as_links` is enabled, custom emoji your account cannot send
388
+ directly are inserted as Discord image links instead.
389
+
390
+ To react from the composer, select a message, enter insert mode, then type
391
+ `+:`. The reaction picker opens for that message. Press `/` to search, Enter to
392
+ lock the filter, then Enter again or use a shown shortcut to react.
393
+
394
+ #### Bot commands
395
+
396
+ When the composer input starts with a slash `/`, the command suggestion popup
397
+
398
+ ## Configuration
399
+
400
+ Concord options are stored under Concord's config directory. If
401
+ `XDG_CONFIG_HOME` is set, Concord uses `$XDG_CONFIG_HOME/concord/config.toml`
402
+ for app options and `$XDG_CONFIG_HOME/concord/keymap.toml` for key settings.
403
+ Otherwise it uses the platform config directory. The usual fallback is
404
+ `~/.config/concord/config.toml` and `~/.config/concord/keymap.toml` on Linux,
405
+ matching files under `~/Library/Application Support/concord/` on macOS, and the
406
+ roaming AppData config directory on Windows.
407
+
408
+ You can change some configuration from the in-app Options menu, and Concord saves them back
409
+ to `config.toml`. Key settings are read from `keymap.toml`.
410
+
411
+ <details>
412
+ <summary>Default config</summary>
413
+
414
+ ```toml
415
+ [display]
416
+ # Master switch that hides all image previews when true.
417
+ disable_image_preview = false
418
+
419
+ # Show user avatars next to messages and in profile views.
420
+ show_avatars = true
421
+
422
+ # Render inline image previews for attachments and embeds.
423
+ show_images = true
424
+
425
+ # Preview quality: efficient, balanced, high, or original.
426
+ image_preview_quality = "balanced"
427
+
428
+ # Render custom Discord emoji as images when possible.
429
+ show_custom_emoji = true
430
+
431
+ # Crop avatars into circles instead of showing square images.
432
+ circular_avatars = false
433
+
434
+ [composer]
435
+ # Send custom emoji your account cannot use directly as image links.
436
+ emojis_as_links = false
437
+
438
+ [notifications]
439
+ # Show desktop notifications for Discord messages that pass notification rules.
440
+ desktop_notifications = true
441
+
442
+ # Optional notification icon to include in notifications. May not work on all platforms.
443
+ # When unset, no icon is used. It must either be a name of an icon (typically in /usr/share/icons)
444
+ # or a path to an icon.
445
+ notification_icon = "/path/to/icon.svg"
446
+
447
+ # Optional WAV files for voice join and leave notification sounds.
448
+ # When unset, Concord uses built-in generated tones.
449
+ voice_join_sound = "/path/to/join.wav"
450
+ voice_leave_sound = "/path/to/leave.wav"
451
+
452
+ [voice]
453
+ # Join or update Discord voice with Concord self-muted.
454
+ self_mute = false
455
+
456
+ # Join or update Discord voice with Concord self-deafened.
457
+ self_deaf = false
458
+
459
+ # Allow microphone transmit while this session is joined and not self-muted.
460
+ allow_microphone_transmit = false
461
+
462
+ # Voice activity threshold in dB. Lower values transmit quieter input.
463
+ microphone_sensitivity = -30
464
+
465
+ # Microphone input volume percentage, from 0 to 100.
466
+ microphone_volume = 100
467
+
468
+ # Received voice playback volume percentage, from 0 to 100.
469
+ voice_output_volume = 100
470
+ ```
471
+
472
+ </details><br>
473
+
474
+ `image_preview_quality` supports these values:
475
+
476
+ - `efficient`: smaller preview requests to reduce bandwidth and memory use.
477
+ - `balanced`: default quality with bounded resource use.
478
+ - `high`: sharper resized previews using lossless quality.
479
+ - `original`: request the original source image for previews when possible.
480
+
481
+ This setting only applies to attachment, embed, and attachment viewer previews.
482
+ Avatars and custom emoji keep their separate small-image behavior.
483
+
484
+ <details>
485
+ <summary>Default keymap config</summary>
486
+
487
+ ```toml
488
+ [keymap]
489
+ leader = "space"
490
+ StartComposer = "i"
491
+ OpenPaneFilter = "/"
492
+ FocusGuildPane = "1"
493
+ FocusChannelPane = "2"
494
+ FocusMessagePane = "3"
495
+ FocusMemberPane = "4"
496
+ SelectNext = "j"
497
+ SelectPrevious = "k"
498
+ CycleFocusNext = { keys = ["tab", "l", "right"] }
499
+ CycleFocusPrevious = { keys = ["<S-tab>", "h", "left"] }
500
+ HalfPageDown = "<C-d>"
501
+ HalfPageUp = "<C-u>"
502
+ ScrollViewportDown = "J"
503
+ ScrollViewportUp = "K"
504
+ JumpTop = "gg"
505
+ JumpBottom = "G"
506
+ ScrollHorizontalLeft = "H"
507
+ ScrollHorizontalRight = "L"
508
+ ResizePaneLeft = { keys = ["<A-h>", "<A-left>"] }
509
+ ResizePaneRight = { keys = ["<A-l>", "<A-right>"] }
510
+ Quit = "q"
511
+ CopyMessage = "y"
512
+ ReactMessage = "r"
513
+ ReplyMessage = "R"
514
+ DeleteMessage = "d"
515
+ EditMessage = "e"
516
+ OpenMessageUrl = "o"
517
+ ViewMessageAttachment = "v"
518
+ ToggleGuildPane = "<leader>1"
519
+ ToggleChannelPane = "<leader>2"
520
+ ToggleMemberPane = "<leader>4"
521
+ OpenFocusedPaneAction = "<leader>a"
522
+ OpenCurrentUserProfile = "<leader>p"
523
+ OpenOptions = "<leader>o"
524
+ ChannelSwitcher = "<leader><leader>"
525
+ VoiceDeafen = "<leader>vd"
526
+ VoiceMute = "<leader>vm"
527
+ VoiceLeave = "<leader>vl"
528
+
529
+ [keymap.groups]
530
+ "<leader>v" = "Voice"
531
+
532
+ [keymap.guild_actions]
533
+ MarkAsRead = "m"
534
+ MuteServer = "u"
535
+ LeaveServer = "l"
536
+
537
+ [keymap.channel_actions]
538
+ JoinVoice = "j"
539
+ LeaveVoice = "l"
540
+ ShowPinnedMessages = "p"
541
+ ShowThreads = "t"
542
+ MarkAsRead = "m"
543
+ MuteChannel = "u"
544
+
545
+ [keymap.message_actions]
546
+ CopyMessage = "y"
547
+ ReactMessage = "r"
548
+ ReplyMessage = "R"
549
+ DeleteMessage = "d"
550
+ EditMessage = "e"
551
+ OpenMessageUrl = "o"
552
+ ViewMessageAttachment = "v"
553
+ GoToReferencedMessage = "g"
554
+ ShowMessageProfile = "p"
555
+ PinMessage = "P"
556
+ OpenThread = "t"
557
+ ShowReactionUsers = "u"
558
+ OpenPollVotePicker = "c"
559
+
560
+ [keymap.member_actions]
561
+ ShowProfile = "p"
562
+
563
+ [keymap.composer]
564
+ OpenEditor = "<C-e>"
565
+ PasteClipboard = "<C-v>"
566
+ InsertNewline = { keys = ["<S-enter>", "<C-enter>", "<A-enter>"] }
567
+ Submit = "enter"
568
+ Close = "esc"
569
+ ClearInput = "<C-c>"
570
+ RemoveLastAttachment = "delete"
571
+ DeletePreviousChar = "backspace"
572
+ DeletePreviousWord = { keys = ["<C-backspace>", "<C-w>"] }
573
+ MoveCursorUp = "up"
574
+ MoveCursorDown = "down"
575
+ MoveCursorWordLeft = "<C-left>"
576
+ MoveCursorLeft = "left"
577
+ MoveCursorWordRight = "<C-right>"
578
+ MoveCursorRight = "right"
579
+ MoveCursorHome = "home"
580
+ MoveCursorEnd = "end"
581
+ ```
582
+
583
+ </details><br>
584
+
585
+ You can customize key bindings. Check the [Keymap options](./docs/keymap-options.md) for the config format, supported actions.
586
+
587
+ ## Performance
588
+
589
+ Concord is designed to stay lightweight in normal terminal use. In observed
590
+ typical use, it usually uses about 20-40 MB of memory.
591
+
592
+ Image-heavy screens can temporarily use more memory because compressed image
593
+ bytes need to be decoded before they can be rendered in the terminal. When many
594
+ images are loaded, memory can briefly rise to around 100-200 MB while decoding
595
+ and then drop again as work completes and caches are pruned.
596
+
597
+ To keep resource usage bounded, Concord limits media work in several places:
598
+
599
+ - Attachment previews are downloaded with an 8 MiB per-preview cap.
600
+ - Attachment downloads are capped at 64 MiB.
601
+ - Up to 4 attachment previews are fetched at once.
602
+ - Up to 2 inline image previews are decoded at once.
603
+ - Inline image previews, avatars, and custom emoji use small LRU caches.
604
+ - Image preview requests prefer resized Discord proxy URLs sized for the
605
+ terminal instead of original full-size media when possible.
606
+ - The preview quality preset can lower preview source dimensions or opt into
607
+ original source images. It does not change avatar or custom emoji sizing.
608
+
609
+ Message history is also cached with a per-channel limit, so long-running
610
+ sessions do not keep every message in memory forever.
611
+
612
+ ## FAQ
613
+
614
+ ### Can my account be blocked?
615
+
616
+ Honestly, no.
617
+
618
+ There are some path that did trigger a account block:
619
+
620
+ - Trying to **create a new DM channel and send a message to an unknown user**(meaning there was no pre-existing DM created through the Discord client) can immediately block your account temporarily.
621
+ - Some features that requires a hCapcha challenge on Discord's side.
622
+
623
+ Other features have not caused blocks in my testing.
624
+
625
+ That said, Concord is not an official Discord client. Using unofficial clients, automated user accounts, or self-bots can violate Discord's TOS, so there is always some risk. Use it at your own discretion.
626
+
627
+ ### Does Concord support CAPTCHA?
628
+
629
+ No. If Discord requires a CAPTCHA during login, use token login instead.
630
+
631
+ ## Security
632
+
633
+ - Tokens are stored as **plain text** in Concord's config directory. So keep that file secure and do not share it. You can use the token from that file to log in to the official Discord client, so treat it like a password.
634
+ - On Unix, the credential's parent directory is created with `0700` and the credential file with `0600` permissions.
635
+ - All concord state (config, keymap, credential, log) lives under a single `concord/` directory inside `XDG_CONFIG_HOME` when it is set, or inside the platform config directory otherwise.
636
+ - No system keychain integration yet.
637
+
638
+ ## Contributing
639
+
640
+ Any issues, pull requests, and feedback are welcome. See [CONTRIBUTING.md](./CONTRIBUTING.md) for details.
641
+
642
+ ## License
643
+
644
+ Concord is licensed under GPL-3.0-only.