docs(readme): redesenha o README com hero em SVG [skip ci]
This commit is contained in:
1 parent
e24c5c6bba
commit
c972bf0811
2 files changed
+98
-121
No files matched your search
@@ -1,94 +1,79 @@
|
||||
<div align="center">
|
||||
|
||||
# oh-my-pi-telegram
|
||||
<img src="assets/readme/hero.svg" width="100%" alt="oh-my-pi-telegram: drive a live omp session from a private Telegram chat, with /start, the /compact, /next and /stop menu and prompts sent from the phone">
|
||||
|
||||
**A Telegram companion hub for live [Oh My Pi](https://github.com/can1357/oh-my-pi) (`omp`) sessions —
|
||||
queue prompts, stream replies, send files and voice, and supervise your agent from your phone.**
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
[Install](#installation) · [Features](#what-it-does) · [How it works](#how-it-works) · [Limitations](#limitations) · [Development](#development) · [CI/CD](#cicd)
|
||||
|
||||
<img src="screenshot.png" width="520" alt="pi-telegram running in Telegram">
|
||||
[Issues](https://git.evandro.dev.br/evandro/oh-my-pi-telegram/issues) · [Docs](docs/README.md) · [Changelog](CHANGELOG.md) · [Backlog](BACKLOG.md)
|
||||
|
||||
</div>
|
||||
|
||||
> [!NOTE]
|
||||
> **Project status:** fork of [`@llblab/[email protected]`](https://github.com/llblab/pi-telegram/tree/v0.22.0)
|
||||
> (SHA `afe09c5`), repackaged as `@evandrodevbr/oh-my-pi-telegram` and declared as an
|
||||
> `omp` extension. Per [`CHANGELOG.md`](CHANGELOG.md), the fork passes the upstream
|
||||
> gates (typecheck, 1229/1230 tests with one platform-only skip, `npm audit` with 0
|
||||
> vulnerabilities, clean `npm pack --dry-run`). The latest commit adds a design spec
|
||||
> for an OMP 17 status-bar segment ([`docs/superpowers/specs/`](docs/superpowers/specs/2026-07-15-telegram-omp-status-design.md));
|
||||
> that spec needs a new OMP core API and is **not implemented in this repository yet**.
|
||||

|
||||
|
||||
> [!IMPORTANT]
|
||||
> **This is a runtime adapter, not a remote terminal.** Telegram prompts are normal
|
||||
> model turns in the instance's *currently active* session and inherit its
|
||||
> post-compaction context, so token cost is not proportional only to the new mobile
|
||||
> message. Telegram can compact the current session, but cannot create, resume, fork,
|
||||
> browse or switch sessions, and arbitrary slash commands are never forwarded to the TUI.
|
||||
## What it is
|
||||
|
||||
## Installation
|
||||
oh-my-pi-telegram is an [Oh My Pi](https://github.com/can1357/oh-my-pi) (`omp`) extension that turns a private chat with your own Telegram bot into a companion for the session running on your machine. From the phone you send prompts, files and voice notes, queue and steer turns, switch the model or thinking level, and receive streamed previews and the final answer.
|
||||
|
||||
Requires `omp` ≥ 16.5.2 (`@oh-my-pi/pi-coding-agent`) and Node.js ≥ 22.19.0.
|
||||
It is a fork of [`@llblab/[email protected]`](https://github.com/llblab/pi-telegram/tree/v0.22.0) (SHA `afe09c5`), repackaged as `@evandrodevbr/oh-my-pi-telegram` and declared as an `omp` extension.
|
||||
|
||||
| Surface | What you can do |
|
||||
|---|---|
|
||||
| Prompt intake | Send text, replies, edits, images, files, albums and voice notes into the session. |
|
||||
| Queue control | Messages sent while the agent is busy become queued turns: inspect, delete, promote, continue, abort, stop or force the next one. |
|
||||
| Operator menu | `/start` opens status, prompt templates, model, thinking level, settings, queue and extension sections. |
|
||||
| Rich replies | Rich Markdown (default) or legacy Markdown-to-HTML for final answers; optional live draft previews; native `...typing` status while the agent works. |
|
||||
| Files and voice | Inbound files land in `<agent dir>/tmp/telegram` (50 MiB default limit); `telegram_attach` returns artifacts as real files; inbound voice goes through command templates or STT handlers; outbound voice through `telegram_voice` and TTS providers. |
|
||||
| Buttons | Hidden `telegram_button` comments become inline buttons whose callbacks re-enter the session. |
|
||||
| Threaded Mode | One leader plus visible follower `omp` instances, each with its own Telegram thread, through one bot. |
|
||||
| Named profiles | Independent bots from one agent directory, with isolated polling, diagnostics and bus transport. |
|
||||
|
||||
## Why use it
|
||||
|
||||
It is a runtime adapter, not a remote terminal. A Telegram prompt is a normal model turn in the session that is active right now and inherits its post-compaction context, so token cost is not proportional only to the new mobile message.
|
||||
|
||||
Why this fork and not upstream: `@llblab/[email protected]` targets the Pi extension platform (`@earendil-works/pi-*`), and `omp` consumes the same platform republished as `@oh-my-pi/pi-coding-agent`. This fork:
|
||||
|
||||
1. Renames the package to `@evandrodevbr/oh-my-pi-telegram` so it is unambiguous in the `omp` extension registry.
|
||||
2. Keeps the upstream `peerDependencies` on `@earendil-works/pi-{ai,agent-core,coding-agent}` `>=0.80.6`, with no code changes or shims.
|
||||
3. Declares the extension through an `omp` block in `package.json` (extensions, display name, `compatibleWith: >=16.5.2`); the old `pi` block was removed in `572967c`.
|
||||
|
||||
Do not use it if you need a real terminal from the phone: there are no hidden `omp` processes, no PTY and no raw TTY input. Telegram can compact the current session but cannot create, resume, fork, browse or switch sessions, and arbitrary slash commands are never forwarded to the TUI. For plain Pi, use upstream `@llblab/pi-telegram`.
|
||||
|
||||
## How it works
|
||||
|
||||
- The active `omp` instance owns `getUpdates` polling for one bot. You start it with `/telegram-connect`; Telegram never launches hidden `omp` processes.
|
||||
- Each Telegram message becomes a turn: it goes to the queue or is dispatched to the active session, then streams back as a preview with the native typing status and ends as a final Rich Markdown reply, optionally with files, voice, buttons or callback actions.
|
||||
- In Threaded Mode, follower instances talk to the leader over a local bus (Unix socket or named pipe) and get their own Telegram thread.
|
||||
- Code layout: `index.ts` is the composition root, `lib/*.ts` are flat domain modules (queue, polling, locks, bus, menus, rendering, delivery), `api/*.ts` are the public entry points for companion extensions, and `docs/` holds the architecture and contract documents.
|
||||
|
||||
## Quickstart
|
||||
|
||||
Requires `omp` >= 16.5.2 (`package.json` → `omp.compatibleWith`) and Node.js >= 22.19.0 (`engines.node`).
|
||||
|
||||
```bash
|
||||
# From git (this repository)
|
||||
omp plugin install https://git.evandro.dev.br/evandro/oh-my-pi-telegram.git
|
||||
|
||||
# From npm (once the package is published)
|
||||
omp plugin install npm:@evandrodevbr/oh-my-pi-telegram
|
||||
|
||||
# From a local checkout (development)
|
||||
omp plugin link /path/to/oh-my-pi-telegram
|
||||
```
|
||||
|
||||
Restart (or reload) `omp` so the extension loads, then:
|
||||
The npm package `@evandrodevbr/oh-my-pi-telegram` is not published yet. Restart (or reload) `omp` so the extension loads, then:
|
||||
|
||||
1. Create a bot with [@BotFather](https://t.me/BotFather) (`/newbot`) and copy the token.
|
||||
2. In `omp`, run `/telegram-setup` and paste the token.
|
||||
3. Run `/telegram-connect` to activate polling for this instance.
|
||||
3. Run `/telegram-connect` to start polling for this instance.
|
||||
4. In the bot DM, send `/start`.
|
||||
|
||||
> [!WARNING]
|
||||
> **The first Telegram user to message the bot becomes the allowed owner**; everyone
|
||||
> else is ignored. Pair right after `/telegram-connect`, and never put the bot token in
|
||||
> chat, source, committed config or logs. Setup can prefill the token from
|
||||
> `TELEGRAM_BOT_TOKEN`, `TELEGRAM_BOT_KEY`, `TELEGRAM_TOKEN` or `TELEGRAM_KEY`; the saved
|
||||
> config lives in `~/.pi/agent/telegram.json`.
|
||||
> The first Telegram user to message the bot becomes the allowed owner; everyone else is ignored. Pair right after `/telegram-connect`, and never put the bot token in chat, source, committed config or logs. Setup can prefill the token from `TELEGRAM_BOT_TOKEN`, `TELEGRAM_BOT_KEY`, `TELEGRAM_TOKEN` or `TELEGRAM_KEY`.
|
||||
|
||||
## Why this fork and not upstream
|
||||
The saved config is `<agent dir>/telegram.json`. The agent directory is `PI_CODING_AGENT_DIR` when set, `~/.omp/agent` when the process is `omp`, and `~/.pi/agent` otherwise (`lib/paths.ts`).
|
||||
|
||||
`llblab/[email protected]` targets the Pi extension platform (`@earendil-works/pi-*`).
|
||||
`omp` consumes the same platform republished as `@oh-my-pi/pi-coding-agent`. This fork:
|
||||
|
||||
1. Renames the package to `@evandrodevbr/oh-my-pi-telegram` so it is unambiguous in the `omp` extension registry.
|
||||
2. Keeps the upstream `peerDependencies` on `@earendil-works/pi-{ai,agent-core,coding-agent}` `>=0.80.6`, the runtime surface `omp` consumes — no code changes or shims.
|
||||
3. Declares the extension through an `omp` block in `package.json` (`extensions`, display name and `compatibleWith: >=16.5.2`); the old `pi` block was replaced by it.
|
||||
4. Re-runs every upstream gate (`typecheck` → `test` → `audit` → `pack:check`) on the `v0.22.0` source.
|
||||
|
||||
Lineage: `badlogic/pi-telegram` → `llblab/pi-telegram` (0.22.0) → **this fork**.
|
||||
|
||||
## What it does
|
||||
|
||||
| Surface | What you can do |
|
||||
|---|---|
|
||||
| **Prompt intake** | Send text, replies, edits, images, files, albums and voice notes into the session |
|
||||
| **Queue control** | Messages sent while the agent is busy become queued turns; inspect, delete, promote, continue, abort, stop or force the next one |
|
||||
| **Operator menu** | `/start` opens status, prompt templates, model, thinking level, settings, queue and extension sections |
|
||||
| **Prompt templates** | Run Pi prompt templates as Telegram-safe commands such as `/fix_tests` |
|
||||
| **Model and thinking** | Switch model or reasoning level through safe continuation flows; confirm `/compact` |
|
||||
| **Rich replies** | Native Rich Markdown (default) or legacy Markdown-to-HTML for final answers; optional live draft previews; native `…typing` status while the agent works |
|
||||
| **Files** | Inbound files land in `<agent-dir>/tmp/telegram` (50 MiB default limit); `telegram_attach` returns artifacts as real files |
|
||||
| **Voice** | Inbound voice through command-template, programmatic or STT handlers; outbound via `telegram_voice` and TTS providers |
|
||||
| **Buttons** | Hidden `telegram_button` comments become inline buttons whose callbacks re-enter the session |
|
||||
| **Threaded Mode** | One leader plus visible follower `omp` instances, each with its own Telegram thread, through one bot |
|
||||
| **Named profiles** | Run independent bots from one agent directory with isolated polling, diagnostics and bus transport |
|
||||
| **Extension platform** | Companion extensions add commands, menu sections, status rows, update/callback handlers, inbound/outbound handlers and voice providers |
|
||||
| **Diagnostics** | `/telegram-status` shows connection, mode, queue, transport and recent redacted events |
|
||||
## Usage
|
||||
|
||||
<details>
|
||||
<summary>Commands</summary>
|
||||
@@ -125,81 +110,41 @@ Profile names use lowercase ASCII letters and digits (max 32 characters); `defau
|
||||
| Area | Variables |
|
||||
|---|---|
|
||||
| Bot token bootstrap | `TELEGRAM_BOT_TOKEN`, `TELEGRAM_BOT_KEY`, `TELEGRAM_TOKEN`, `TELEGRAM_KEY` |
|
||||
| HTTP proxy | `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`, plus `NODE_USE_ENV_PROXY=1` or Node `--use-env-proxy` |
|
||||
| Network family | `PI_TELEGRAM_NETWORK_FAMILY` = `auto`, `ipv4`, `ipv6` or `ipv4-fallback` |
|
||||
| Network family | `PI_TELEGRAM_NETWORK_FAMILY` = `auto`, `ipv4`, `ipv6` or `ipv4-fallback` (default) |
|
||||
| Agent data root | `PI_CODING_AGENT_DIR` |
|
||||
| Inbound file limit | `PI_TELEGRAM_INBOUND_FILE_MAX_BYTES`, `TELEGRAM_MAX_FILE_SIZE_BYTES` |
|
||||
| Outbound attachment limit | `PI_TELEGRAM_OUTBOUND_ATTACHMENT_MAX_BYTES`, `TELEGRAM_MAX_ATTACHMENT_SIZE_BYTES` |
|
||||
|
||||
Defaults: config in `~/.pi/agent`, inbound temp files in `~/.pi/agent/tmp/telegram`, and `assistant: { rendering: "rich", draftPreviews: false }`.
|
||||
Defaults: inbound temp files in `<agent dir>/tmp/telegram`, and `assistant: { rendering: "rich", draftPreviews: false }`.
|
||||
|
||||
</details>
|
||||
|
||||
## How it works
|
||||
Full reference: [architecture](docs/architecture.md), [public API](docs/public-api.md), [delivery](docs/delivery.md), [inbound](docs/inbound.md), [outbound](docs/outbound.md), [voice](docs/voice.md), [multi-instance bus](docs/multi-instance-bus.md) and the rest in the [docs index](docs/README.md).
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
TG["Telegram<br/>private DM · Threaded Mode"] -->|"getUpdates"| POLL
|
||||
subgraph OMP["omp instance (extension)"]
|
||||
POLL["polling + updates<br/>pairing · routing"] --> Q["turns + queue<br/>control · priority · default"]
|
||||
Q -->|"sendUserMessage"| AG["agent session<br/>(currently active)"]
|
||||
AG -->|"lifecycle events"| OUT["previews · rich replies<br/>files · voice · buttons"]
|
||||
end
|
||||
OUT -->|"Bot API"| TG
|
||||
POLL <-->|"local bus<br/>Unix socket / named pipe"| F["follower omp instances<br/>(Threaded Mode)"]
|
||||
```
|
||||
## Project status
|
||||
|
||||
The core loop is: Telegram message → Telegram turn → queue or active dispatch →
|
||||
agent lifecycle → streaming preview / native active status → final Rich Markdown
|
||||
reply → optional files, voice, buttons or callback actions. Exactly one instance
|
||||
owns `getUpdates` per bot; in Threaded Mode followers are visible processes the
|
||||
operator started and ran `/telegram-connect` in — Telegram never launches hidden
|
||||
`omp` processes.
|
||||
Fork release `0.22.0-evandro.1`. Per [`CHANGELOG.md`](CHANGELOG.md), the fork re-ran the upstream gates: typecheck, 1,229 of 1,230 tests passing with one platform-only skip, `npm audit` with 0 vulnerabilities and a clean `npm pack --dry-run`. CI (`.github/workflows/validate.yml`) runs `npm ci` and `npm run validate` on Ubuntu with Node 24 for every push and pull request.
|
||||
|
||||
<details>
|
||||
<summary>Layout and public entrypoints</summary>
|
||||
|
||||
| Path | Role |
|
||||
|---|---|
|
||||
| `index.ts` | Composition root: wires live ports, session state, transport adapters and lifecycle hooks |
|
||||
| `lib/*.ts` | Flat domain modules (queue, polling, locks, bus, menus, rendering, delivery…) forming an acyclic import graph |
|
||||
| `api/*.ts` | Public companion-extension entrypoints: `inbound`, `outbound`, `delivery`, `activity`, `updates`, `commands`, `sections`, `status`, `voice`, `keyboard` |
|
||||
| `docs/` | Architecture and contract documentation |
|
||||
| `tests/*.test.ts` | Domain regressions run with `node --test` |
|
||||
|
||||
State: `~/.pi/agent/telegram.json` (config), `~/.pi/agent/locks.json` (polling ownership) and profile-scoped redacted `logs*.jsonl` under `tmp/telegram` (never model context).
|
||||
|
||||
Documentation: [Architecture](docs/architecture.md) · [Public API](docs/public-api.md) · [Delivery](docs/delivery.md) · [Activity](docs/activity.md) · [Inbound](docs/inbound.md) · [Outbound](docs/outbound.md) · [Voice](docs/voice.md) · [Sections](docs/sections.md) · [Updates](docs/updates.md) · [Multi-Instance Bus](docs/multi-instance-bus.md) · [Locks](docs/locks.md) · [UI Style](docs/ui-style.md) · [Callback Namespaces](docs/callback-namespaces.md) · [Command Templates](docs/command-templates.md) — index in [`docs/README.md`](docs/README.md).
|
||||
|
||||
</details>
|
||||
|
||||
## Limitations
|
||||
|
||||
- Telegram is a companion surface around a live runtime, not a second runtime: no hidden `omp` processes, no PTY or fake terminal, no raw TTY input, no session replacement without an official extension API, and non-owner users cannot control the bridge.
|
||||
- A design spec for an `omp` status-bar segment ([`docs/superpowers/specs/`](docs/superpowers/specs/2026-07-15-telegram-omp-status-design.md)) needs a new `omp` core API and is not implemented here.
|
||||
- In Threaded Mode, threadless messages sent from the `All` tab are not routed as prompts once bound threads exist; use a bound thread tab.
|
||||
- Package metadata declares the extension only under `omp.extensions` (the `pi` block was removed in `572967c`); install this fork through `omp`, and use upstream `@llblab/pi-telegram` for plain Pi.
|
||||
- Open work is tracked in [`BACKLOG.md`](BACKLOG.md) (promoted-follower reload evidence, native Windows Threaded Mode follow-ups, evidence-backed Telegram client and Rich Markdown quirks).
|
||||
- `release.yml` needs a `## <version>` heading in `CHANGELOG.md`; the fork entry sits under `## Unreleased` as a `###` heading, so a tag fails that check until the section is promoted.
|
||||
- Open work (promoted-follower reload evidence, native Windows Threaded Mode follow-ups, Telegram client and Rich Markdown quirks) is tracked in [`BACKLOG.md`](BACKLOG.md).
|
||||
|
||||
## Development
|
||||
Development:
|
||||
|
||||
```bash
|
||||
npm ci
|
||||
npm run typecheck # tsc --noEmit
|
||||
npm test # node --experimental-strip-types --test tests/*.test.ts
|
||||
npm run audit # npm audit
|
||||
npm run pack:check # npm pack --dry-run
|
||||
npm run validate # all of the above
|
||||
npm run validate # typecheck + test + audit + pack:check
|
||||
```
|
||||
|
||||
Engineering conventions: [`AGENTS.md`](AGENTS.md). Completed delivery history: [`CHANGELOG.md`](CHANGELOG.md).
|
||||
Engineering conventions are in [`AGENTS.md`](AGENTS.md).
|
||||
|
||||
## CI/CD
|
||||
## License
|
||||
|
||||
- [`.github/workflows/validate.yml`](.github/workflows/validate.yml) — on every push and pull request: Node 24, `npm ci`, `npm run validate`.
|
||||
- [`.github/workflows/release.yml`](.github/workflows/release.yml) — on tags `v*.*.*`: checks that the tag matches `package.json`'s version, extracts that version's section from `CHANGELOG.md` into the release notes, and creates the release with `gh release create` (a GitHub CLI call). The extraction expects a `## <version>` heading; the fork's entry currently sits under `## Unreleased` as a `###` heading, so a tag would fail that check until the section is promoted.
|
||||
MIT, see [`LICENSE`](LICENSE): copyright Evandro Fonseca Junior (evandrodevbr), llblab and Mario Zechner (badlogic). Built on [llblab/pi-telegram](https://github.com/llblab/pi-telegram), itself a fork of [badlogic/pi-telegram](https://github.com/badlogic/pi-telegram); runs inside [Oh My Pi](https://github.com/can1357/oh-my-pi) and talks to the Telegram Bot API. Unofficial project, not affiliated with Telegram or the Oh My Pi maintainers.
|
||||
|
||||
## Credits and notices
|
||||
---
|
||||
|
||||
- MIT licensed ([`LICENSE`](LICENSE)): copyright Evandro Fonseca Junior (evandrodevbr) and llblab.
|
||||
- Built on [`llblab/pi-telegram`](https://github.com/llblab/pi-telegram), itself a fork of [`badlogic/pi-telegram`](https://github.com/badlogic/pi-telegram); runs inside [Oh My Pi](https://github.com/can1357/oh-my-pi) and talks to the Telegram Bot API.
|
||||
- Unofficial project, not affiliated with Telegram or the Oh My Pi maintainers.
|
||||
<div align="center">
|
||||
<sub>Made by <a href="https://evandro.dev.br">Evandro Fonseca Junior</a> · <a href="https://git.evandro.dev.br/evandro">git.evandro.dev.br</a></sub>
|
||||
</div>
|
||||
@@ -0,0 +1,32 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="420" viewBox="0 0 1200 420" role="img" aria-labelledby="title desc">
|
||||
<title id="title">oh-my-pi-telegram</title>
|
||||
<desc id="desc">oh-my-pi-telegram: drive a live omp session from a private Telegram chat. On the right, a simplified Telegram chat shows the /start command, the bot menu with /compact, /next and /stop, and a prompt sent from the phone.</desc>
|
||||
|
||||
<rect width="1200" height="420" rx="24" fill="#17212b"/>
|
||||
|
||||
<g id="title-block" font-family="system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif">
|
||||
<text x="64" y="156" font-size="64" font-weight="700" fill="#f5f5f5">oh-my-pi-telegram</text>
|
||||
<text x="64" y="214" font-size="28" fill="#f5f5f5">Drive a live omp session from</text>
|
||||
<text x="64" y="252" font-size="28" fill="#f5f5f5">a private Telegram chat.</text>
|
||||
<text x="64" y="326" font-size="20" fill="#8a9bad" font-family="ui-monospace, "SF Mono", Consolas, monospace">TypeScript · Node ≥22.19 · omp ≥16.5.2</text>
|
||||
</g>
|
||||
|
||||
<g id="chat" font-family="system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif" font-size="20">
|
||||
<rect x="712" y="44" width="424" height="332" rx="20" fill="#1e2c3a"/>
|
||||
|
||||
<rect x="980" y="68" width="132" height="44" rx="14" fill="#2e557c"/>
|
||||
<text x="1000" y="97" fill="#f5f5f5">/start</text>
|
||||
<path d="M1074 92 L1079 97 L1088 87 M1082 97 L1091 87" fill="none" stroke="#70baf5" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
|
||||
<rect x="736" y="132" width="376" height="144" rx="14" fill="#182533"/>
|
||||
<text x="756" y="174" fill="#70baf5">/compact</text>
|
||||
<text x="860" y="174" fill="#f5f5f5">Compact current session</text>
|
||||
<text x="756" y="214" fill="#70baf5">/next</text>
|
||||
<text x="860" y="214" fill="#f5f5f5">Force next turn</text>
|
||||
<text x="756" y="254" fill="#70baf5">/stop</text>
|
||||
<text x="860" y="254" fill="#f5f5f5">Abort Pi & Clear queue</text>
|
||||
|
||||
<rect x="928" y="296" width="184" height="44" rx="14" fill="#2e557c"/>
|
||||
<text x="948" y="325" fill="#f5f5f5">run the tests</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
Reference in new issue
Block a user