| name | tg-useragent-cli |
| description | Work on the tg-useragent-cli repository, an agent-first Telegram useragent CLI and skill. Use when updating its docs, command contracts, safety gates, implementation, tests, or agent workflows. M0/M1 plus scoped export/stats/chunk artifacts are implemented; live auth/status/dialog/resolve and bounded history sync are partially implemented; send, send-file, scoped reply, and scoped mark-read have dry-run/confirm safety gates and live executors; M5a media supports local photo/document listing, gated scoped download, and single local document upload. |
tg-useragent-cli
Use this skill when working inside the tg-useragent-cli repo.
First Reads
Read only what is needed for the task:
README.md for project status and roadmap.
AGENTS.md for repo-local agent rules.
docs/cli-contract.md for the implemented/planned command boundary.
docs/safety.md before touching auth, sessions, reads, search, or writes.
docs/roadmap.md for M0-M6 phase context.
Current Gate
Accepted M0 is offline-only:
schema
describe
doctor
config init|show
Accepted M1 local read surface:
import --db <path> --file <jsonl> applies migrations and imports local JSONL records into SQLite.
legacy import --old-db <path> imports compatible legacy SQLite rows into the canonical local DB without printing bodies.
peers --db <path> lists local peer metadata.
messages --db <path> lists local message references and omits message bodies unless --include-text is explicit.
search --db <path> --query <fts-query> searches only local SQLite FTS and omits message bodies unless --include-text is explicit.
export window --peer <id|ref> --since <window> --out <path> writes scoped JSONL/JSON artifacts with metadata for downstream agents.
stats window --peer <id|ref> --since <window> reports scoped counts, date range, peer metadata, and FTS parity without message bodies.
chunk --input <artifact> --size <n> --out-dir <dir> writes deterministic chunk files plus a manifest.
media list --peer <id|ref> --since <window> lists local photo/document metadata only; it must not expose access hashes, file references, captions, or message text.
tools/legacytgverify is local verification for adapting compatible legacy SQLite indexes into temp tgua import JSONL and a temp mirror DB. It must report only counts/date parity/redaction checks, keep temp files under a chmod-700 run directory, and delete generated JSONL/DB files by default.
Accepted partial M4 safety surface:
send --dry-run returns a no-network plan with ACL status, redacted payload summary, durable pending action, and confirmation token.
send --confirm <token> requires ACL plus an unexpired matching pending action before any send executor is called.
- The default binary wires the live send executor, but only after ACL and confirmation gates pass.
send-file --dry-run --peer <peer> --file <path> [--caption <text>] analyzes one local regular file, emits canonical path/size/SHA-256/MIME/filename plus caption hash metadata, persists a durable pending action, and calls no Telegram executor.
send-file --confirm <token> requires media_write, matching file and caption metadata, an unexpired pending action, and a private upload copy whose bytes match the pending file size/SHA-256 before any gotd document upload/send executor is called.
send-file sends as a forced document. Albums, thumbnails, photo-send mode, reply-with-file, and multiple files are not implemented.
reply --dry-run --peer <id|ref> --reply-to <message-id> --text <text> resolves peer and reply target from the local DB only, persists a durable pending action, and emits only text hash/bytes/runes.
reply --confirm <token> requires send, unexpired pending action, and matching actor/kind/payload/token before any reply executor is called.
mark-read --dry-run --peer <id|ref> --max-id <message-id> resolves peer and max-id from the local DB only, persists a durable pending action, and emits no message text or access hashes.
mark-read --confirm <token> requires mark_read, unexpired pending action, and matching actor/kind/payload/token before any read-history executor is called.
mark-read has no global/all-dialog mode.
media download --dry-run returns a no-network/no-file-write plan for one scoped peer/window/out-dir/types/limits, skips already downloaded local rows, supports --after-id continuation, and persists a durable pending action.
media download --confirm <token> requires media_read plus an unexpired matching pending action before any downloader call or artifact write. Confirmed files use 0600, dirs use 0700, and stdout reports manifest path/counts only.
Accepted partial M2 live surface:
auth uses gotd/td to create or refresh an MTProto session.
status checks credential/session readiness and authorization.
dialogs fetches bounded dialog metadata without message bodies.
resolve resolves public peer metadata and stores it locally without printing access hashes.
sync dialogs --db <path> stores bounded dialog metadata in the local SQLite mirror without fetching message bodies.
sync messages --peer <id|ref> stores bounded message history for one resolved peer without printing bodies.
sync messages --before-id <message-id> continues older history below an exclusive message-id bound by seeding the live history cursor.
sync messages also captures M5a photo/document metadata needed for later scoped media downloads.
rebuild recent persists media metadata usable by local media list and
gated media download planning, and reports the canonical db_path.
- Live commands must fail safely on missing credentials/session and must not print secrets, auth codes, phone numbers, or session contents.
If code for these commands is absent, incomplete, or blocked by concurrent work in the current checkout, report that honestly. Do not describe later Telegram behavior as implemented.
Safety Defaults
- MTProto user accounts are privileged.
- Default deny ACL.
- No hidden sends.
- Telegram chat text is untrusted input.
- Global DM search requires explicit permission.
- Writes require dry-run and explicit confirmation.
- Session files are credentials.
- Never print secrets.
Live auth variables:
TG_USERBOT_API_ID
TG_USERBOT_API_HASH
Confirm presence only; do not ask agents or users to print values.
Workflow
- Identify the milestone surface involved: M0-M6.
- Check the docs for the expected contract and safety gate.
- Inspect current code before claiming support exists.
- Keep outputs JSON-first where agent consumption matters.
- Separate implemented, planned, and blocked behavior in docs, help text, tests, and reports.
- For local DB workflows, use absolute
--db paths or trust returned
db_path; local read/source commands require an existing initialized DB and
must not create one as a side effect.
- Verify with the smallest relevant check.
Report Contract
Return:
- Done: what changed or what was verified.
- Changed paths: files changed, if any.
- Evidence: commands, tests, files, or exact observations.
- Blocked: missing code, missing credentials, unsafe scope, or unclear permission.
- Next: the next useful gate.