telegram-cli-local 0.1.0__tar.gz → 0.2.1__tar.gz
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.
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/.agents/skills/telegram-cli/SKILL.md +110 -92
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/.claude/skills/telegram-cli/SKILL.md +110 -92
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/AGENTS.md +2 -2
- telegram_cli_local-0.2.1/CHANGELOG.md +70 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/CLAUDE.md +2 -2
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/MANIFEST.in +1 -0
- {telegram_cli_local-0.1.0/telegram_cli_local.egg-info → telegram_cli_local-0.2.1}/PKG-INFO +162 -11
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/README.md +161 -10
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/README.ru.md +168 -10
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/RELEASING.md +4 -3
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/scripts/check_distribution.py +2 -1
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/tcli_skills/SKILL.md +110 -92
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/tcli_skills/__init__.py +1 -1
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1/telegram_cli_local.egg-info}/PKG-INFO +162 -11
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/telegram_cli_local.egg-info/SOURCES.txt +1 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/tests/test_tg.py +528 -3
- telegram_cli_local-0.2.1/tg.py +724 -0
- telegram_cli_local-0.1.0/tg.py +0 -418
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/LICENSE +0 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/pyproject.toml +0 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/requirements.txt +0 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/setup.cfg +0 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/telegram_cli_local.egg-info/dependency_links.txt +0 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/telegram_cli_local.egg-info/entry_points.txt +0 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/telegram_cli_local.egg-info/requires.txt +0 -0
- {telegram_cli_local-0.1.0 → telegram_cli_local-0.2.1}/telegram_cli_local.egg-info/top_level.txt +0 -0
|
@@ -1,90 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: telegram-cli
|
|
3
|
-
description:
|
|
3
|
+
description: Use the personal-account Telegram CLI (tcli). Use for chats, message search/history, plain or formatted sending, JSON automation, watching, configuration, login, and diagnostics.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Telegram CLI
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Use the installed `tcli` command from any directory. Run development and installation commands from the project root.
|
|
12
|
-
Respond in the user's requested language; English CLI output does not require English conversation replies.
|
|
13
|
-
Keep the Codex, Claude Code, and bundled `tcli_skills/SKILL.md` copies identical when updating them.
|
|
14
|
-
|
|
15
|
-
## Project map
|
|
16
|
-
|
|
17
|
-
A local Python 3.10+ CLI for one personal Telegram account, using Telethon and MTProto.
|
|
18
|
-
No bot, HTTP server, application database, or FTP deployment is involved.
|
|
19
|
-
|
|
20
|
-
| Location | Responsibility |
|
|
21
|
-
| --- | --- |
|
|
22
|
-
| `tg.py: parser()` | argparse commands, help text, examples, limits |
|
|
23
|
-
| `tg.py: main()` | Help dispatch before credentials, paths, errors, asyncio entry point |
|
|
24
|
-
| `validate_credentials()` / `load_credentials()` / `configure()` | Validate credentials, environment/file precedence, atomic local configuration |
|
|
25
|
-
| `run()` | Connect, authenticate, execute commands, disconnect in finally |
|
|
26
|
-
| `resolve_chat()` | me/@username via Telethon; numeric IDs and exact titles via dialogs |
|
|
27
|
-
| `safe_text()` / `show_message()` | Strip terminal control characters and display messages |
|
|
28
|
-
| `message_data()` | Serialize message fields for JSON and JSONL output |
|
|
29
|
-
| `install_skills()` / `atomic_write()` | Offline user-skill installation, backups, and atomic file replacement |
|
|
30
|
-
| `tcli_skills/` | Version and bundled portable SKILL.md included in wheels |
|
|
31
|
-
| `pyproject.toml` | `tcli` entry point calling `tg:main`; dependencies from requirements.txt |
|
|
32
|
-
| `tests/test_tg.py` | Offline unit tests and help subprocess checks |
|
|
33
|
-
| `README.md` / `README.ru.md` | English and Russian user documentation |
|
|
34
|
-
|
|
35
|
-
Use Semble to locate implementations when available, then read the matching functions and callers.
|
|
36
|
-
Current code and command help take precedence over stale documentation.
|
|
37
|
-
The CLI, developer documentation, and agent instructions are English; preserve Unicode chat names and messages.
|
|
8
|
+
Use `tcli` to work with the user's personal Telegram account from any directory.
|
|
9
|
+
Respond in the user's requested language; CLI output is English.
|
|
10
|
+
Use `tcli help COMMAND` to check available options.
|
|
38
11
|
|
|
39
12
|
## Setup
|
|
40
13
|
|
|
41
14
|
Install the published CLI with `pipx install telegram-cli-local`.
|
|
42
15
|
Update it with `pipx upgrade telegram-cli-local`, then run `tcli skills install` to update user skills.
|
|
43
|
-
|
|
44
|
-
`tcli --version` reports the CLI version.
|
|
45
|
-
|
|
46
|
-
Install from this local project with `py -m pip install --user -e .` on Windows.
|
|
47
|
-
The user scripts directory must be in PATH. If tcli is not found, run in PowerShell:
|
|
48
|
-
|
|
49
|
-
```powershell
|
|
50
|
-
$tcliScriptsDir = (py -c "import sysconfig; print(sysconfig.get_path('scripts', scheme='nt_user'))").Trim()
|
|
51
|
-
$tcliUserPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
|
52
|
-
if (($tcliUserPath -split ';') -notcontains $tcliScriptsDir) {
|
|
53
|
-
$tcliUpdatedPath = (($tcliUserPath + ';' + $tcliScriptsDir).Trim(';'))
|
|
54
|
-
[Environment]::SetEnvironmentVariable('Path', $tcliUpdatedPath, 'User')
|
|
55
|
-
}
|
|
56
|
-
$env:Path = $tcliScriptsDir + ';' + $env:Path
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
New terminals inherit the saved PATH; restart existing terminals or their parent application if needed.
|
|
60
|
-
If pip is missing, run `py -m ensurepip --upgrade --user` before installing.
|
|
61
|
-
Do not install an unrelated similarly named package from PyPI.
|
|
62
|
-
Editable installation depends on the source folder; reinstall if it moves.
|
|
63
|
-
The installed `tcli` command works outside the project root.
|
|
64
|
-
|
|
65
|
-
For development, run from the project root:
|
|
66
|
-
|
|
67
|
-
```powershell
|
|
68
|
-
py -m venv .venv
|
|
69
|
-
.\.venv\Scripts\python.exe -m pip install -e .
|
|
70
|
-
.\.venv\Scripts\tcli.exe help
|
|
71
|
-
.\.venv\Scripts\python.exe -X utf8 -m unittest discover -s tests -v
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
On POSIX use `python3 -m venv .venv`, `.venv/bin/python`, and `.venv/bin/tcli`.
|
|
75
|
-
No activation is needed with those explicit paths.
|
|
76
|
-
On this Windows machine, `py` is available; the system `python` alias may open Microsoft Store.
|
|
77
|
-
If an agent process has an old PATH, refresh its environment or use the installed executable's full path.
|
|
16
|
+
`tcli --version` reports the installed version.
|
|
78
17
|
|
|
79
18
|
## Help and commands
|
|
80
19
|
|
|
81
20
|
`tcli`, `tcli help`, `tcli --help`, and `tcli -h` display general help and exit successfully.
|
|
82
21
|
`tcli help send` is equivalent to `tcli send --help`; this applies to every subcommand.
|
|
83
22
|
Help does not load credentials, create Telegram sessions, or connect to Telegram.
|
|
84
|
-
Interactive general help
|
|
85
|
-
It uses a one-second network timeout and a 24-hour cache at data-directory/cache/update-check.json,
|
|
86
|
-
including failed attempts. It only reports updates on stderr, never installs them automatically.
|
|
87
|
-
Network/cache errors are silent. Redirected stdout, command-specific help, and --version skip checks.
|
|
23
|
+
Interactive general help may report a newer release on stderr; it never installs updates automatically.
|
|
88
24
|
Set TCLI_NO_UPDATE_CHECK=1 to disable checks and their cache writes entirely.
|
|
89
25
|
Unknown commands, unknown help topics, and invalid arguments remain usage errors (exit 2).
|
|
90
26
|
|
|
@@ -98,6 +34,15 @@ Unknown commands, unknown help topics, and invalid arguments remain usage errors
|
|
|
98
34
|
| `tcli send me "Text"` | Send literal text to Saved Messages |
|
|
99
35
|
| `tcli send @username "Text"` | Send to a username |
|
|
100
36
|
| `tcli send -- -1001234567890 "Text"` | Send by negative ID |
|
|
37
|
+
| `tcli send me --attach photo.jpg --caption "Photo"` | Upload a photo, video, audio, or any Telegram-supported local file |
|
|
38
|
+
| `tcli send me --attach archive.zip --as-file` | Force document upload; preserve the original file |
|
|
39
|
+
| `tcli download me 123 --output photo.jpg` | Download the attachment from message 123 into a new local file |
|
|
40
|
+
| `tcli read "Chat" --id 123 --json` | Get one message with reply and album IDs |
|
|
41
|
+
| `tcli read "Chat" --media document --json` | Filter media using Telegram search |
|
|
42
|
+
| `tcli send me --attach app.apk archive.zip --caption "App" --caption "Archive" --json` | Send files individually in order |
|
|
43
|
+
| `tcli send me --attach first.jpg second.jpg --album --json` | Send 2-10 compatible attachments as one album |
|
|
44
|
+
| `tcli download me 123 --album --output-dir downloads --json` | Download the album containing message 123 |
|
|
45
|
+
| `tcli edit me 123 "Corrected text" --json` | Edit outgoing message text or attachment caption |
|
|
101
46
|
| `tcli watch "Chat name"` | New messages until Ctrl+C; blocks the process |
|
|
102
47
|
| `tcli logout` | Revoke this CLI session and remove its session file; keep API credentials |
|
|
103
48
|
| `tcli doctor` | Validate effective credentials and session-file presence locally; show paths, never secret values |
|
|
@@ -119,16 +64,37 @@ Increase `chats --limit` if necessary. Do not invent IDs. Partial names and t.me
|
|
|
119
64
|
Limits must be positive integers. `read` does not mark messages as read.
|
|
120
65
|
|
|
121
66
|
Message output: `[local date and time] sender ID or you (#message ID): text`.
|
|
122
|
-
|
|
67
|
+
Downloadable media displays its type, filename (if available), MIME type, and size in bytes, alongside any caption.
|
|
68
|
+
Other messages without text display `[media or service message]`.
|
|
123
69
|
Human-readable output removes control characters. Optional JSON preserves original text using escaped
|
|
124
70
|
Unicode/control characters. Chat fields: id, name, unread_count. Message fields: id, chat_id,
|
|
125
|
-
date (ISO 8601 with offset), sender_id (nullable), out, text (empty when absent), has_media.
|
|
71
|
+
date (ISO 8601 with offset), sender_id (nullable), out, text (empty when absent), has_media, media, reply_to_id, grouped_id.
|
|
72
|
+
reply_to_id and grouped_id are null when absent; human output also shows these IDs.
|
|
73
|
+
Use read --id with reply_to_id to retrieve the original message of a reply.
|
|
74
|
+
`media` is null for messages without a downloadable photo/document; otherwise it contains
|
|
75
|
+
type (photo, video, audio, voice, video_note, gif, sticker, document), name, mime_type, size (bytes),
|
|
76
|
+
ext, width, height, duration (seconds). Unavailable metadata fields are null.
|
|
77
|
+
Link previews and other Telegram media may have has_media=true with media=null.
|
|
126
78
|
`chats --json` and `read --json` output arrays, including [] for no results.
|
|
127
79
|
`watch --json` outputs JSONL with status/errors only on stderr.
|
|
128
80
|
`read --search QUERY` uses Telegram text search in the selected chat; each page is oldest first.
|
|
129
81
|
`--before ID` is exclusive; use the smallest returned ID for the next page, also with search.
|
|
130
82
|
`--before` and `--reply-to` require positive message IDs from the same chat.
|
|
131
|
-
`send` requires exactly one
|
|
83
|
+
`send` requires exactly one source: positional text, --stdin, --file PATH, or --attach PATH.
|
|
84
|
+
Text sources must be nonempty. --attach uploads one or more existing local files per command,
|
|
85
|
+
including binary documents such as .exe, .apk, .zip; attachments are never decoded as text.
|
|
86
|
+
Telethon selects photo/video/audio/document representation; --as-file forces a document.
|
|
87
|
+
--caption supplies optional text with --attach only; --as-file and --album also require --attach.
|
|
88
|
+
Repeat --caption in attachment order; missing captions are empty. Use --caption "" to skip one.
|
|
89
|
+
Without --album, files are sent individually in order. --album sends 2-10 compatible attachments
|
|
90
|
+
as a group via Telethon; incompatible Telegram album combinations may produce RPC errors.
|
|
91
|
+
A single caption belongs to the first attachment. All paths and caption counts are checked before connecting.
|
|
92
|
+
Captions support --format and --reply-to. File type and size limits are enforced by Telegram.
|
|
93
|
+
`download CHAT ID --output PATH` saves the attachment of one message in that chat.
|
|
94
|
+
Use IDs from read/watch. The destination parent must exist; existing files are never overwritten.
|
|
95
|
+
Remote filenames are metadata only and never select a local path. Failed/cancelled downloads remove
|
|
96
|
+
the partial destination. Download photos are Telegram's stored version, not necessarily the original.
|
|
97
|
+
To view the content, open the downloaded file with a local application; the CLI displays metadata.
|
|
132
98
|
Stdin/files use UTF-8 with optional BOM; whitespace and line breaks are preserved, blank input rejected
|
|
133
99
|
before connecting. PowerShell pipelines must emit UTF-8 (set $OutputEncoding if necessary).
|
|
134
100
|
--file sends text, not an attachment. All sources support --reply-to ID and --format plain|markdown|html.
|
|
@@ -138,19 +104,81 @@ HTML supports b/strong, i/em, u, s/del, code, pre, a href, blockquote (including
|
|
|
138
104
|
and pre/code class="language-python" for code-block language. Use actual newlines, not br tags.
|
|
139
105
|
The installed Telethon parser ignores unsupported HTML tags and does not support spoiler markup.
|
|
140
106
|
Formatting may trim surrounding whitespace. Use HTML for nested formatting.
|
|
141
|
-
No
|
|
107
|
+
No message deletion or interactive conversation UI.
|
|
142
108
|
`doctor` is local, creates no files, and exits 1 for invalid credentials or missing session.
|
|
143
109
|
File presence does not prove authorization. --connect can update the existing Telethon session.
|
|
144
|
-
`watch`
|
|
145
|
-
min_id and reverse order with no fixed batch limit. It includes sends from another CLI process
|
|
146
|
-
and Saved Messages. Session writes are committed before idle waits to release SQLite locks.
|
|
110
|
+
`watch` shows new messages, including sends from another CLI process and Saved Messages.
|
|
147
111
|
Messages deleted before polling cannot be seen. `watch` has no past history; prefer `read` for a one-time request.
|
|
148
112
|
|
|
113
|
+
## Automation, context, filters, and editing
|
|
114
|
+
|
|
115
|
+
`read CHAT --id ID` fetches one message or fails with message_not_found. JSON remains an array
|
|
116
|
+
with one item. --id cannot combine with --around, --before, or search/media/filename filters; --limit applies only to history.
|
|
117
|
+
`read --media photo|video|document|audio|voice|video_note|gif` uses native Telegram filters;
|
|
118
|
+
audio means music. Filters combine with --search, --before, and --limit.
|
|
119
|
+
Search follows Telegram text-search semantics, not local filename/extension matching.
|
|
120
|
+
|
|
121
|
+
`edit CHAT ID TEXT`, `edit CHAT ID --file PATH`, or `edit CHAT ID --stdin` edits outgoing text
|
|
122
|
+
or a caption. Exactly one nonblank UTF-8 text source is required. --format plain|markdown|html
|
|
123
|
+
works as for send. Use a message ID from history and check that the message is outgoing before editing.
|
|
124
|
+
Telegram enforces edit permissions and time limits; unchanged text can raise an RPC error.
|
|
125
|
+
Editing does not replace attachments or clear captions with empty text.
|
|
126
|
+
|
|
127
|
+
`download CHAT ID --album --output-dir DIR` downloads the album containing that message.
|
|
128
|
+
--output-dir requires --album, excludes --output, and must already exist.
|
|
129
|
+
Telegram albums have at most ten items; message IDs can have gaps.
|
|
130
|
+
Save as <message_id><extension>, with .bin for missing/unsafe extensions; never use remote filenames.
|
|
131
|
+
Existing destination files are never overwritten.
|
|
132
|
+
Keep completed files on failure and remove the current partial file. Missing/deleted/inaccessible
|
|
133
|
+
album items cannot be recovered. Download JSON keeps captions and grouped_id without sidecar files.
|
|
134
|
+
|
|
135
|
+
With --json, send outputs {"ok": true, "messages": [message objects]}, edit outputs
|
|
136
|
+
{"ok": true, "message": message object}, and download outputs {"ok": true, "files": [file objects]}.
|
|
137
|
+
File fields: message_id, chat_id, path (absolute), text (caption), grouped_id (nullable).
|
|
138
|
+
chats/read arrays and watch JSONL keep their existing shapes, with the added message fields.
|
|
139
|
+
|
|
140
|
+
Handled errors for commands with --json go to stderr as one JSON object:
|
|
141
|
+
{"ok": false, "error": {"code": "flood_wait", "message": "...", "retry_after": 17}}.
|
|
142
|
+
retry_after is seconds for FloodWait, null otherwise. RPC errors include rpc_type and rpc_code.
|
|
143
|
+
Codes: usage_error, invalid_input, configuration_error, unauthorized, chat_not_found, ambiguous_chat,
|
|
144
|
+
message_not_found, not_outgoing, edit_failed, not_an_album, no_attachment, file_exists, flood_wait,
|
|
145
|
+
rpc_error, network_error, io_error, database_error, cancelled.
|
|
146
|
+
Argument errors exit 2; handled failures exit 1; interruption exits 130. Watch status stays plain text
|
|
147
|
+
on stderr. After a partial operation, error JSON includes messages/files with confirmed completed results.
|
|
148
|
+
Do not automatically retry uncertain send/edit failures: inspect history to avoid duplicate actions.
|
|
149
|
+
|
|
150
|
+
## Filename search, surrounding context, forwarding, and progress
|
|
151
|
+
|
|
152
|
+
`read CHAT --filename "*.apk" --scan-limit 1000 --limit 5 --json` matches original attachment
|
|
153
|
+
names locally with case-insensitive glob patterns (*, ?, [abc]). Messages without names are skipped.
|
|
154
|
+
--scan-limit (default 1000) bounds the newest messages inspected after Telegram search/media filters;
|
|
155
|
+
--limit bounds matches. Results stay oldest first. Combine with --before, --search, or --media.
|
|
156
|
+
No matches in the bounded scan do not prove absence across the whole chat. --scan-limit requires --filename.
|
|
157
|
+
|
|
158
|
+
`read CHAT --around ID --context N` fetches the selected message and up to N neighbors on each side
|
|
159
|
+
(default 5), ordered chronologically. IDs need not be consecutive. Missing anchor: message_not_found.
|
|
160
|
+
--around excludes --id, --before, --search, --media, --filename, and --scan-limit.
|
|
161
|
+
--context requires --around. --limit only applies to history and filename search.
|
|
162
|
+
|
|
163
|
+
`forward FROM_CHAT ID TO_CHAT [--json]` forwards one message, attachment and caption included,
|
|
164
|
+
using native Telegram forwarding without local download/upload. Standard chat selectors apply on
|
|
165
|
+
both sides. Preserve attribution. Telegram enforces protected-content and posting restrictions.
|
|
166
|
+
JSON success uses the send shape: {"ok": true, "messages": [message object]}.
|
|
167
|
+
Forward only on explicit user instruction with known source, message ID, and destination.
|
|
168
|
+
Development/testing does not authorize live forwarding. Verify history before retrying an uncertain failure.
|
|
169
|
+
|
|
170
|
+
send (attachments only) and download support --progress / --no-progress.
|
|
171
|
+
Default: enabled when stderr is a terminal. Progress reports bytes, percentage, and average bytes/sec
|
|
172
|
+
on stderr. With --json, progress is JSONL on stderr:
|
|
173
|
+
event="transfer_progress", operation="upload"|"download", file, transferred_bytes, total_bytes,
|
|
174
|
+
percent (null for unknown/zero size), bytes_per_second. Errors have ok=false and may follow progress events.
|
|
175
|
+
Stdout remains the final JSON result. Progress is not proof of delivery; cached transfers may emit no events.
|
|
176
|
+
|
|
149
177
|
## Common workflows
|
|
150
178
|
|
|
151
179
|
`skills install` defaults to --agent auto: detect installed agents and copy the bundled skill only for those agents.
|
|
152
|
-
|
|
153
|
-
|
|
180
|
+
Default destinations are the official personal skill locations, independent of the current directory:
|
|
181
|
+
Codex: ~/.agents/skills/telegram-cli/SKILL.md; Claude Code: ~/.claude/skills/telegram-cli/SKILL.md.
|
|
154
182
|
If neither agent is found, it creates nothing. Explicit --agent codex|claude|all bypasses detection for custom installations.
|
|
155
183
|
The installer never downloads anything or launches either agent.
|
|
156
184
|
It skips identical files, backs up differing SKILL.md files as SKILL.md.backup-*.bak, and atomically
|
|
@@ -195,7 +223,9 @@ The user enters login code and 2FA password in their terminal; agent sessions mu
|
|
|
195
223
|
Account commands fail when unauthorized rather than automatically prompting for login.
|
|
196
224
|
|
|
197
225
|
Read only chats needed for the user's request; do not store private conversations in project files.
|
|
198
|
-
Send only on the user's direct instruction with a known recipient
|
|
226
|
+
Send, forward, or edit only on the user's direct instruction with a known recipient, message ID where needed,
|
|
227
|
+
and text or attachment. Development requests do not authorize live sends or edits.
|
|
228
|
+
Download only requested attachments into the requested local location; never execute downloaded files.
|
|
199
229
|
An unambiguous prior instruction needs no extra confirmation. A development/test request does not authorize sending, even to `me`.
|
|
200
230
|
Clarify ambiguous recipients before sending. Use correct shell quoting to pass text as one argument;
|
|
201
231
|
never interpolate untrusted messages as executable shell code. JSON.stringify is not shell escaping.
|
|
@@ -211,16 +241,4 @@ Missing authorization: suggest local `tcli login`.
|
|
|
211
241
|
FloodWait: wait the reported duration; do not bypass limits or retry immediately.
|
|
212
242
|
RPC/network errors: address the specific cause; a send may have an uncertain outcome.
|
|
213
243
|
SQLite locking: investigate other CLI processes; do not delete the session file.
|
|
214
|
-
`Could not find platform independent libraries <prefix>`: Python installation/path warning before application startup.
|
|
215
|
-
Inspect the interpreter and its standard library; repair the installation rather than suppressing stderr or changing Telegram code.
|
|
216
244
|
Exit codes: 0 success, 1 handled error, 2 argparse usage error, 130 Ctrl+C.
|
|
217
|
-
Telethon may perform internal retries; the CLI has no custom send retry loop.
|
|
218
|
-
|
|
219
|
-
Preserve credential validation, authorization checks, unambiguous chat resolution,
|
|
220
|
-
terminal sanitization, literal outgoing text by default, disconnect in finally, and FloodWait handling.
|
|
221
|
-
Update affected tests, both READMEs, and all three copies of this SKILL.md when changing commands.
|
|
222
|
-
Tests cover help without credentials, JSON/JSONL, search/pagination arguments, replies, stdin/files,
|
|
223
|
-
doctor, login/logout, watch polling/cursors and cancellation, formatting selection, disconnects
|
|
224
|
-
and handled errors including FloodWait and SQLite locks.
|
|
225
|
-
They do not verify real login,
|
|
226
|
-
network watching, or message delivery. State those limits when reporting validation.
|
|
@@ -1,90 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: telegram-cli
|
|
3
|
-
description:
|
|
3
|
+
description: Use the personal-account Telegram CLI (tcli). Use for chats, message search/history, plain or formatted sending, JSON automation, watching, configuration, login, and diagnostics.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Telegram CLI
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Use the installed `tcli` command from any directory. Run development and installation commands from the project root.
|
|
12
|
-
Respond in the user's requested language; English CLI output does not require English conversation replies.
|
|
13
|
-
Keep the Codex, Claude Code, and bundled `tcli_skills/SKILL.md` copies identical when updating them.
|
|
14
|
-
|
|
15
|
-
## Project map
|
|
16
|
-
|
|
17
|
-
A local Python 3.10+ CLI for one personal Telegram account, using Telethon and MTProto.
|
|
18
|
-
No bot, HTTP server, application database, or FTP deployment is involved.
|
|
19
|
-
|
|
20
|
-
| Location | Responsibility |
|
|
21
|
-
| --- | --- |
|
|
22
|
-
| `tg.py: parser()` | argparse commands, help text, examples, limits |
|
|
23
|
-
| `tg.py: main()` | Help dispatch before credentials, paths, errors, asyncio entry point |
|
|
24
|
-
| `validate_credentials()` / `load_credentials()` / `configure()` | Validate credentials, environment/file precedence, atomic local configuration |
|
|
25
|
-
| `run()` | Connect, authenticate, execute commands, disconnect in finally |
|
|
26
|
-
| `resolve_chat()` | me/@username via Telethon; numeric IDs and exact titles via dialogs |
|
|
27
|
-
| `safe_text()` / `show_message()` | Strip terminal control characters and display messages |
|
|
28
|
-
| `message_data()` | Serialize message fields for JSON and JSONL output |
|
|
29
|
-
| `install_skills()` / `atomic_write()` | Offline user-skill installation, backups, and atomic file replacement |
|
|
30
|
-
| `tcli_skills/` | Version and bundled portable SKILL.md included in wheels |
|
|
31
|
-
| `pyproject.toml` | `tcli` entry point calling `tg:main`; dependencies from requirements.txt |
|
|
32
|
-
| `tests/test_tg.py` | Offline unit tests and help subprocess checks |
|
|
33
|
-
| `README.md` / `README.ru.md` | English and Russian user documentation |
|
|
34
|
-
|
|
35
|
-
Use Semble to locate implementations when available, then read the matching functions and callers.
|
|
36
|
-
Current code and command help take precedence over stale documentation.
|
|
37
|
-
The CLI, developer documentation, and agent instructions are English; preserve Unicode chat names and messages.
|
|
8
|
+
Use `tcli` to work with the user's personal Telegram account from any directory.
|
|
9
|
+
Respond in the user's requested language; CLI output is English.
|
|
10
|
+
Use `tcli help COMMAND` to check available options.
|
|
38
11
|
|
|
39
12
|
## Setup
|
|
40
13
|
|
|
41
14
|
Install the published CLI with `pipx install telegram-cli-local`.
|
|
42
15
|
Update it with `pipx upgrade telegram-cli-local`, then run `tcli skills install` to update user skills.
|
|
43
|
-
|
|
44
|
-
`tcli --version` reports the CLI version.
|
|
45
|
-
|
|
46
|
-
Install from this local project with `py -m pip install --user -e .` on Windows.
|
|
47
|
-
The user scripts directory must be in PATH. If tcli is not found, run in PowerShell:
|
|
48
|
-
|
|
49
|
-
```powershell
|
|
50
|
-
$tcliScriptsDir = (py -c "import sysconfig; print(sysconfig.get_path('scripts', scheme='nt_user'))").Trim()
|
|
51
|
-
$tcliUserPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
|
52
|
-
if (($tcliUserPath -split ';') -notcontains $tcliScriptsDir) {
|
|
53
|
-
$tcliUpdatedPath = (($tcliUserPath + ';' + $tcliScriptsDir).Trim(';'))
|
|
54
|
-
[Environment]::SetEnvironmentVariable('Path', $tcliUpdatedPath, 'User')
|
|
55
|
-
}
|
|
56
|
-
$env:Path = $tcliScriptsDir + ';' + $env:Path
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
New terminals inherit the saved PATH; restart existing terminals or their parent application if needed.
|
|
60
|
-
If pip is missing, run `py -m ensurepip --upgrade --user` before installing.
|
|
61
|
-
Do not install an unrelated similarly named package from PyPI.
|
|
62
|
-
Editable installation depends on the source folder; reinstall if it moves.
|
|
63
|
-
The installed `tcli` command works outside the project root.
|
|
64
|
-
|
|
65
|
-
For development, run from the project root:
|
|
66
|
-
|
|
67
|
-
```powershell
|
|
68
|
-
py -m venv .venv
|
|
69
|
-
.\.venv\Scripts\python.exe -m pip install -e .
|
|
70
|
-
.\.venv\Scripts\tcli.exe help
|
|
71
|
-
.\.venv\Scripts\python.exe -X utf8 -m unittest discover -s tests -v
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
On POSIX use `python3 -m venv .venv`, `.venv/bin/python`, and `.venv/bin/tcli`.
|
|
75
|
-
No activation is needed with those explicit paths.
|
|
76
|
-
On this Windows machine, `py` is available; the system `python` alias may open Microsoft Store.
|
|
77
|
-
If an agent process has an old PATH, refresh its environment or use the installed executable's full path.
|
|
16
|
+
`tcli --version` reports the installed version.
|
|
78
17
|
|
|
79
18
|
## Help and commands
|
|
80
19
|
|
|
81
20
|
`tcli`, `tcli help`, `tcli --help`, and `tcli -h` display general help and exit successfully.
|
|
82
21
|
`tcli help send` is equivalent to `tcli send --help`; this applies to every subcommand.
|
|
83
22
|
Help does not load credentials, create Telegram sessions, or connect to Telegram.
|
|
84
|
-
Interactive general help
|
|
85
|
-
It uses a one-second network timeout and a 24-hour cache at data-directory/cache/update-check.json,
|
|
86
|
-
including failed attempts. It only reports updates on stderr, never installs them automatically.
|
|
87
|
-
Network/cache errors are silent. Redirected stdout, command-specific help, and --version skip checks.
|
|
23
|
+
Interactive general help may report a newer release on stderr; it never installs updates automatically.
|
|
88
24
|
Set TCLI_NO_UPDATE_CHECK=1 to disable checks and their cache writes entirely.
|
|
89
25
|
Unknown commands, unknown help topics, and invalid arguments remain usage errors (exit 2).
|
|
90
26
|
|
|
@@ -98,6 +34,15 @@ Unknown commands, unknown help topics, and invalid arguments remain usage errors
|
|
|
98
34
|
| `tcli send me "Text"` | Send literal text to Saved Messages |
|
|
99
35
|
| `tcli send @username "Text"` | Send to a username |
|
|
100
36
|
| `tcli send -- -1001234567890 "Text"` | Send by negative ID |
|
|
37
|
+
| `tcli send me --attach photo.jpg --caption "Photo"` | Upload a photo, video, audio, or any Telegram-supported local file |
|
|
38
|
+
| `tcli send me --attach archive.zip --as-file` | Force document upload; preserve the original file |
|
|
39
|
+
| `tcli download me 123 --output photo.jpg` | Download the attachment from message 123 into a new local file |
|
|
40
|
+
| `tcli read "Chat" --id 123 --json` | Get one message with reply and album IDs |
|
|
41
|
+
| `tcli read "Chat" --media document --json` | Filter media using Telegram search |
|
|
42
|
+
| `tcli send me --attach app.apk archive.zip --caption "App" --caption "Archive" --json` | Send files individually in order |
|
|
43
|
+
| `tcli send me --attach first.jpg second.jpg --album --json` | Send 2-10 compatible attachments as one album |
|
|
44
|
+
| `tcli download me 123 --album --output-dir downloads --json` | Download the album containing message 123 |
|
|
45
|
+
| `tcli edit me 123 "Corrected text" --json` | Edit outgoing message text or attachment caption |
|
|
101
46
|
| `tcli watch "Chat name"` | New messages until Ctrl+C; blocks the process |
|
|
102
47
|
| `tcli logout` | Revoke this CLI session and remove its session file; keep API credentials |
|
|
103
48
|
| `tcli doctor` | Validate effective credentials and session-file presence locally; show paths, never secret values |
|
|
@@ -119,16 +64,37 @@ Increase `chats --limit` if necessary. Do not invent IDs. Partial names and t.me
|
|
|
119
64
|
Limits must be positive integers. `read` does not mark messages as read.
|
|
120
65
|
|
|
121
66
|
Message output: `[local date and time] sender ID or you (#message ID): text`.
|
|
122
|
-
|
|
67
|
+
Downloadable media displays its type, filename (if available), MIME type, and size in bytes, alongside any caption.
|
|
68
|
+
Other messages without text display `[media or service message]`.
|
|
123
69
|
Human-readable output removes control characters. Optional JSON preserves original text using escaped
|
|
124
70
|
Unicode/control characters. Chat fields: id, name, unread_count. Message fields: id, chat_id,
|
|
125
|
-
date (ISO 8601 with offset), sender_id (nullable), out, text (empty when absent), has_media.
|
|
71
|
+
date (ISO 8601 with offset), sender_id (nullable), out, text (empty when absent), has_media, media, reply_to_id, grouped_id.
|
|
72
|
+
reply_to_id and grouped_id are null when absent; human output also shows these IDs.
|
|
73
|
+
Use read --id with reply_to_id to retrieve the original message of a reply.
|
|
74
|
+
`media` is null for messages without a downloadable photo/document; otherwise it contains
|
|
75
|
+
type (photo, video, audio, voice, video_note, gif, sticker, document), name, mime_type, size (bytes),
|
|
76
|
+
ext, width, height, duration (seconds). Unavailable metadata fields are null.
|
|
77
|
+
Link previews and other Telegram media may have has_media=true with media=null.
|
|
126
78
|
`chats --json` and `read --json` output arrays, including [] for no results.
|
|
127
79
|
`watch --json` outputs JSONL with status/errors only on stderr.
|
|
128
80
|
`read --search QUERY` uses Telegram text search in the selected chat; each page is oldest first.
|
|
129
81
|
`--before ID` is exclusive; use the smallest returned ID for the next page, also with search.
|
|
130
82
|
`--before` and `--reply-to` require positive message IDs from the same chat.
|
|
131
|
-
`send` requires exactly one
|
|
83
|
+
`send` requires exactly one source: positional text, --stdin, --file PATH, or --attach PATH.
|
|
84
|
+
Text sources must be nonempty. --attach uploads one or more existing local files per command,
|
|
85
|
+
including binary documents such as .exe, .apk, .zip; attachments are never decoded as text.
|
|
86
|
+
Telethon selects photo/video/audio/document representation; --as-file forces a document.
|
|
87
|
+
--caption supplies optional text with --attach only; --as-file and --album also require --attach.
|
|
88
|
+
Repeat --caption in attachment order; missing captions are empty. Use --caption "" to skip one.
|
|
89
|
+
Without --album, files are sent individually in order. --album sends 2-10 compatible attachments
|
|
90
|
+
as a group via Telethon; incompatible Telegram album combinations may produce RPC errors.
|
|
91
|
+
A single caption belongs to the first attachment. All paths and caption counts are checked before connecting.
|
|
92
|
+
Captions support --format and --reply-to. File type and size limits are enforced by Telegram.
|
|
93
|
+
`download CHAT ID --output PATH` saves the attachment of one message in that chat.
|
|
94
|
+
Use IDs from read/watch. The destination parent must exist; existing files are never overwritten.
|
|
95
|
+
Remote filenames are metadata only and never select a local path. Failed/cancelled downloads remove
|
|
96
|
+
the partial destination. Download photos are Telegram's stored version, not necessarily the original.
|
|
97
|
+
To view the content, open the downloaded file with a local application; the CLI displays metadata.
|
|
132
98
|
Stdin/files use UTF-8 with optional BOM; whitespace and line breaks are preserved, blank input rejected
|
|
133
99
|
before connecting. PowerShell pipelines must emit UTF-8 (set $OutputEncoding if necessary).
|
|
134
100
|
--file sends text, not an attachment. All sources support --reply-to ID and --format plain|markdown|html.
|
|
@@ -138,19 +104,81 @@ HTML supports b/strong, i/em, u, s/del, code, pre, a href, blockquote (including
|
|
|
138
104
|
and pre/code class="language-python" for code-block language. Use actual newlines, not br tags.
|
|
139
105
|
The installed Telethon parser ignores unsupported HTML tags and does not support spoiler markup.
|
|
140
106
|
Formatting may trim surrounding whitespace. Use HTML for nested formatting.
|
|
141
|
-
No
|
|
107
|
+
No message deletion or interactive conversation UI.
|
|
142
108
|
`doctor` is local, creates no files, and exits 1 for invalid credentials or missing session.
|
|
143
109
|
File presence does not prove authorization. --connect can update the existing Telethon session.
|
|
144
|
-
`watch`
|
|
145
|
-
min_id and reverse order with no fixed batch limit. It includes sends from another CLI process
|
|
146
|
-
and Saved Messages. Session writes are committed before idle waits to release SQLite locks.
|
|
110
|
+
`watch` shows new messages, including sends from another CLI process and Saved Messages.
|
|
147
111
|
Messages deleted before polling cannot be seen. `watch` has no past history; prefer `read` for a one-time request.
|
|
148
112
|
|
|
113
|
+
## Automation, context, filters, and editing
|
|
114
|
+
|
|
115
|
+
`read CHAT --id ID` fetches one message or fails with message_not_found. JSON remains an array
|
|
116
|
+
with one item. --id cannot combine with --around, --before, or search/media/filename filters; --limit applies only to history.
|
|
117
|
+
`read --media photo|video|document|audio|voice|video_note|gif` uses native Telegram filters;
|
|
118
|
+
audio means music. Filters combine with --search, --before, and --limit.
|
|
119
|
+
Search follows Telegram text-search semantics, not local filename/extension matching.
|
|
120
|
+
|
|
121
|
+
`edit CHAT ID TEXT`, `edit CHAT ID --file PATH`, or `edit CHAT ID --stdin` edits outgoing text
|
|
122
|
+
or a caption. Exactly one nonblank UTF-8 text source is required. --format plain|markdown|html
|
|
123
|
+
works as for send. Use a message ID from history and check that the message is outgoing before editing.
|
|
124
|
+
Telegram enforces edit permissions and time limits; unchanged text can raise an RPC error.
|
|
125
|
+
Editing does not replace attachments or clear captions with empty text.
|
|
126
|
+
|
|
127
|
+
`download CHAT ID --album --output-dir DIR` downloads the album containing that message.
|
|
128
|
+
--output-dir requires --album, excludes --output, and must already exist.
|
|
129
|
+
Telegram albums have at most ten items; message IDs can have gaps.
|
|
130
|
+
Save as <message_id><extension>, with .bin for missing/unsafe extensions; never use remote filenames.
|
|
131
|
+
Existing destination files are never overwritten.
|
|
132
|
+
Keep completed files on failure and remove the current partial file. Missing/deleted/inaccessible
|
|
133
|
+
album items cannot be recovered. Download JSON keeps captions and grouped_id without sidecar files.
|
|
134
|
+
|
|
135
|
+
With --json, send outputs {"ok": true, "messages": [message objects]}, edit outputs
|
|
136
|
+
{"ok": true, "message": message object}, and download outputs {"ok": true, "files": [file objects]}.
|
|
137
|
+
File fields: message_id, chat_id, path (absolute), text (caption), grouped_id (nullable).
|
|
138
|
+
chats/read arrays and watch JSONL keep their existing shapes, with the added message fields.
|
|
139
|
+
|
|
140
|
+
Handled errors for commands with --json go to stderr as one JSON object:
|
|
141
|
+
{"ok": false, "error": {"code": "flood_wait", "message": "...", "retry_after": 17}}.
|
|
142
|
+
retry_after is seconds for FloodWait, null otherwise. RPC errors include rpc_type and rpc_code.
|
|
143
|
+
Codes: usage_error, invalid_input, configuration_error, unauthorized, chat_not_found, ambiguous_chat,
|
|
144
|
+
message_not_found, not_outgoing, edit_failed, not_an_album, no_attachment, file_exists, flood_wait,
|
|
145
|
+
rpc_error, network_error, io_error, database_error, cancelled.
|
|
146
|
+
Argument errors exit 2; handled failures exit 1; interruption exits 130. Watch status stays plain text
|
|
147
|
+
on stderr. After a partial operation, error JSON includes messages/files with confirmed completed results.
|
|
148
|
+
Do not automatically retry uncertain send/edit failures: inspect history to avoid duplicate actions.
|
|
149
|
+
|
|
150
|
+
## Filename search, surrounding context, forwarding, and progress
|
|
151
|
+
|
|
152
|
+
`read CHAT --filename "*.apk" --scan-limit 1000 --limit 5 --json` matches original attachment
|
|
153
|
+
names locally with case-insensitive glob patterns (*, ?, [abc]). Messages without names are skipped.
|
|
154
|
+
--scan-limit (default 1000) bounds the newest messages inspected after Telegram search/media filters;
|
|
155
|
+
--limit bounds matches. Results stay oldest first. Combine with --before, --search, or --media.
|
|
156
|
+
No matches in the bounded scan do not prove absence across the whole chat. --scan-limit requires --filename.
|
|
157
|
+
|
|
158
|
+
`read CHAT --around ID --context N` fetches the selected message and up to N neighbors on each side
|
|
159
|
+
(default 5), ordered chronologically. IDs need not be consecutive. Missing anchor: message_not_found.
|
|
160
|
+
--around excludes --id, --before, --search, --media, --filename, and --scan-limit.
|
|
161
|
+
--context requires --around. --limit only applies to history and filename search.
|
|
162
|
+
|
|
163
|
+
`forward FROM_CHAT ID TO_CHAT [--json]` forwards one message, attachment and caption included,
|
|
164
|
+
using native Telegram forwarding without local download/upload. Standard chat selectors apply on
|
|
165
|
+
both sides. Preserve attribution. Telegram enforces protected-content and posting restrictions.
|
|
166
|
+
JSON success uses the send shape: {"ok": true, "messages": [message object]}.
|
|
167
|
+
Forward only on explicit user instruction with known source, message ID, and destination.
|
|
168
|
+
Development/testing does not authorize live forwarding. Verify history before retrying an uncertain failure.
|
|
169
|
+
|
|
170
|
+
send (attachments only) and download support --progress / --no-progress.
|
|
171
|
+
Default: enabled when stderr is a terminal. Progress reports bytes, percentage, and average bytes/sec
|
|
172
|
+
on stderr. With --json, progress is JSONL on stderr:
|
|
173
|
+
event="transfer_progress", operation="upload"|"download", file, transferred_bytes, total_bytes,
|
|
174
|
+
percent (null for unknown/zero size), bytes_per_second. Errors have ok=false and may follow progress events.
|
|
175
|
+
Stdout remains the final JSON result. Progress is not proof of delivery; cached transfers may emit no events.
|
|
176
|
+
|
|
149
177
|
## Common workflows
|
|
150
178
|
|
|
151
179
|
`skills install` defaults to --agent auto: detect installed agents and copy the bundled skill only for those agents.
|
|
152
|
-
|
|
153
|
-
|
|
180
|
+
Default destinations are the official personal skill locations, independent of the current directory:
|
|
181
|
+
Codex: ~/.agents/skills/telegram-cli/SKILL.md; Claude Code: ~/.claude/skills/telegram-cli/SKILL.md.
|
|
154
182
|
If neither agent is found, it creates nothing. Explicit --agent codex|claude|all bypasses detection for custom installations.
|
|
155
183
|
The installer never downloads anything or launches either agent.
|
|
156
184
|
It skips identical files, backs up differing SKILL.md files as SKILL.md.backup-*.bak, and atomically
|
|
@@ -195,7 +223,9 @@ The user enters login code and 2FA password in their terminal; agent sessions mu
|
|
|
195
223
|
Account commands fail when unauthorized rather than automatically prompting for login.
|
|
196
224
|
|
|
197
225
|
Read only chats needed for the user's request; do not store private conversations in project files.
|
|
198
|
-
Send only on the user's direct instruction with a known recipient
|
|
226
|
+
Send, forward, or edit only on the user's direct instruction with a known recipient, message ID where needed,
|
|
227
|
+
and text or attachment. Development requests do not authorize live sends or edits.
|
|
228
|
+
Download only requested attachments into the requested local location; never execute downloaded files.
|
|
199
229
|
An unambiguous prior instruction needs no extra confirmation. A development/test request does not authorize sending, even to `me`.
|
|
200
230
|
Clarify ambiguous recipients before sending. Use correct shell quoting to pass text as one argument;
|
|
201
231
|
never interpolate untrusted messages as executable shell code. JSON.stringify is not shell escaping.
|
|
@@ -211,16 +241,4 @@ Missing authorization: suggest local `tcli login`.
|
|
|
211
241
|
FloodWait: wait the reported duration; do not bypass limits or retry immediately.
|
|
212
242
|
RPC/network errors: address the specific cause; a send may have an uncertain outcome.
|
|
213
243
|
SQLite locking: investigate other CLI processes; do not delete the session file.
|
|
214
|
-
`Could not find platform independent libraries <prefix>`: Python installation/path warning before application startup.
|
|
215
|
-
Inspect the interpreter and its standard library; repair the installation rather than suppressing stderr or changing Telegram code.
|
|
216
244
|
Exit codes: 0 success, 1 handled error, 2 argparse usage error, 130 Ctrl+C.
|
|
217
|
-
Telethon may perform internal retries; the CLI has no custom send retry loop.
|
|
218
|
-
|
|
219
|
-
Preserve credential validation, authorization checks, unambiguous chat resolution,
|
|
220
|
-
terminal sanitization, literal outgoing text by default, disconnect in finally, and FloodWait handling.
|
|
221
|
-
Update affected tests, both READMEs, and all three copies of this SKILL.md when changing commands.
|
|
222
|
-
Tests cover help without credentials, JSON/JSONL, search/pagination arguments, replies, stdin/files,
|
|
223
|
-
doctor, login/logout, watch polling/cursors and cancellation, formatting selection, disconnects
|
|
224
|
-
and handled errors including FloodWait and SQLite locks.
|
|
225
|
-
They do not verify real login,
|
|
226
|
-
network watching, or message delivery. State those limits when reporting validation.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Telegram CLI
|
|
2
2
|
|
|
3
3
|
Local Python CLI for a personal Telegram account, using Telethon. Entry point: `tg.py`.
|
|
4
|
-
Use `.agents/skills/telegram-cli/SKILL.md` for CLI
|
|
5
|
-
|
|
4
|
+
Use `.agents/skills/telegram-cli/SKILL.md` for CLI usage, commands, and operational constraints.
|
|
5
|
+
Keep architecture and development instructions in repository documentation, not in the skill.
|
|
6
6
|
|
|
7
7
|
Offline validation: `.\.venv\Scripts\python.exe -X utf8 -m unittest discover -s tests -v`.
|
|
8
8
|
Development and tests do not require a live account or sending real messages.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable project changes are recorded here. New changes go under `Unreleased`;
|
|
4
|
+
move them into a versioned section when publishing a release.
|
|
5
|
+
|
|
6
|
+
## Unreleased
|
|
7
|
+
|
|
8
|
+
No unreleased changes.
|
|
9
|
+
|
|
10
|
+
## 0.2.1 - 2026-10-18
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Focus the Telegram CLI skill on usage; remove project architecture and development instructions from all three copies.
|
|
15
|
+
|
|
16
|
+
## 0.2.0 - 2026-10-18
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Bounded, case-insensitive filename glob search with `read --filename` and `--scan-limit`.
|
|
21
|
+
- Conversation context with `read --around ID --context N`, using history order even when IDs have gaps.
|
|
22
|
+
- Native forwarding of messages and attachments with `forward FROM_CHAT ID TO_CHAT`, including JSON results.
|
|
23
|
+
- Automatic terminal upload/download progress, explicit `--progress` / `--no-progress`, JSONL progress
|
|
24
|
+
events on stderr, byte counts, percentages, average transfer speed, and size-weighted album progress.
|
|
25
|
+
- Offline regression tests for filename search, context, forwarding restrictions, progress throttling,
|
|
26
|
+
album byte accounting, and clean JSON stdout.
|
|
27
|
+
- Include this changelog in source distributions and check new command help in clean wheel installations.
|
|
28
|
+
|
|
29
|
+
- Upload local photos, videos, audio, and arbitrary binary documents (including
|
|
30
|
+
`.exe`, `.apk`, and `.zip`) with `send --attach`; use `--as-file` to force document upload.
|
|
31
|
+
- Attachment captions with text formatting and reply targets; repeat `--caption`
|
|
32
|
+
to provide a separate caption for each attachment.
|
|
33
|
+
- Send multiple files individually in order, or group 2-10 compatible attachments
|
|
34
|
+
with `send --album`.
|
|
35
|
+
- Download individual attachments by message ID with `download --output` and
|
|
36
|
+
download entire albums with `download --album --output-dir`.
|
|
37
|
+
- Safe downloads: exclusive file creation, collision checks, ID-based album filenames,
|
|
38
|
+
safe extensions, and removal of the current partial file after failure or cancellation.
|
|
39
|
+
- Display attachment type, filename, MIME type, and size in `read` and `watch`;
|
|
40
|
+
expose dimensions, duration, and other metadata in JSON.
|
|
41
|
+
- Read a specific message with `read --id`; include reply and album IDs in message output.
|
|
42
|
+
- Filter history with `read --media photo|video|document|audio|voice|video_note|gif`,
|
|
43
|
+
combined with Telegram text search and pagination.
|
|
44
|
+
- Edit outgoing message text or attachment captions with `edit`, using positional
|
|
45
|
+
text, UTF-8 files, or stdin and optional Markdown/HTML formatting.
|
|
46
|
+
- JSON results for sending, editing, and downloading, including captions and album
|
|
47
|
+
IDs in downloaded-file records.
|
|
48
|
+
- Structured JSON errors on stderr with stable codes, FloodWait retry delays,
|
|
49
|
+
RPC details, and confirmed completed results after partial multi-file operations.
|
|
50
|
+
- Offline tests for binary uploads, metadata, JSON contracts, filters, edits,
|
|
51
|
+
ordered files and albums, validation, safe downloads, cancellation, and partial failures.
|
|
52
|
+
- This changelog and a requirement to update it alongside future changes.
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
|
|
56
|
+
- Explain in both READMEs that the project was created specifically to help AI agents
|
|
57
|
+
manage Telegram chats effectively.
|
|
58
|
+
- Expand English and Russian documentation and synchronize all three bundled/project
|
|
59
|
+
skill copies with the new commands and automation workflows.
|
|
60
|
+
- Clarify the existing official user-skill destinations in installer help and documentation:
|
|
61
|
+
`~/.agents/skills/telegram-cli/SKILL.md` for Codex and
|
|
62
|
+
`~/.claude/skills/telegram-cli/SKILL.md` for Claude Code.
|
|
63
|
+
Default installation still targets detected agents and backs up differing skills.
|
|
64
|
+
|
|
65
|
+
### Compatibility
|
|
66
|
+
|
|
67
|
+
- `send --file` still sends UTF-8 file contents as text; `--attach` uploads binary files.
|
|
68
|
+
- Existing `chats`/`read` JSON arrays and `watch` JSONL retain their shapes, with
|
|
69
|
+
additional message fields. Human-readable output remains the default.
|
|
70
|
+
- Message deletion, inline media playback, and automatic retries remain unsupported.
|