@emaxe/tuigram 1.0.0 → 1.0.1
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/CHANGELOG.md +108 -0
- package/CHANGELOG.ru.md +110 -0
- package/README.md +496 -199
- package/README.ru.md +656 -0
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,78 +1,336 @@
|
|
|
1
1
|
# 🚀 TuiGram
|
|
2
2
|
|
|
3
|
+
**English** · [Русский](./README.ru.md)
|
|
4
|
+
|
|
3
5
|
[](https://www.npmjs.com/package/@emaxe/tuigram)
|
|
4
6
|
[](https://nodejs.org)
|
|
5
7
|
[](./LICENSE)
|
|
8
|
+
[](https://www.npmjs.com/package/@emaxe/tuigram)
|
|
9
|
+
[](#-installation)
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
A full-featured Telegram terminal client (TUI + CLI) for Node.js, built on the MTProto protocol (`teleproto`).
|
|
8
12
|
|
|
9
|
-
|
|
13
|
+
TuiGram lets you use Telegram entirely from the terminal: browse your dialog list split into categories, read conversations with formatting preserved (bold, italic, links, code highlighting), send messages, reply, edit, delete, react and send files.
|
|
10
14
|
|
|
11
15
|
```
|
|
12
16
|
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
13
|
-
│ 🚀 TuiGram │
|
|
14
|
-
│ 👥 Tech Chat [1420 уч.]
|
|
17
|
+
│ 🚀 TuiGram │ Alex Rivers (@alex_rivers) │ ● В сети │
|
|
18
|
+
│ 👥 Tech Chat [1420 уч.] ✍️ Sam печатает... │
|
|
15
19
|
├──────────────────────────────┬──────────────────────────────────────────────────────────────┤
|
|
16
|
-
│ [1:Все] [2:ЛС] [3:Группы]
|
|
20
|
+
│ [1:Все] [2:ЛС] [3:Группы] … │ ──────────────── Сегодня ──────────────── │
|
|
17
21
|
│ [/] Поиск чатов... │ │
|
|
18
|
-
│ 📌 👤
|
|
22
|
+
│ 📌 👤 Sam Lee · Let me know… │ Sam Lee [13:40] │
|
|
19
23
|
│ 👥 Tech Chat · Nice work! [3]│ Have you checked the latest release? │
|
|
20
|
-
│ 🤖
|
|
21
|
-
│ 📢 News Channel · Дайд… [12] │
|
|
24
|
+
│ 🤖 Deploy Bot · Done! 12:10│ │
|
|
25
|
+
│ 📢 News Channel · Дайд… [12] │ Sam Lee [13:41] │
|
|
26
|
+
│ 👤 Mia Novak · 📷 Фото 9:41 │ 📷 Фото · 1.8 MB │
|
|
27
|
+
│ 💾 Избранное · Ссылка вчр│ │
|
|
28
|
+
│ │ Вы [13:42] ✓✓ │
|
|
29
|
+
│ │ ┌─ Ответ на сообщение #1042 │
|
|
22
30
|
│ │ Yes, testing it right now! │
|
|
23
31
|
│ │ 👍 4 🔥 2 │
|
|
24
32
|
│ ├──────────────────────────────────────────────────────────────┤
|
|
25
|
-
│ │ ↩️ Ответ на [
|
|
26
|
-
│ │ Пишу ответ прямо здесь█
|
|
27
|
-
│ │ │
|
|
33
|
+
│ │ ↩️ Ответ на [Sam Lee]: "Have you checked…" [Esc] │
|
|
34
|
+
│ │ Пишу ответ прямо здесь█ │
|
|
28
35
|
├──────────────────────────────┴──────────────────────────────────────────────────────────────┤
|
|
29
|
-
│ [Tab] Панель │ [Enter] Отправить │ [1-6] Вкладки │ [F1] Помощь │ [Ctrl+
|
|
36
|
+
│ [Tab] Панель │ [Enter] Отправить │ [1-6] Вкладки │ [F1] Помощь │ [Ctrl+Q] Выход │
|
|
30
37
|
└─────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
31
38
|
```
|
|
32
39
|
|
|
40
|
+
> **Note on localization.** The TUI and CLI interface strings are currently in Russian only.
|
|
41
|
+
> The client itself works with any language of chat content. Localization of the UI is planned —
|
|
42
|
+
> see [CHANGELOG.md](./CHANGELOG.md).
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 📑 Table of contents
|
|
47
|
+
|
|
48
|
+
- [Features](#-features)
|
|
49
|
+
- [Screenshots](#-screenshots)
|
|
50
|
+
- [Installation](#-installation)
|
|
51
|
+
- [First run](#-first-run)
|
|
52
|
+
- [Where files are stored](#-where-files-are-stored)
|
|
53
|
+
- [Development](#-development)
|
|
54
|
+
- [Keyboard shortcuts](#️-keyboard-shortcuts)
|
|
55
|
+
- [Slash commands](#-slash-commands-in-the-input-box)
|
|
56
|
+
- [Sending files and images](#-sending-files-and-images)
|
|
57
|
+
- [Themes](#-themes)
|
|
58
|
+
- [Command line usage (CLI)](#️-command-line-usage-cli)
|
|
59
|
+
- [Project structure](#-project-structure)
|
|
60
|
+
- [Security](#-security)
|
|
61
|
+
- [Changelog](#-changelog)
|
|
62
|
+
- [Contributing](#-contributing)
|
|
63
|
+
- [License](#-license)
|
|
64
|
+
|
|
33
65
|
---
|
|
34
66
|
|
|
35
|
-
## ⚡
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
67
|
+
## ⚡ Features
|
|
68
|
+
|
|
69
|
+
- **A complete interactive TUI**:
|
|
70
|
+
- Two-pane adaptive layout (dialog list on the left, history and input box on the right);
|
|
71
|
+
- Keyboard and mouse control (clicks, wheel scrolling);
|
|
72
|
+
- Chat categories: All, Direct messages, Groups, Channels, Bots, Unread;
|
|
73
|
+
- Instant search and filtering of chats by title and `@username` (`/`);
|
|
74
|
+
- Live typing indicator ("… is typing");
|
|
75
|
+
- Colored rendering of Telegram entities (bold, italic, monospace code, URLs, mentions, spoilers);
|
|
76
|
+
- Media attachment indicators (photo, video, document, voice, sticker, poll);
|
|
77
|
+
- Message reactions (👍, 🔥, ❤️);
|
|
78
|
+
- Infinite upward pagination of message history (`PageUp` / `Ctrl+U`);
|
|
79
|
+
- Contextual quick-reply (`Ctrl+R`) and edit (`Ctrl+E`) modes;
|
|
80
|
+
- Modal windows: Help (`F1` / `?`), Chat info (`Ctrl+P`), Action menu (`Ctrl+A`), Send file (`Ctrl+O`).
|
|
81
|
+
- **Standalone CLI mode**:
|
|
82
|
+
- Send messages and files straight from the command line;
|
|
83
|
+
- List dialogs and print chat history in the terminal;
|
|
84
|
+
- Stream live updates.
|
|
85
|
+
- **Sensible configuration**:
|
|
86
|
+
- Credentials and session live in OS user directories — the package stays read-only and survives updates;
|
|
87
|
+
- Session and credentials are written with `0600` permissions.
|
|
56
88
|
|
|
57
89
|
---
|
|
58
90
|
|
|
59
|
-
##
|
|
91
|
+
## 🖼 Screenshots
|
|
92
|
+
|
|
93
|
+
TuiGram lives in the terminal, so instead of images here are exact text captures of its
|
|
94
|
+
screens. Labels, hints and output formats are taken from the interface code rather than
|
|
95
|
+
invented; the data in the examples is fictional.
|
|
96
|
+
|
|
97
|
+
Note that the interface strings are Russian — the screens below show the client as it
|
|
98
|
+
actually looks today.
|
|
99
|
+
|
|
100
|
+
The main window is shown at the top of this README. Below are the remaining screens.
|
|
101
|
+
|
|
102
|
+
### Chat search and filtering
|
|
103
|
+
|
|
104
|
+
`/` starts an instant search by title and `@username`; the digits `1`–`6` switch categories
|
|
105
|
+
(All, Direct messages, Groups, Channels, Bots, Unread).
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
┌─────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
109
|
+
│ 🚀 TuiGram │ Alex Rivers (@alex_rivers) │ ● В сети │
|
|
110
|
+
├──────────────────────────────┬──────────────────────────────────────────────────────────────┤
|
|
111
|
+
│ [1:Все] [2:ЛС] [3:Группы] … │ ──────────────── Сегодня ──────────────── │
|
|
112
|
+
│ [/] tech█ │ │
|
|
113
|
+
│ 👥 Tech Chat · Nice work! [3]│ Sam Lee [11:02] │
|
|
114
|
+
│ 📢 Tech Digest · Выпуск… │ Let me know how it goes. │
|
|
115
|
+
│ 🤖 TechSupport Bot · Ок │ │
|
|
116
|
+
│ │ Вы [11:05] ✓✓ │
|
|
117
|
+
│ 3 из 214 чатов │ Will do 👍 │
|
|
118
|
+
│ ├──────────────────────────────────────────────────────────────┤
|
|
119
|
+
│ │ Введите сообщение…█ │
|
|
120
|
+
└──────────────────────────────┴──────────────────────────────────────────────────────────────┘
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
<details>
|
|
124
|
+
<summary><b>Help — <code>F1</code> / <code>?</code></b></summary>
|
|
125
|
+
|
|
126
|
+
The full list of shortcuts and slash commands, right inside the client.
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
┌──────────────────────────────────────────────────────────────────────────┐
|
|
130
|
+
│ 🚀 TuiGram — Горячие клавиши и управление │
|
|
131
|
+
│ │
|
|
132
|
+
│ Навигация и фокус: │
|
|
133
|
+
│ [Tab] / [Shift+Tab] Фокус: Чаты → Сообщения → Ввод │
|
|
134
|
+
│ [↑] / [↓] Перемещение по списку чатов │
|
|
135
|
+
│ [Enter] Открыть чат / Загрузить историю │
|
|
136
|
+
│ [PageUp] / [Ctrl+U] Прокрутка вверх / старая история │
|
|
137
|
+
│ │
|
|
138
|
+
│ Вкладки фильтрации диалогов: │
|
|
139
|
+
│ [1] Все чаты [2] Личные (ЛС) [3] Группы │
|
|
140
|
+
│ [4] Каналы [5] Боты [6] Непрочитанные │
|
|
141
|
+
│ [/] Поиск чатов по названию/username │
|
|
142
|
+
│ │
|
|
143
|
+
│ Работа с сообщениями: │
|
|
144
|
+
│ [Enter] Отправить [Ctrl+R] Ответить (Reply) │
|
|
145
|
+
│ [Ctrl+J] Перенос строки [Ctrl+E] Редактировать сообщение │
|
|
146
|
+
│ [Ctrl+A] Меню действий [Ctrl+O] Отправить файл / фото │
|
|
147
|
+
│ [Ctrl+P] Инфо о чате [Esc] Закрыть окно / режим │
|
|
148
|
+
│ │
|
|
149
|
+
│ Слэш-команды в поле ввода: │
|
|
150
|
+
│ /help /info /sendfile /sendfile <путь> /clear /logout │
|
|
151
|
+
│ │
|
|
152
|
+
│ Выход: │
|
|
153
|
+
│ [Ctrl+Q] или [Ctrl+C] Безопасный выход из клиента │
|
|
154
|
+
│ │
|
|
155
|
+
│ [ Закрыть ] │
|
|
156
|
+
└──────────────────────────────────────────────────────────────────────────┘
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
</details>
|
|
60
160
|
|
|
61
|
-
|
|
161
|
+
<details>
|
|
162
|
+
<summary><b>Message action menu — <code>Ctrl+A</code></b></summary>
|
|
163
|
+
|
|
164
|
+
Reply, edit, delete, reactions and attachment download. "Edit" and
|
|
165
|
+
"Download" appear only where they actually apply.
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
┌──────────────────────────────────────────────────────┐
|
|
169
|
+
│ ⚡ Действия с сообщением #1042 │
|
|
170
|
+
│ Sam Lee: Have you checked the latest release? │
|
|
171
|
+
├──────────────────────────────────────────────────────┤
|
|
172
|
+
│ ↩️ Ответить (Reply) │
|
|
173
|
+
│ ✏️ Редактировать текст │
|
|
174
|
+
│ 🗑️ Удалить сообщение │
|
|
175
|
+
│ 👍 Поставить реакцию 👍 │
|
|
176
|
+
│ 🔥 Поставить реакцию 🔥 │
|
|
177
|
+
│ ❤️ Поставить реакцию ❤️ │
|
|
178
|
+
│ 📥 Скачать медиа-вложение │
|
|
179
|
+
│ 📋 Скопировать текст в ввод │
|
|
180
|
+
├──────────────────────────────────────────────────────┤
|
|
181
|
+
│ [↑↓] Выбор [Enter] Выполнить [Esc] Отмена │
|
|
182
|
+
└──────────────────────────────────────────────────────┘
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
</details>
|
|
186
|
+
|
|
187
|
+
<details>
|
|
188
|
+
<summary><b>Send file — <code>Ctrl+O</code></b></summary>
|
|
189
|
+
|
|
190
|
+
Several paths separated by `|` are sent as a single album. The line under the
|
|
191
|
+
checkbox states exactly what the file will become on Telegram's side.
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
┌────────────────────────────────────────────────────────────┐
|
|
195
|
+
│ 📤 Отправка файла или документа │
|
|
196
|
+
├────────────────────────────────────────────────────────────┤
|
|
197
|
+
│ Путь к файлу (несколько — через |) [Ctrl+F] Обзор │
|
|
198
|
+
│ ┌────────────────────────────────────────────────────────┐ │
|
|
199
|
+
│ │ ~/Desktop/photo.png | ~/Desktop/chart.png█ │ │
|
|
200
|
+
│ └────────────────────────────────────────────────────────┘ │
|
|
201
|
+
│ Подпись (необязательно): │
|
|
202
|
+
│ ┌────────────────────────────────────────────────────────┐ │
|
|
203
|
+
│ │ Две картинки с релиза │ │
|
|
204
|
+
│ └────────────────────────────────────────────────────────┘ │
|
|
205
|
+
│ [ ] Как файл, без сжатия [Ctrl+D] │
|
|
206
|
+
│ ✓ photo.png · 2.4 MB · уйдёт как фото │
|
|
207
|
+
├────────────────────────────────────────────────────────────┤
|
|
208
|
+
│ [ Отправить ] [ Отмена ] │
|
|
209
|
+
│ [Tab] Поля [Enter] Далее [Ctrl+F] Обзор [Esc] Выход │
|
|
210
|
+
└────────────────────────────────────────────────────────────┘
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
</details>
|
|
214
|
+
|
|
215
|
+
<details>
|
|
216
|
+
<summary><b>File browser — <code>Ctrl+F</code></b></summary>
|
|
217
|
+
|
|
218
|
+
Navigate folders with the arrow keys; the size of the highlighted file is shown
|
|
219
|
+
at the bottom.
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
┌──────────────────────────────────────────────────────────┐
|
|
223
|
+
│ 📁 Выбор файла: /Users/alex/Desktop │
|
|
224
|
+
├──────────────────────────────────────────────────────────┤
|
|
225
|
+
│ .. <папка> │
|
|
226
|
+
│ screenshots/ <папка> │
|
|
227
|
+
│ ▸ photo.png 2.4 MB │
|
|
228
|
+
│ chart.png 812 KB │
|
|
229
|
+
│ report.pdf 1.1 MB │
|
|
230
|
+
│ archive.zip 18.7 MB │
|
|
231
|
+
├──────────────────────────────────────────────────────────┤
|
|
232
|
+
│ photo.png · 2.4 MB │
|
|
233
|
+
│ [↑↓] Навигация [Enter] Выбрать [Esc] Назад │
|
|
234
|
+
└──────────────────────────────────────────────────────────┘
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
</details>
|
|
238
|
+
|
|
239
|
+
<details>
|
|
240
|
+
<summary><b>Chat info — <code>Ctrl+P</code></b></summary>
|
|
241
|
+
|
|
242
|
+
ID, type, username, member count and description.
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
┌──────────────────────────────────────────────────────┐
|
|
246
|
+
│ ℹ Информация о чате │
|
|
247
|
+
├──────────────────────────────────────────────────────┤
|
|
248
|
+
│ Название: Tech Chat │
|
|
249
|
+
│ Тип: supergroup │
|
|
250
|
+
│ ID: -1001234567890 │
|
|
251
|
+
│ Username: @techchat │
|
|
252
|
+
│ Участников: 1420 │
|
|
253
|
+
│ Уведомления: Включены │
|
|
254
|
+
│ │
|
|
255
|
+
│ О чате / О себе: │
|
|
256
|
+
│ Чат про терминальные клиенты и MTProto. │
|
|
257
|
+
├──────────────────────────────────────────────────────┤
|
|
258
|
+
│ [ Закрыть ] │
|
|
259
|
+
└──────────────────────────────────────────────────────┘
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
</details>
|
|
263
|
+
|
|
264
|
+
### Command line mode
|
|
265
|
+
|
|
266
|
+
<details>
|
|
267
|
+
<summary><b>CLI command output</b></summary>
|
|
268
|
+
|
|
269
|
+
**`tuigram dialogs --limit 8`**
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
📂 Загрузка диалогов (макс. 8)...
|
|
273
|
+
|
|
274
|
+
📌 [user ] Sam Lee id=100200301
|
|
275
|
+
[supergroup] Tech Chat id=-1001234567890 (+3)
|
|
276
|
+
[bot ] Deploy Bot id=100200302
|
|
277
|
+
[channel ] News Channel id=-1009876543210 (+12)
|
|
278
|
+
[saved ] Избранное id=100200300
|
|
279
|
+
[user ] Mia Novak id=100200303 (+1)
|
|
280
|
+
[group ] Team Terminal id=-400112233
|
|
281
|
+
[user ] Nina Ivanova id=100200304
|
|
282
|
+
|
|
283
|
+
Всего получено: 8 диалогов
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**`tuigram history @sam_lee --limit 5`**
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
💬 Загрузка истории для @sam_lee (макс. 5 сообщений)...
|
|
290
|
+
|
|
291
|
+
[29.08.2026, 11:02:14] #1040 Sam Lee: Let me know how it goes.
|
|
292
|
+
[29.08.2026, 11:05:41] #1041 Вы: Will do 👍
|
|
293
|
+
[29.08.2026, 13:40:07] #1042 Sam Lee: Have you checked the latest release?
|
|
294
|
+
[29.08.2026, 13:41:22] #1043 Sam Lee: 📷 Фото
|
|
295
|
+
[29.08.2026, 13:42:55] #1044 Вы (в ответ на #1042): Yes, testing it right now! (изменено)
|
|
296
|
+
|
|
297
|
+
Всего отображено: 5 сообщений
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**`tuigram listen`**
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
🟢 Подключено как: Alex Rivers (@alex_rivers)
|
|
304
|
+
Слушаю обновления в реальном времени... Нажмите Ctrl+C для выхода.
|
|
305
|
+
|
|
306
|
+
[13:40:07] + НОВОЕ [-1001234567890] Sam Lee: Have you checked the latest release?
|
|
307
|
+
[13:41:19] ✍️ ПЕЧАТАЕТ чат: -1001234567890
|
|
308
|
+
[13:42:55] + НОВОЕ [-1001234567890] Вы: Yes, testing it right now!
|
|
309
|
+
[13:43:30] ~ ИЗМЕНЕНО [-1001234567890] #1044: Yes, testing it right now! 🚀
|
|
310
|
+
[13:44:02] - УДАЛЕНО [123456789] IDs: 1039, 1038
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
</details>
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## 📦 Installation
|
|
318
|
+
|
|
319
|
+
### Option 1: global install from npm (recommended)
|
|
62
320
|
|
|
63
321
|
```bash
|
|
64
322
|
npm install -g @emaxe/tuigram
|
|
65
323
|
```
|
|
66
324
|
|
|
67
|
-
|
|
325
|
+
The `tuigram` command is then available from any directory.
|
|
68
326
|
|
|
69
|
-
###
|
|
327
|
+
### Option 2: one-off run without installing
|
|
70
328
|
|
|
71
329
|
```bash
|
|
72
330
|
npx @emaxe/tuigram
|
|
73
331
|
```
|
|
74
332
|
|
|
75
|
-
###
|
|
333
|
+
### Option 3: from source (for development)
|
|
76
334
|
|
|
77
335
|
```bash
|
|
78
336
|
git clone https://github.com/emaxe/tuigram.git
|
|
@@ -83,282 +341,321 @@ npm start
|
|
|
83
341
|
|
|
84
342
|
---
|
|
85
343
|
|
|
86
|
-
## ⚙️
|
|
344
|
+
## ⚙️ First run
|
|
87
345
|
|
|
88
|
-
### 1.
|
|
346
|
+
### 1. Telegram API credentials
|
|
89
347
|
|
|
90
|
-
|
|
348
|
+
Get your `api_id` and `api_hash` at [https://my.telegram.org](https://my.telegram.org) (*API development tools*), then run:
|
|
91
349
|
|
|
92
350
|
```bash
|
|
93
351
|
tuigram init
|
|
94
352
|
```
|
|
95
353
|
|
|
96
|
-
|
|
354
|
+
The command asks for both keys and stores them with `0600` permissions. For scripts and CI there is a non-interactive form:
|
|
97
355
|
|
|
98
356
|
```bash
|
|
99
357
|
tuigram init --api-id 1234567 --api-hash 0123456789abcdef0123456789abcdef
|
|
100
358
|
```
|
|
101
359
|
|
|
102
|
-
|
|
360
|
+
Alternatively, use the `TELEGRAM_API_ID` and `TELEGRAM_API_HASH` environment variables — they take precedence over the settings file.
|
|
103
361
|
|
|
104
|
-
### 2.
|
|
362
|
+
### 2. Authorization and launch
|
|
105
363
|
|
|
106
364
|
```bash
|
|
107
365
|
tuigram
|
|
108
366
|
```
|
|
109
367
|
|
|
110
|
-
|
|
368
|
+
On first launch TuiGram asks for your phone number, the confirmation code from Telegram and your 2FA password (if enabled). The session is then saved and subsequent launches are instant.
|
|
111
369
|
|
|
112
|
-
|
|
370
|
+
You can also authorize separately with `tuigram login`.
|
|
113
371
|
|
|
114
|
-
>
|
|
115
|
-
> `tuigram login`
|
|
116
|
-
>
|
|
117
|
-
>
|
|
118
|
-
> (
|
|
372
|
+
> **In a non-interactive environment** (CI, a pipe, `< /dev/null`) phone login is impossible:
|
|
373
|
+
> `tuigram login` exits immediately with a clear error instead of hanging. If a session
|
|
374
|
+
> already exists, the command simply reports who you are signed in as and returns exit
|
|
375
|
+
> code `0`. For automation, drop a ready `session.txt` into the data directory
|
|
376
|
+
> (`tuigram paths` prints the location).
|
|
119
377
|
|
|
120
378
|
---
|
|
121
379
|
|
|
122
|
-
## 📂
|
|
380
|
+
## 📂 Where files are stored
|
|
123
381
|
|
|
124
|
-
|
|
382
|
+
Nothing is written inside the package itself — this matters for global installs, where `node_modules` is usually not writable and is wiped on update.
|
|
125
383
|
|
|
126
|
-
|
|
|
384
|
+
| What | macOS / Linux | Windows |
|
|
127
385
|
|---|---|---|
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
|
|
|
386
|
+
| Settings (`.env`) | `~/.config/tuigram/.env` | `%APPDATA%\tuigram\.env` |
|
|
387
|
+
| Session | `~/.local/share/tuigram/session.txt` | `%LOCALAPPDATA%\tuigram\session.txt` |
|
|
388
|
+
| Downloads from chats | `~/.local/share/tuigram/downloads/` | `%LOCALAPPDATA%\tuigram\downloads\` |
|
|
131
389
|
|
|
132
|
-
|
|
390
|
+
To inspect the actual paths and configuration state:
|
|
133
391
|
|
|
134
392
|
```bash
|
|
135
393
|
tuigram paths
|
|
136
394
|
```
|
|
137
395
|
|
|
138
|
-
|
|
396
|
+
Locations can be overridden with `TUIGRAM_CONFIG_DIR` and `TUIGRAM_DATA_DIR` (`XDG_CONFIG_HOME` / `XDG_DATA_HOME` are honored too).
|
|
139
397
|
|
|
140
|
-
|
|
141
|
-
1.
|
|
142
|
-
2. `.env`
|
|
143
|
-
3. `~/.config/tuigram/.env` —
|
|
398
|
+
**Settings precedence** (top to bottom, first match wins):
|
|
399
|
+
1. process environment variables;
|
|
400
|
+
2. `.env` in the project root — only when running from a repository clone;
|
|
401
|
+
3. `~/.config/tuigram/.env` — the main file for an installed CLI.
|
|
144
402
|
|
|
145
|
-
|
|
403
|
+
A session from an older installation (`<project>/data/session.txt`) is migrated to the new location automatically on first run — no need to log in again.
|
|
146
404
|
|
|
147
405
|
---
|
|
148
406
|
|
|
149
|
-
## 🛠
|
|
407
|
+
## 🛠 Development
|
|
150
408
|
|
|
151
|
-
|
|
409
|
+
When running from a repository clone, an interactive launcher menu is available:
|
|
152
410
|
|
|
153
411
|
```bash
|
|
154
|
-
./run.sh #
|
|
412
|
+
./run.sh # or npm run menu
|
|
155
413
|
```
|
|
156
414
|
|
|
157
|
-
|
|
415
|
+
It offers a convenient choice of mode (TUI, login, dialogs, send, tests, cleanup).
|
|
158
416
|
|
|
159
|
-
|
|
417
|
+
Tests and a check of the future npm package contents:
|
|
160
418
|
|
|
161
419
|
```bash
|
|
162
|
-
npm test #
|
|
163
|
-
node scripts/check-package.js #
|
|
420
|
+
npm test # unit tests
|
|
421
|
+
node scripts/check-package.js # verifies that .env and the session do not leak into the package
|
|
164
422
|
```
|
|
165
423
|
|
|
166
424
|
---
|
|
167
425
|
|
|
168
|
-
## ⌨️
|
|
426
|
+
## ⌨️ Keyboard shortcuts
|
|
169
427
|
|
|
170
|
-
|
|
|
428
|
+
| Shortcut | Scope | Action |
|
|
171
429
|
|---|---|---|
|
|
172
|
-
| `Tab` / `Shift+Tab` |
|
|
173
|
-
| `↑` / `↓` |
|
|
174
|
-
| `Enter` |
|
|
175
|
-
| `1` .. `6` |
|
|
176
|
-
| `/` |
|
|
177
|
-
| `Enter` |
|
|
178
|
-
| `Ctrl+J` |
|
|
179
|
-
| `Ctrl+R` |
|
|
180
|
-
| `Ctrl+E` |
|
|
181
|
-
| `Ctrl+A` |
|
|
182
|
-
| `Ctrl+O` |
|
|
183
|
-
| `Ctrl+F` |
|
|
184
|
-
| `Ctrl+D` |
|
|
185
|
-
| `Ctrl+P` |
|
|
186
|
-
| `PageUp` / `Ctrl+U
|
|
187
|
-
| `PageDown` / `Ctrl+D
|
|
188
|
-
| `Esc` |
|
|
189
|
-
| `F1`
|
|
190
|
-
| `Ctrl+Q` / `Ctrl+C` |
|
|
430
|
+
| `Tab` / `Shift+Tab` | Global | Cycle focus: dialog list → message feed → input box |
|
|
431
|
+
| `↑` / `↓` | Dialog list | Select a chat |
|
|
432
|
+
| `Enter` | Dialog list | Open the selected chat and load its history |
|
|
433
|
+
| `1` .. `6` | Dialog list | Switch category: `1:All`, `2:DM`, `3:Groups`, `4:Channels`, `5:Bots`, `6:Unread` |
|
|
434
|
+
| `/` | Dialog list | Search / filter chats |
|
|
435
|
+
| `Enter` | Input box | Send the typed message |
|
|
436
|
+
| `Ctrl+J` | Input box | Insert a line break without sending |
|
|
437
|
+
| `Ctrl+R` | Chat / Input | Reply to the last message |
|
|
438
|
+
| `Ctrl+E` | Chat / Input | Edit your own last message |
|
|
439
|
+
| `Ctrl+A` | Messages | Context action menu (reactions, delete, download, reply) |
|
|
440
|
+
| `Ctrl+O` | Global | Send a file / photo / document |
|
|
441
|
+
| `Ctrl+F` | Send dialog | File browser (navigate folders) |
|
|
442
|
+
| `Ctrl+D` | Send dialog | Send uncompressed, as a document |
|
|
443
|
+
| `Ctrl+P` | Global | Info about the current chat (ID, members, links) |
|
|
444
|
+
| `PageUp` / `Ctrl+U` | History | Scroll up / load older history |
|
|
445
|
+
| `PageDown` / `Ctrl+D` | History | Scroll down |
|
|
446
|
+
| `Esc` | Modals | Close the modal / cancel reply or edit |
|
|
447
|
+
| `F1` or `?` | Global | Help window with every shortcut |
|
|
448
|
+
| `Ctrl+Q` / `Ctrl+C` | Global | Safely exit the client |
|
|
191
449
|
|
|
192
450
|
---
|
|
193
451
|
|
|
194
|
-
## 💬
|
|
452
|
+
## 💬 Slash commands in the input box
|
|
195
453
|
|
|
196
|
-
|
|
454
|
+
Quick commands are available in the message input box (they start with `/`):
|
|
197
455
|
|
|
198
|
-
- `/help` —
|
|
199
|
-
- `/info` —
|
|
200
|
-
- `/sendfile` —
|
|
201
|
-
- `/sendfile
|
|
202
|
-
- `/sendfile
|
|
203
|
-
- `/sendfile
|
|
204
|
-
- `/clear` —
|
|
205
|
-
- `/logout` —
|
|
456
|
+
- `/help` — open the help window;
|
|
457
|
+
- `/info` — detailed information about the current chat;
|
|
458
|
+
- `/sendfile` — open the send-file dialog;
|
|
459
|
+
- `/sendfile <path>` — send a file right away;
|
|
460
|
+
- `/sendfile <path> -- <caption>` — file with a caption;
|
|
461
|
+
- `/sendfile <path> | <path> -- <caption>` — an album of several files;
|
|
462
|
+
- `/clear` — clear the on-screen message feed;
|
|
463
|
+
- `/logout` — sign out of the Telegram account.
|
|
206
464
|
|
|
207
465
|
---
|
|
208
466
|
|
|
209
|
-
## 📎
|
|
467
|
+
## 📎 Sending files and images
|
|
210
468
|
|
|
211
|
-
|
|
469
|
+
Three ways: the `Ctrl+O` dialog, the `/sendfile` slash command, and the `sendfile` console command.
|
|
212
470
|
|
|
213
|
-
|
|
471
|
+
**The send dialog (`Ctrl+O`)**
|
|
214
472
|
|
|
215
|
-
- `Ctrl+F` —
|
|
216
|
-
-
|
|
217
|
-
-
|
|
218
|
-
- `Ctrl+D` —
|
|
219
|
-
-
|
|
220
|
-
-
|
|
473
|
+
- `Ctrl+F` — file browser: navigate folders with the arrow keys, `Enter` enters a folder or picks a file, `Esc` goes back. The size of the highlighted file is shown at the bottom.
|
|
474
|
+
- You can also just type a path: `~/Desktop/photo.png`, quoted paths and escaped spaces are understood — so dragging a file into the terminal works.
|
|
475
|
+
- Multiple files — separate them with `|` in the path field (or add them one by one via the browser). Up to 10 are sent as a single album.
|
|
476
|
+
- `Ctrl+D` — send uncompressed, as a document. Useful when the original image quality matters.
|
|
477
|
+
- The line under the checkbox shows exactly what will be sent: `✓ photo.png · 2.4 MB · will be sent as a photo`.
|
|
478
|
+
- If reply mode (`Ctrl+R`) is active at that moment, the file is sent **as a reply** to that message.
|
|
221
479
|
|
|
222
|
-
|
|
480
|
+
**What goes as a photo and what as a document**
|
|
223
481
|
|
|
224
|
-
`.png`, `.jpg`, `.jpeg`
|
|
482
|
+
Telegram accepts `.png`, `.jpg`, `.jpeg` as compressed photos; video formats (`.mp4`, `.mov`, `.mkv`, etc.) as video; everything else, including `.webp` and `.heic`, as a document. The "As a file, uncompressed" checkbox (`Ctrl+D`, or `--as-file` in the CLI) forces anything to be sent as a document.
|
|
225
483
|
|
|
226
|
-
|
|
484
|
+
**Progress and cancellation**
|
|
227
485
|
|
|
228
|
-
|
|
486
|
+
The status bar shows a percentage during upload. `Esc` aborts the transfer.
|
|
229
487
|
|
|
230
|
-
|
|
488
|
+
**Downloading incoming media**
|
|
231
489
|
|
|
232
|
-
`Ctrl+A`
|
|
490
|
+
`Ctrl+A` on a message → "Download attachment". The file is saved to the downloads directory.
|
|
233
491
|
|
|
234
492
|
---
|
|
235
493
|
|
|
236
|
-
## 🎨
|
|
494
|
+
## 🎨 Themes
|
|
237
495
|
|
|
238
|
-
|
|
496
|
+
The theme is set in `.env`:
|
|
239
497
|
|
|
240
498
|
```env
|
|
241
|
-
TUI_THEME=default #
|
|
499
|
+
TUI_THEME=default # dark (default)
|
|
242
500
|
TUI_THEME=nord # Nord
|
|
243
|
-
TUI_THEME=light #
|
|
501
|
+
TUI_THEME=light # light
|
|
244
502
|
```
|
|
245
503
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
504
|
+
All colors are given as hex values and are reduced to the xterm-256 palette (indices ≥ 16).
|
|
505
|
+
Named colors (`blue`, `cyan`, `gray`) are deliberately avoided: they occupy indices 0–15,
|
|
506
|
+
which the terminal theme repaints as it pleases — that is why a blue background could render
|
|
507
|
+
as teal and gray text could disappear entirely.
|
|
250
508
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
увидит пользователь.
|
|
509
|
+
The contrast of every "text on background" pair is verified by an automated WCAG test
|
|
510
|
+
(threshold 3:1) **after** conversion to xterm-256 — that is, exactly as the user will see it.
|
|
254
511
|
|
|
255
512
|
---
|
|
256
513
|
|
|
257
|
-
## 🛠️
|
|
514
|
+
## 🛠️ Command line usage (CLI)
|
|
258
515
|
|
|
259
|
-
TuiGram
|
|
260
|
-
|
|
516
|
+
TuiGram can be used as a set of console utilities (when running from a repository
|
|
517
|
+
clone, substitute `node bin/tuigram.js` for `tuigram`):
|
|
261
518
|
|
|
262
519
|
```bash
|
|
263
|
-
#
|
|
520
|
+
# Authorization
|
|
264
521
|
tuigram login
|
|
265
522
|
|
|
266
|
-
#
|
|
523
|
+
# List dialogs
|
|
267
524
|
tuigram dialogs --limit 30
|
|
268
525
|
|
|
269
|
-
#
|
|
270
|
-
tuigram history @
|
|
526
|
+
# View chat history (@username, ID, or `me` for Saved Messages)
|
|
527
|
+
tuigram history @sam_lee --limit 20
|
|
271
528
|
tuigram history me
|
|
272
529
|
|
|
273
|
-
#
|
|
274
|
-
tuigram send me "
|
|
275
|
-
tuigram send @friend "
|
|
530
|
+
# Send a text message
|
|
531
|
+
tuigram send me "Hello from the terminal!"
|
|
532
|
+
tuigram send @friend "See you at 18:00"
|
|
276
533
|
|
|
277
|
-
#
|
|
534
|
+
# Send a file (multiple paths are sent as one album)
|
|
278
535
|
tuigram sendfile me ./screenshot.png
|
|
279
|
-
tuigram sendfile me ~/a.png ~/b.png --caption "
|
|
280
|
-
tuigram sendfile me ~/photo.png --as-file #
|
|
536
|
+
tuigram sendfile me ~/a.png ~/b.png --caption "Two pictures"
|
|
537
|
+
tuigram sendfile me ~/photo.png --as-file # uncompressed, as a document
|
|
281
538
|
|
|
282
|
-
#
|
|
539
|
+
# Live stream of real-time updates
|
|
283
540
|
tuigram listen
|
|
284
541
|
```
|
|
285
542
|
|
|
286
543
|
---
|
|
287
544
|
|
|
288
|
-
## 📁
|
|
545
|
+
## 📁 Project structure
|
|
289
546
|
|
|
290
547
|
```
|
|
291
548
|
TuiGram/
|
|
292
549
|
├── bin/
|
|
293
|
-
│ └── tuigram.js # CLI
|
|
550
|
+
│ └── tuigram.js # CLI executable
|
|
294
551
|
├── src/
|
|
295
|
-
│ ├── index.js #
|
|
296
|
-
│ ├── config.js #
|
|
297
|
-
│ ├── state.js #
|
|
552
|
+
│ ├── index.js # Main entry point (TUI / CLI router)
|
|
553
|
+
│ ├── config.js # User directory paths and .env loader
|
|
554
|
+
│ ├── state.js # Reactive centralized state store
|
|
298
555
|
│ ├── telegram/
|
|
299
|
-
│ │ ├── client.js #
|
|
300
|
-
│ │ ├── auth.js #
|
|
301
|
-
│ │ ├── dialogs.js #
|
|
302
|
-
│ │ ├── messages.js #
|
|
303
|
-
│ │ ├── listener.js #
|
|
304
|
-
│ │ ├── entities.js #
|
|
305
|
-
│ │ └── formatter.js # Telegram
|
|
556
|
+
│ │ ├── client.js # MTProto client creation and management
|
|
557
|
+
│ │ ├── auth.js # Interactive login wizard and 2FA
|
|
558
|
+
│ │ ├── dialogs.js # Fetching, filtering and searching dialogs
|
|
559
|
+
│ │ ├── messages.js # History loading, sending, editing, files, reactions
|
|
560
|
+
│ │ ├── listener.js # Live background MTProto event listener
|
|
561
|
+
│ │ ├── entities.js # Peer parsing, chat types and entity cache
|
|
562
|
+
│ │ └── formatter.js # Telegram entities -> Blessed ANSI formatting
|
|
306
563
|
│ ├── ui/
|
|
307
|
-
│ │ ├── screen.js #
|
|
308
|
-
│ │ ├── theme.js #
|
|
309
|
-
│ │ ├── app.js #
|
|
564
|
+
│ │ ├── screen.js # Blessed screen management
|
|
565
|
+
│ │ ├── theme.js # Themes (Default Dark, Nord, Light)
|
|
566
|
+
│ │ ├── app.js # Main interface coordinator
|
|
310
567
|
│ │ └── components/
|
|
311
|
-
│ │ ├── header.js #
|
|
312
|
-
│ │ ├── chatList.js #
|
|
313
|
-
│ │ ├── chatView.js #
|
|
314
|
-
│ │ ├── inputBox.js #
|
|
315
|
-
│ │ ├── statusBar.js #
|
|
568
|
+
│ │ ├── header.js # Top header and connection status
|
|
569
|
+
│ │ ├── chatList.js # Dialog list with scrolling, tabs and search
|
|
570
|
+
│ │ ├── chatView.js # Message feed with autoscroll and formatting
|
|
571
|
+
│ │ ├── inputBox.js # Input box with reply/edit banner and history
|
|
572
|
+
│ │ ├── statusBar.js # Bottom hint line and toasts
|
|
316
573
|
│ │ └── modals/
|
|
317
|
-
│ │ ├── helpModal.js #
|
|
318
|
-
│ │ ├── chatInfoModal.js #
|
|
319
|
-
│ │ ├── actionModal.js #
|
|
320
|
-
│ │ ├── fileModal.js #
|
|
321
|
-
│ │ └── confirmModal.js #
|
|
574
|
+
│ │ ├── helpModal.js # Help window
|
|
575
|
+
│ │ ├── chatInfoModal.js # Chat info window
|
|
576
|
+
│ │ ├── actionModal.js # Message action menu
|
|
577
|
+
│ │ ├── fileModal.js # Send-file dialog
|
|
578
|
+
│ │ └── confirmModal.js # Confirmation dialog
|
|
322
579
|
│ ├── cli/
|
|
323
|
-
│ │ ├── cliCommands.js #
|
|
324
|
-
│ │ ├── init.js # tuigram init / paths —
|
|
325
|
-
│ │ └── formatters.js #
|
|
580
|
+
│ │ ├── cliCommands.js # Standalone CLI commands
|
|
581
|
+
│ │ ├── init.js # tuigram init / paths — setup and diagnostics
|
|
582
|
+
│ │ └── formatters.js # Console table and log formatters
|
|
326
583
|
│ └── utils/
|
|
327
|
-
│ ├── storage.js #
|
|
328
|
-
│ └── time.js #
|
|
584
|
+
│ ├── storage.js # File operations and session persistence
|
|
585
|
+
│ └── time.js # Time and date formatting
|
|
329
586
|
├── scripts/
|
|
330
|
-
│ └── check-package.js #
|
|
587
|
+
│ └── check-package.js # Pre-publish npm package check
|
|
331
588
|
├── test/
|
|
332
|
-
│ └── unit.test.js #
|
|
333
|
-
├── .env.example #
|
|
334
|
-
├── run.sh #
|
|
589
|
+
│ └── unit.test.js # Unit tests
|
|
590
|
+
├── .env.example # Configuration example
|
|
591
|
+
├── run.sh # Development launcher menu
|
|
592
|
+
├── AGENTS.md # Codebase rules (source of truth for AI agents)
|
|
593
|
+
├── CHANGELOG.md
|
|
335
594
|
├── LICENSE
|
|
336
595
|
├── package.json
|
|
337
|
-
|
|
596
|
+
├── README.md
|
|
597
|
+
└── README.ru.md
|
|
338
598
|
```
|
|
339
599
|
|
|
340
|
-
>
|
|
341
|
-
>
|
|
600
|
+
> The published npm package contains only `bin/`, `src/`, `README.md`, `README.ru.md`,
|
|
601
|
+
> `CHANGELOG.md`, `LICENSE` and `.env.example` — see the `files` field in `package.json`.
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## 🔒 Security
|
|
606
|
+
|
|
607
|
+
**Where the authorization lives.** A single file — `session.txt` in the data directory
|
|
608
|
+
(`~/.local/share/tuigram/` or `%LOCALAPPDATA%\tuigram\`; the location can be changed with
|
|
609
|
+
`TUIGRAM_DATA_DIR` and inspected with `tuigram paths`). It holds an MTProto `StringSession`:
|
|
610
|
+
the format version, the data-center number, its address and port, and a 256-byte `authKey`,
|
|
611
|
+
base64-encoded. Neither your password nor the confirmation code is stored there.
|
|
612
|
+
|
|
613
|
+
- The session file and the settings file are written with `0600` permissions — owner read/write only.
|
|
614
|
+
- Neither the session nor the credentials live inside the package: `npm update` does not touch them.
|
|
615
|
+
- `data/` and `.env` are in `.gitignore` and excluded from the npm package via the `files` field;
|
|
616
|
+
`node scripts/check-package.js` fails if a secret ends up in the build anyway.
|
|
617
|
+
- **The `authKey` is stored in the clear**: base64 is an encoding, not encryption.
|
|
618
|
+
Anyone who reads the file gets full access to the account without the phone, the code or 2FA.
|
|
619
|
+
Do not put it in shared folders or unencrypted backups. If the file leaks,
|
|
620
|
+
terminate the session in an official client (*Settings → Devices*) — that revokes the key
|
|
621
|
+
on the server and makes the string useless.
|
|
622
|
+
- `/logout` in the TUI revokes the key on the server and deletes the session file.
|
|
623
|
+
- No data is sent to third-party servers — the client connects directly to the official
|
|
624
|
+
Telegram MTProto servers.
|
|
342
625
|
|
|
343
626
|
---
|
|
344
627
|
|
|
345
|
-
##
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
-
|
|
363
|
-
|
|
364
|
-
|
|
628
|
+
## 📜 Changelog
|
|
629
|
+
|
|
630
|
+
All notable changes are recorded in [CHANGELOG.md](./CHANGELOG.md).
|
|
631
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
632
|
+
and versioning follows [SemVer](https://semver.org/).
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|
|
636
|
+
## 🤝 Contributing
|
|
637
|
+
|
|
638
|
+
Bug reports and pull requests are welcome:
|
|
639
|
+
[issues](https://github.com/emaxe/tuigram/issues).
|
|
640
|
+
|
|
641
|
+
Before submitting changes:
|
|
642
|
+
|
|
643
|
+
```bash
|
|
644
|
+
npm test # unit tests must be green
|
|
645
|
+
node scripts/check-package.js # .env and the session must not reach the package
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
Codebase rules for humans and AI agents live in [AGENTS.md](./AGENTS.md) — the single
|
|
649
|
+
source of truth for architecture, style, testing and security. If you work with
|
|
650
|
+
Claude Code, Cursor or Copilot, start there.
|
|
651
|
+
|
|
652
|
+
Both README versions (`README.md` and `README.ru.md`) must be updated together.
|
|
653
|
+
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
## 📄 License
|
|
657
|
+
|
|
658
|
+
[MIT](./LICENSE) © Maksim Klisin
|
|
659
|
+
|
|
660
|
+
TuiGram is an unofficial client. The project is not affiliated with,
|
|
661
|
+
nor endorsed by, Telegram Messenger Inc.
|