grok-telegram-bot 2.4.0 → 2.5.0

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.
Files changed (78) hide show
  1. package/.env.example +38 -2
  2. package/CHANGELOG.md +119 -1
  3. package/README.md +58 -15
  4. package/docs/GROUP.md +225 -0
  5. package/docs/INSTALL.md +3 -0
  6. package/package.json +1 -1
  7. package/src/app/lifetime-flag.ts +20 -0
  8. package/src/app/settings-store.ts +47 -8
  9. package/src/app/types.ts +12 -1
  10. package/src/app/updater.ts +24 -3
  11. package/src/bot/auth.ts +96 -15
  12. package/src/bot/bot.ts +122 -15
  13. package/src/bot/chat-controller.ts +52 -18
  14. package/src/bot/commands.ts +69 -29
  15. package/src/bot/deps.ts +3 -0
  16. package/src/bot/group-memory.ts +159 -0
  17. package/src/bot/handlers/accounts.ts +7 -0
  18. package/src/bot/handlers/control.ts +85 -32
  19. package/src/bot/handlers/document.ts +31 -4
  20. package/src/bot/handlers/forum.ts +207 -0
  21. package/src/bot/handlers/menu.ts +86 -24
  22. package/src/bot/handlers/message.ts +101 -21
  23. package/src/bot/handlers/photo.ts +123 -16
  24. package/src/bot/handlers/running.ts +150 -24
  25. package/src/bot/handlers/session-card.ts +13 -5
  26. package/src/bot/handlers/sessions.ts +68 -18
  27. package/src/bot/handlers/voice.ts +52 -7
  28. package/src/bot/image-return.ts +8 -5
  29. package/src/bot/menu/ephemeral.ts +13 -3
  30. package/src/bot/menu/keyboard.ts +53 -14
  31. package/src/bot/menu/refresh.ts +3 -1
  32. package/src/bot/menu/status-panel.ts +12 -6
  33. package/src/bot/permission-service.ts +19 -0
  34. package/src/bot/prompt-anchor.ts +300 -0
  35. package/src/bot/prompt-content.ts +3 -0
  36. package/src/bot/registry.ts +94 -1
  37. package/src/bot/scope.ts +94 -0
  38. package/src/bot/session-runtime.ts +647 -158
  39. package/src/bot/suggestions.ts +91 -31
  40. package/src/bot/telegram-actions.ts +440 -0
  41. package/src/bot/telegram-bots.ts +495 -0
  42. package/src/bot/telegram-io.ts +94 -10
  43. package/src/cli.ts +2 -0
  44. package/src/config.ts +201 -2
  45. package/src/forum/bind-path.ts +146 -0
  46. package/src/forum/manager.ts +651 -0
  47. package/src/forum/project-icon.ts +142 -0
  48. package/src/forum/thread.ts +16 -0
  49. package/src/forum/topic-store.ts +114 -0
  50. package/src/forum/types.ts +29 -0
  51. package/src/grok/client.ts +130 -28
  52. package/src/index.ts +205 -75
  53. package/src/projects/manager.ts +16 -3
  54. package/src/render/chunk.ts +17 -10
  55. package/src/render/hashtags.ts +5 -1
  56. package/src/render/session-comment.ts +64 -7
  57. package/src/render/telegram-bridge.ts +360 -0
  58. package/src/render/tool-call.ts +56 -37
  59. package/src/service/platform.ts +44 -7
  60. package/src/service/windows.ts +16 -4
  61. package/src/sessions/history.ts +50 -9
  62. package/src/sessions/process.ts +7 -0
  63. package/src/sessions/types.ts +2 -2
  64. package/src/stream/streamer.ts +17 -6
  65. package/scripts/analyze-jsonl.ts +0 -33
  66. package/scripts/delayed-restart.ps1 +0 -29
  67. package/scripts/probe-exit-response-shape.py +0 -77
  68. package/scripts/probe-plan-exit.py +0 -60
  69. package/scripts/probe-plan-exit2.py +0 -48
  70. package/scripts/probe-plan-fields.py +0 -41
  71. package/scripts/probe-plan-fields2.py +0 -58
  72. package/scripts/probe-plan-response-path.py +0 -48
  73. package/scripts/sample-claude-tooluse.ts +0 -21
  74. package/scripts/sample-kiro-events.ts +0 -31
  75. package/scripts/smoke-exit-plan.ts +0 -274
  76. package/scripts/smoke-exit-shapes.ts +0 -252
  77. package/scripts/smoke-import.mjs +0 -82
  78. package/scripts/smoke-import.ts +0 -73
package/.env.example CHANGED
@@ -6,8 +6,11 @@
6
6
  # REQUIRED — Telegram bot token from @BotFather (https://t.me/BotFather)
7
7
  TELEGRAM_BOT_TOKEN=
8
8
 
9
- # RECOMMENDED — comma-separated Telegram user IDs allowed to use the bot.
10
- # Get yours from @userinfobot. If empty, ANYONE can use the bot (unsafe).
9
+ # RECOMMENDED — comma-separated Telegram user IDs allowed to use the bot
10
+ # (private chats AND groups / forum topics). Get yours from @userinfobot.
11
+ # Example: ALLOWED_USERS=123456789,987654321
12
+ # If empty, ANYONE can use the bot (unsafe — especially with TOPIC_GROUP_ID).
13
+ # Unauthorized group members are ignored silently (no ⛔ spam in the group).
11
14
  ALLOWED_USERS=
12
15
 
13
16
  # ── Grok Build CLI ───────────────────────────────────────────────────────────
@@ -96,6 +99,36 @@ NOTIFY_OTHER_SESSIONS=true
96
99
  # 2) second
97
100
  # SUGGESTIONS_AUTO_APPROVE_PCT=95
98
101
 
102
+ # ── Forum topics (optional project workspace) ────────────────────────────────
103
+ # Telegram forum supergroup id (negative for supergroups). When set, the bot
104
+ # probes the group at startup / /forum_setup:
105
+ # • not admin (or no Manage Topics) → ignore group for topic features
106
+ # • Topics off → best-effort try to enable (Bot API has no official method;
107
+ # if it fails, enable Topics manually in group settings and re-run setup)
108
+ # • Topics on + admin → creates "AI Chat" + optional per-project topics
109
+ # (TOPIC_AUTO_CREATE), paced + 429-retried for large catalogs
110
+ # • pins favicon / MSIX logo when found; user topics auto-bind on exact
111
+ # catalog name match only (else absolute path / exact name)
112
+ # Messages in a topic run Grok sessions in that topic's project path.
113
+ # TOPIC_GROUP_ID=
114
+ # TOPIC_AUTO_CREATE=true
115
+ # TOPIC_AI_CHAT_NAME=AI Chat
116
+
117
+ # ── Sibling Telegram bots (agent "MCP-like" tools via JSON actions) ──────────
118
+ # Comma-separated usernames (with or without @) the agent may call with
119
+ # bot_command / list_bots after the first-prompt Telegram bridge directive.
120
+ # Example: ALLOWED_TELEGRAM_BOTS=helperbot,other_bot
121
+ # ALLOWED_TELEGRAM_BOTS=
122
+ # Optional command catalogs (shown by list_bots / first-prompt teaching).
123
+ # Compact: TELEGRAM_BOT_COMMANDS=helperbot:status,help,ping;otherbot:start|Start,info
124
+ # JSON: TELEGRAM_BOT_COMMANDS={"helperbot":["status","help"],"otherbot":[{"command":"start","description":"Start"}]}
125
+ # TELEGRAM_BOT_COMMANDS=
126
+ # Hard timeout waiting for a sibling bot after /cmd@bot (ms). Default 45000.
127
+ # TELEGRAM_BOT_REPLY_TIMEOUT_MS=45000
128
+ # Quiet settle after last message/edit from that bot (ms) — "typing done" for
129
+ # streaming bots that edit one message. Default 2000.
130
+ # TELEGRAM_BOT_SETTLE_MS=2000
131
+
99
132
  # ── Self-recheck (once per user prompt, gated) ───────────────────────────────
100
133
  # After a successful user turn (queue empty), the bot may run one quality pass.
101
134
  # Flow:
@@ -110,6 +143,9 @@ NOTIFY_OTHER_SESSIONS=true
110
143
  # Optional: when set AND the AI decides recheck is needed, use this template
111
144
  # instead of the AI-written recheck body ({{USER}} / {{DONE}} placeholders).
112
145
  # SELF_RECHECK_PROMPT=
146
+ # Max wait (ms) for quiet meta prompts (recheck decision + suggestions JSON).
147
+ # On timeout the session prompt is cancelled so ✅ Done is not blocked forever.
148
+ # QUIET_PROMPT_TIMEOUT_MS=90000
113
149
 
114
150
  # ── MCP servers (/mcp) ───────────────────────────────────────────────────────
115
151
  # /mcp lists MCP servers the bot can discover and health-checks them. Grok Build
package/CHANGELOG.md CHANGED
@@ -7,7 +7,124 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
  The latest section is published verbatim as the GitHub Release notes by
8
8
  `.github/workflows/release.yml` when a `vX.Y.Z` tag is pushed.
9
9
 
10
- ## [Unreleased]
10
+ ## [2.5.0] - 2026-08-05
11
+
12
+ Forum project topics, cross-topic Telegram bridge, prompt anchors, and a more
13
+ reliable Done / stop path for multi-topic groups.
14
+
15
+ ### Added
16
+
17
+ - **Forum project topics (optional).** `TOPIC_GROUP_ID` manages a Telegram forum
18
+ supergroup: default **AI Chat** topic (workspace), optional auto-create one
19
+ topic per catalog project (`TOPIC_AUTO_CREATE`), favicon/MSIX logo discovery
20
+ pinned in the topic, and path-binding when users create new topics. Messages
21
+ in a topic run sessions in that project path.
22
+ - **Telegram bridge actions (agent JSON).** On the first prompt of a session the
23
+ bot injects how-to-work memory: the agent may emit a fenced `json` block with
24
+ `"telegram": [ actions ]` to create forum topics, search session/topic memory,
25
+ list allowlisted sibling bots, and call them via `/cmd@bot` (MCP-like). Results
26
+ are fed back as a quiet follow-up turn (not a Done). Configure bots with
27
+ `ALLOWED_TELEGRAM_BOTS`, optional `TELEGRAM_BOT_COMMANDS` catalogs, reply
28
+ timeout / settle (`TELEGRAM_BOT_REPLY_TIMEOUT_MS`, `TELEGRAM_BOT_SETTLE_MS`).
29
+ Sibling-bot waits only accept content from the triggered bot (prefer reply-to
30
+ our trigger), collect edits until idle, and timeouts continue the session.
31
+ Bridge plumbing stays out of the chat (no “continuing session” / queue spam);
32
+ only durable side-effects like topic creation are announced.
33
+ - **Cross-topic bridge actions.** From General / AI Chat (`GROK_WORKSPACE`), the
34
+ agent can orchestrate other forum topics via telegram JSON:
35
+ - `create_topic` with optional path
36
+ - **`set_path`** — bind/rebind a topic to an absolute path or exact catalog name
37
+ - **`send_prompt`** — inject a prompt into another topic’s session (`ran`/`queued`;
38
+ does not wait for that turn). Optional `new_session`.
39
+ Multiple actions run in order (cap **9**; up to **5** `send_prompt` per turn).
40
+ **New project paths:** agent `create_topic` / `set_path` with an absolute path
41
+ that does not exist yet **creates the folder** on disk, then binds the topic.
42
+ - **New session on the persistent bar + `/new`.** Private chat: bar is
43
+ ☰ Menu · 🆕 New session / 🧭 Running · ⏹ Stop (not the inline Menu message).
44
+ Slash command `/new` (Telegram command list) starts a fresh session. Forum
45
+ topics keep New on the topic inline menu because reply keyboards are unreliable.
46
+ - **Instant command feedback.** Slash commands and bar taps are deleted
47
+ immediately; handlers post bot status messages (e.g. `/new` →
48
+ “Creating new session…”) so the chat feels alive while the CLI/ACP starts.
49
+ - **Prompt anchors + `#prompt_<id>`.** User prompts (text, photos, docs, voice,
50
+ `/btw`, suggestion taps) are re-posted as bot messages with a searchable
51
+ `#prompt_` tag; the originals are best-effort deleted. Photos, documents, and
52
+ voice/audio are re-attached on the anchor via Telegram `file_id` so media is
53
+ not lost when the user message is removed. All AI stream bubbles, Done/error
54
+ notices, and queue acks for that turn reply to the anchor and carry the same
55
+ tag (alongside `#proj_` / `#sess_`).
56
+
57
+ ### Changed
58
+
59
+ - **Session card comments.** Cards (`/running`, `/sessions`, `/active`, status
60
+ panel) now show the **last user prompt** (max 250 chars). While a session is
61
+ running, a second line shows the **last AI agent thinking** (max 250). Idle
62
+ cards no longer use last-turn assistant outcome summaries as the comment.
63
+ - **Stronger self-recheck prompts.** Decision + default recheck briefs now push
64
+ production-related completeness for the same feature (e.g. water→waves,
65
+ auth→rate limits), **finish-all** (no “still need…” / incomplete honest
66
+ leftovers that force critical follow-up buttons), and a required **per-bug
67
+ recheck checklist** at the end of the pass. Compose always injects those
68
+ rules when an AI brief looks complete (headers only) but omitted them.
69
+ `/new`, bar **New**, and inline **New** share the same success copy.
70
+
71
+ ### Fixed
72
+
73
+ - **Missing `✅ Done` after a turn.** Done no longer waits on suggestion JSON
74
+ (send Done first, then attach buttons). Quiet meta prompts (recheck decision
75
+ + suggestions) use `QUIET_PROMPT_TIMEOUT_MS` (default 90s) and cancel the
76
+ session prompt on timeout so a hung meta call cannot block Done forever
77
+ (does not set user-cancelled / does not kill the agent). Chat shows
78
+ “Checking if a quality pass is needed…” while deciding recheck. Done text is
79
+ rebuilt after that wait so `/stop` mid-decision shows ⏹ Stopped. `notify`
80
+ retries truncated/plain text if the first send fails; a finally safety net
81
+ forces a short Done when one was expected but never delivered.
82
+ - **`/stop` / `/cancel` must not kill the bot or other sessions.** Stop is
83
+ session-scoped only: soft ACP `session/cancel`, cancel pending permissions
84
+ for that session, and force-complete that session’s in-flight prompt after a
85
+ short grace if the agent is slow — **never** kill the shared `grok agent`
86
+ process (which multiplexes every chat/topic). `killPid` also refuses to
87
+ target the bot’s own Node process.
88
+ - **`grok-tg install|start|restart` hang on Windows.** The service VBS is a
89
+ forever-restart loop (`Run …, True` waits for the bot). Launching it with
90
+ `execFileSync` made the CLI wait forever. Startup launches now use detached
91
+ `spawn` so the CLI returns immediately.
92
+ - **No silent process death.** Exit paths always log reason + code to stderr/file;
93
+ instance-lock conflict uses exit 1; polling classifies 429/409/401/network with
94
+ backoff; interactive runs recover in-process (no detach re-exec that blanks the
95
+ terminal); ref'd keepalive every 5m; `beforeExit` keeps the process up if the
96
+ event loop empties unexpectedly. Updater re-exec inherits TTY stdio.
97
+ - **Markdown / tool path rendering.** File paths in tool cards (Edit/Read/…) are
98
+ no longer wrapped in bold (Windows `C:\…` paths broke MarkdownV2 and fell
99
+ back to plain text that clients soft-render as `**Edit C:**`). Paths use
100
+ inline code; plain fallback demotes `**`/fences so soft-render cannot mangle
101
+ them. Chunked fences preserve tick length when reopening.
102
+ - **Group / topic stop controls.** Forum topic menu leads with **Stop** + Running;
103
+ `/cancel` and `/stop` work in topics; group slash-command menu is a short,
104
+ sorted list with cancel first (private keeps the full sorted catalog). Stop
105
+ confirms in-thread (not only a toast).
106
+ - **Forum topic bind: exact name only.** New user topics auto-bind when the
107
+ topic title exactly matches a catalog project (case-insensitive). Path prompts
108
+ and first messages no longer use fuzzy/partial project search (which could
109
+ bind the wrong folder). Unmatched topics still accept an absolute path or an
110
+ exact catalog name.
111
+ - **Forum bulk topic create.** Startup/`/forum_setup` walks the **full** project
112
+ catalog (not a 200-item cap), paces creates, and retries on Telegram 429
113
+ (`retry_after`) and transient network errors so large catalogs (1000+) can
114
+ finish reliably across restarts.
115
+ - **Forum group readiness.** Setup probes the configured group: if the bot is
116
+ not admin (or lacks Manage Topics), the group is **ignored** for topic
117
+ features. If Topics are off, the bot best-effort tries to enable them (no
118
+ official Bot API method today), otherwise ignores the group with a clear
119
+ status. Re-probes on promotion via `my_chat_member`; `/forum_setup` reports
120
+ ready vs disabled reason.
121
+
122
+ ### Docs
123
+
124
+ - **README** updated for forum topics, bridge, prompt anchors, suggestions,
125
+ self-recheck, and related config.
126
+ - **[docs/GROUP.md](./docs/GROUP.md)** — how to set up and use a forum project
127
+ group (binding, bridge actions, access control, troubleshooting).
11
128
 
12
129
  ## [2.4.0] - 2026-08-01
13
130
 
@@ -814,6 +931,7 @@ from a single chat and switch between them, on a redesigned, compact menu.
814
931
  diffs, MarkdownV2 rendering, scheduled tasks, multi-image prompts, and a
815
932
  cross-platform 24/7 background service.
816
933
 
934
+ [2.5.0]: https://github.com/artickc/grok-telegram-bot/releases/tag/v2.5.0
817
935
  [2.4.0]: https://github.com/artickc/grok-telegram-bot/releases/tag/v2.4.0
818
936
  [2.3.1]: https://github.com/artickc/grok-telegram-bot/releases/tag/v2.3.1
819
937
  [2.3.0]: https://github.com/artickc/grok-telegram-bot/releases/tag/v2.3.0
package/README.md CHANGED
@@ -27,9 +27,15 @@ re-architected for the Grok Build CLI and extended into a full multi-session cli
27
27
  | Capability | What it does |
28
28
  |---|---|
29
29
  | 🗂 **Projects** | `/projects` browses your folders and runs Grok in the one you pick. |
30
+ | 🏷 **Forum project topics** | Optional forum supergroup: one topic per project, **AI Chat** workspace, exact-name bind, `/forum_setup`. See **[docs/GROUP.md](./docs/GROUP.md)**. |
31
+ | 🌉 **Telegram bridge** | Agent can `create_topic`, `set_path`, `send_prompt` across topics, `search_memory`, and call allowlisted sibling bots via JSON actions. |
32
+ | 🔖 **Prompt anchors** | Each user prompt is re-posted with a searchable `#prompt_…` tag; stream/Done messages reply to that anchor (media re-attached). |
33
+ | 🆕 **New session** | `/new` or the bar **New** button starts a fresh session; forum topics keep New on the topic menu. |
34
+ | 💡 **Post-turn suggestions** | After Done, 1–3 scored follow-ups as buttons; high-score items can auto-queue as one multi-step prompt. |
35
+ | 🔍 **Gated self-recheck** | After file-changing turns, an optional quality pass runs once before Done (`SELF_RECHECK`). |
30
36
  | ♻️ **Resume sessions** | `/sessions` lists recent Grok sessions; tap to resume one (`grok --session <id>`). |
31
37
  | 🟢 **Connect to live sessions** | `/active` shows sessions running **right now** on your PC. Watch them live, or continue them — see below. |
32
- | 🛑 **Kill a session / PID** | Each live `/sessions` · `/active` card has a **🛑 Kill · pid N** button (confirm-guarded) that stops that session's process and its child tree; `/killall` stops them all. The bot's own agent is never killable. |
38
+ | 🛑 **Kill a session / PID** | Each live `/sessions` · `/active` card has a **🛑 Kill · pid N** button (confirm-guarded) that stops that session's process and its child tree; `/killall` stops them all. The bot's own agent is never killable. **Stop** only cancels the current session turn — never the shared agent. |
33
39
  | 📡 **Live watch** | Follow a running session read-only in real time (tails its event log). |
34
40
  | 🧭 **Always-visible menu** | A persistent keyboard plus a pinned status panel that appears while a task runs (and clears when idle), showing your current **project, agent, reasoning effort, model, session and queue**. |
35
41
  | ⏰ **Scheduled tasks** | Create prompts that run on a schedule (once / daily / weekly / monthly / every-N-minutes) in a chosen project, delivered back to your chat. |
@@ -49,7 +55,7 @@ re-architected for the Grok Build CLI and extended into a full multi-session cli
49
55
  | 💬 **Quality markdown** | Converts agent markdown to Telegram **MarkdownV2** with safe escaping and code-fence-aware splitting. |
50
56
  | 🔁 **Self-healing** | Auto-restarts the Grok agent with backoff and re-binds your session. |
51
57
  | 🖥 **Runs 24/7** | 1-click install as a background service that starts on boot — Windows, Linux, macOS, auto-detected. |
52
- | 🔒 **Access control** | Restrict to specific Telegram user IDs. |
58
+ | 🔒 **Access control** | Restrict to specific Telegram user IDs (private chats **and** forum groups). |
53
59
 
54
60
  ---
55
61
 
@@ -59,6 +65,8 @@ re-architected for the Grok Build CLI and extended into a full multi-session cli
59
65
  |---|:---:|:---:|
60
66
  | Connect Grok CLI to Telegram (ACP) | ✅ | ✅ |
61
67
  | Switch between projects | ✅ | ❌ |
68
+ | **Forum topics = projects** + AI Chat workspace | ✅ | ❌ |
69
+ | **Cross-topic agent bridge** (create / bind / send_prompt) | ✅ | ❌ |
62
70
  | Resume saved sessions | ✅ | ❌ |
63
71
  | Attach to **live** PC sessions (watch / fork) | ✅ | ❌ |
64
72
  | **Kill a session by PID** (or all at once) | ✅ | ❌ |
@@ -69,6 +77,7 @@ re-architected for the Grok Build CLI and extended into a full multi-session cli
69
77
  | **Session auto-approve** + **pinned** interactive permissions | ✅ | ❌ |
70
78
  | Multiple isolated sessions | ✅ | ❌ (single shared) |
71
79
  | Queued follow-ups while busy | ✅ | ❌ |
80
+ | **Post-turn suggestions** + gated self-recheck | ✅ | ❌ |
72
81
  | **Scheduled tasks** (cron-like) | ✅ | ❌ |
73
82
  | **Multi-image** prompts (albums) | ✅ | ❌ |
74
83
  | Unified **edit diffs** | ✅ | ❌ |
@@ -216,14 +225,16 @@ Logs are written to `logs/grok-telegram-bot.log` (rotated at 5 MB).
216
225
  /tasks Manage scheduled tasks
217
226
  /newtask Create a scheduled task (wizard)
218
227
  /history Show recent conversation history
219
- /new Start a fresh session here
228
+ /new Start a fresh session here (also bar: 🆕 New session)
229
+ /forum_setup Re-probe / create forum topics (use inside the configured group)
220
230
  /status Current session, project & queue
221
231
  /usage Account info & current context usage
222
232
  /btw <text> Run it now if idle, else queue to run right after the current task
223
233
  /flush Send queued follow-ups now
224
234
  /queue Show queued follow-ups
225
235
  /clearqueue Clear the queue
226
- /cancel Stop the current turn
236
+ /cancel Stop the current turn (session-scoped — never kills the shared agent)
237
+ /stop Same as /cancel
227
238
  /unwatch Stop following a live session
228
239
  /model <id> Switch the model for this session
229
240
  /restart Restart the Grok agent
@@ -237,13 +248,28 @@ running, your messages are queued and sent automatically when it finishes.
237
248
 
238
249
  ---
239
250
 
251
+ ## 🏷 Forum project group (optional)
252
+
253
+ Drive **many projects in parallel** from one Telegram forum supergroup: each
254
+ topic is bound to a folder, and **AI Chat** stays on `GROK_WORKSPACE` for
255
+ orchestration. Set `TOPIC_GROUP_ID`, make the bot admin with Manage Topics, and
256
+ run `/forum_setup`. Full walkthrough (binding rules, agent bridge, access
257
+ control, troubleshooting):
258
+
259
+ **→ [docs/GROUP.md](./docs/GROUP.md)**
260
+
261
+ ---
262
+
240
263
  ## 🧭 The menu & status panel
241
264
 
242
- A tiny **persistent bar** sits under the message box — **☰ Menu · 🧭 Running ·
243
- Stop** so common actions are one tap away without clutter. Tap **☰ Menu**
244
- (or `/menu`) to open a clean, grouped **inline menu**: Project · New · Running ·
245
- Sessions · Agent · Model · Reasoning · Tasks · Status · Usage · Stop · Kill all.
246
- The bar can be hidden (🙈) and restored (⌨️ Show bar or `/menu`).
265
+ A tiny **persistent bar** sits under the message box — **☰ Menu · 🆕 New session
266
+ · 🧭 Running · Stop** (while idle/busy the middle button may show Running
267
+ instead of New) so common actions are one tap away without clutter. Tap
268
+ **☰ Menu** (or `/menu`) to open a clean, grouped **inline menu**: Project ·
269
+ Running · Sessions · Agent · Model · Reasoning · Tasks · Status · Usage · Stop ·
270
+ Kill all. Forum topics keep **New** on the topic inline menu (reply keyboards are
271
+ unreliable there). The bar can be hidden (🙈) and restored (⌨️ Show bar or
272
+ `/menu`).
247
273
 
248
274
  While a task is running, a **pinned status panel** appears at the top of the chat
249
275
  showing your current **task progress, activity, queue, project, session, context
@@ -403,9 +429,9 @@ Resuming an **idle** session loads it directly so you continue the exact thread.
403
429
  | Variable | Required | Default | Description |
404
430
  |---|---|---|---|
405
431
  | `TELEGRAM_BOT_TOKEN` | **yes** | — | Bot token from @BotFather. |
406
- | `ALLOWED_USERS` | recommended | *(all)* | Comma-separated Telegram user IDs. Empty = anyone (unsafe). |
432
+ | `ALLOWED_USERS` | recommended | *(all)* | Comma-separated Telegram user IDs for private chats **and** groups. Empty = anyone (unsafe — never leave empty with `TOPIC_GROUP_ID`). Unauthorized group members are ignored silently. |
407
433
  | `GROK_CLI_PATH` | no | auto / `grok` | Path to the `grok` binary. |
408
- | `GROK_WORKSPACE` | no | cwd | Default working directory. |
434
+ | `GROK_WORKSPACE` | no | cwd | Default working directory (also AI Chat / General in a forum group). |
409
435
  | `XAI_API_KEY` | no | — | xAI API key, only for headless hosts with no browser. Normally you sign in with `grok login` (or `/reauth`) — no key needed. Exported to the agent when set. |
410
436
  | `GROK_MODEL` | no | `grok-4.5` | Default model for new sessions. |
411
437
  | `GROK_TG_DIR` | no | `~/.grok/tg` | Folder holding this instance's `.env`, `logs/`, `data/`. Resolution: `--instance` → `GROK_TG_DIR` → a `.env` in the current folder → `~/.grok/tg`. So a `.env` created once is loaded from any startup path. |
@@ -423,6 +449,18 @@ Resuming an **idle** session loads it directly so you continue the exact thread.
423
449
  | `SHOW_PROGRESS` | no | `true` | Ask the agent to append a `{progress: N%}` marker to each message; the bot parses it, hides the marker, and renders a green 0–100% bar on the live message, in session cards, and in the status panel. |
424
450
  | `PROGRESS_FALLBACK` | no | `true` | When `SHOW_PROGRESS` is on but the agent emits **no** `{progress: N%}` marker (weaker/free models and long tool-heavy turns often skip it), render a **bot-computed** bar derived from real activity (completed tool calls, streamed output, elapsed time) so a live bar still advances — filling to 100% when the turn completes. The agent's own marker, when present, always takes precedence and stays monotonic. |
425
451
  | `NOTIFY_OTHER_SESSIONS` | no | `true` | Deliver a session's "Done" summary (with a short created/edited/deleted count) even when it's a background session, marked "From other session". `false` keeps background sessions silent. |
452
+ | `SUGGESTIONS_ENABLED` | no | `true` | After Done, quietly ask for 1–3 scored follow-ups shown as buttons. |
453
+ | `SUGGESTIONS_AUTO_APPROVE_PCT` | no | `95` | Auto-queue suggestions with need ≥ this % as one multi-step prompt (`0` = buttons only). |
454
+ | `SELF_RECHECK` | no | `true` | After a successful user turn that modified files, optionally run one gated quality pass before Done. Alias: `SLEF_RECHECK`. |
455
+ | `SELF_RECHECK_PROMPT` | no | — | Optional fixed recheck template when AI decides recheck is needed (`{{USER}}` / `{{DONE}}`). |
456
+ | `QUIET_PROMPT_TIMEOUT_MS` | no | `90000` | Max wait for quiet meta prompts (recheck decision + suggestions). Timeout cancels the meta prompt so Done is not blocked. |
457
+ | `TOPIC_GROUP_ID` | no | — | Forum supergroup id for project topics. Bot must be admin with Manage Topics. See **[docs/GROUP.md](./docs/GROUP.md)**. |
458
+ | `TOPIC_AUTO_CREATE` | no | `true` | When forum is ready, create one topic per catalog project (paced + 429-retried). |
459
+ | `TOPIC_AI_CHAT_NAME` | no | `AI Chat` | Display name for the workspace topic. |
460
+ | `ALLOWED_TELEGRAM_BOTS` | no | — | Comma-separated sibling bot usernames the agent may call via bridge `bot_command` / `list_bots`. |
461
+ | `TELEGRAM_BOT_COMMANDS` | no | — | Optional command catalogs for sibling bots (compact or JSON; see `.env.example`). |
462
+ | `TELEGRAM_BOT_REPLY_TIMEOUT_MS` | no | `45000` | Hard timeout waiting for a sibling bot after `/cmd@bot`. |
463
+ | `TELEGRAM_BOT_SETTLE_MS` | no | `2000` | Quiet settle after the last message/edit from that bot. |
426
464
  | `MCP_PROBE_TIMEOUT_MS` | no | `8000` | Per-server timeout for the `/mcp` live health-check. |
427
465
  | `MCP_PROBE_CONCURRENCY` | no | `6` | How many MCP health probes run at once. |
428
466
  | `GROK_AUTO_RESTART` | no | `true` | Auto-restart the agent if it exits. |
@@ -475,11 +513,12 @@ src/
475
513
  ├── grok/ Grok bridge: headless client, JSONL types, models, session log
476
514
  ├── sessions/ Session discovery, history parser, live tail watcher
477
515
  ├── projects/ Project directory discovery
516
+ ├── forum/ Forum topic store, path bind, project icons
478
517
  ├── mcp/ MCP config (list/toggle) + live health probe
479
518
  ├── render/ Markdown→MarkdownV2, diffs, tool formatting, chunking
480
519
  ├── stream/ Incremental edit-streaming
481
520
  ├── service/ Cross-platform daemon (windows/linux/macos + selector)
482
- └── bot/ grammY bot, per-chat runtime, handlers
521
+ └── bot/ grammY bot, per-chat runtime, handlers, Telegram bridge
483
522
  ```
484
523
 
485
524
  ---
@@ -549,10 +588,13 @@ user. See [SECURITY.md](./SECURITY.md) for the full model.
549
588
  - [x] Device-code `/reauth` (no host browser) + real email labels from auth.json
550
589
  - [x] Rich per-kind tool-call detail (search / edit diffs / shell / MCP / …)
551
590
  - [x] README community sections — Contributors, Top Contributors, Stars, StarMapper
591
+ - [x] Forum project topics + AI Chat workspace (`TOPIC_GROUP_ID`)
592
+ - [x] Cross-topic Telegram bridge (`create_topic` / `set_path` / `send_prompt` / …)
593
+ - [x] Prompt anchors, post-turn suggestions, gated self-recheck
552
594
  - [ ] **Token & cost meter** — per-session token counts and an estimated spend tally
553
595
  - [ ] **Text-to-speech replies** — optionally speak answers back as voice notes
554
596
  - [ ] **Scheduled-task chaining & conditions** — run task B after A, or only if a command/file check passes
555
- - [ ] **Team mode** — multiple authorized users with per-user sessions, roles, and an audit log
597
+ - [ ] **Team mode** — roles and audit log beyond shared `ALLOWED_USERS` + forum topics
556
598
  - [ ] Localized bot UI (i18n)
557
599
  - [ ] Docker image with `grok` preinstalled
558
600
  - [ ] Webhook mode for serverless deployment
@@ -657,8 +699,9 @@ Grab the latest packaged build from the
657
699
  release ships a clean `grok-telegram-bot-<version>.zip` (no `node_modules` or
658
700
  secrets) plus GitHub's source archives. See [CHANGELOG.md](./CHANGELOG.md) for
659
701
  what changed in each version, **[docs/INSTALL.md](./docs/INSTALL.md)** for the
660
- full 1-click install guide, and **[docs/UPGRADE.md](./docs/UPGRADE.md)** for how
661
- to update an existing install (npm, zip, or source).
702
+ full 1-click install guide, **[docs/UPGRADE.md](./docs/UPGRADE.md)** for how to
703
+ update an existing install (npm, zip, or source), and
704
+ **[docs/GROUP.md](./docs/GROUP.md)** for forum project topics.
662
705
 
663
706
  ---
664
707
 
package/docs/GROUP.md ADDED
@@ -0,0 +1,225 @@
1
+ # Forum project group
2
+
3
+ Use a **Telegram forum supergroup** so each project gets its own topic. The bot
4
+ runs Grok sessions **in the bound project path** for that topic, while the
5
+ default **AI Chat** topic stays on your workspace (`GROK_WORKSPACE`).
6
+
7
+ This is optional. Private DMs with the bot still work exactly as before.
8
+
9
+ ---
10
+
11
+ ## Prerequisites
12
+
13
+ 1. A **supergroup** with **Topics** enabled (Telegram group settings → Topics).
14
+ 2. The bot is an **administrator** with **Manage Topics** (and enough rights to
15
+ post / pin when you want icons or setup announcements).
16
+ 3. Your bot token and allowlist configured as usual:
17
+ - `TELEGRAM_BOT_TOKEN`
18
+ - **`ALLOWED_USERS`** — required for groups. Unauthorized members are
19
+ **ignored silently** (no ⛔ spam). Empty allowlist with a forum group is
20
+ unsafe (any member could drive the host).
21
+ 4. `PROJECT_ROOTS` / catalog so project names resolve (same roots as `/projects`).
22
+
23
+ ---
24
+
25
+ ## Configure
26
+
27
+ In `.env` (or `~/.grok/tg/.env` for a global npm install):
28
+
29
+ ```ini
30
+ # Negative Telegram chat id of the forum supergroup
31
+ TOPIC_GROUP_ID=-100xxxxxxxxxx
32
+
33
+ # Default true: create one topic per catalog project (paced + 429-retried)
34
+ TOPIC_AUTO_CREATE=true
35
+
36
+ # Display name for the workspace topic (default AI Chat)
37
+ TOPIC_AI_CHAT_NAME=AI Chat
38
+
39
+ # Workspace used in General / AI Chat
40
+ GROK_WORKSPACE=C:\path\to\workspace
41
+
42
+ # Where /projects and exact-name topic binds look for folders
43
+ PROJECT_ROOTS=C:\path\to\Domains,H:\Lucru\Domains
44
+ ```
45
+
46
+ Restart the bot after changing these. On startup the bot **probes** the group:
47
+
48
+ | Probe result | Behavior |
49
+ |---|---|
50
+ | Not admin / no Manage Topics | Group **ignored** for topic features |
51
+ | Topics off | Best-effort try to enable; if Telegram has no API for it, group ignored until you enable Topics manually |
52
+ | Admin + Topics on | **Ready** — creates AI Chat (and optional project topics) |
53
+
54
+ Re-run setup any time from inside the group:
55
+
56
+ ```
57
+ /forum_setup
58
+ ```
59
+
60
+ You get a clear **ready** vs **disabled (reason)** status and the mapped topic count.
61
+
62
+ When the bot is later promoted to admin, it re-probes automatically (`my_chat_member`).
63
+
64
+ ---
65
+
66
+ ## Topic model
67
+
68
+ | Topic | Working directory | Typical use |
69
+ |---|---|---|
70
+ | **General** / **AI Chat** | `GROK_WORKSPACE` | Orchestration, cross-project planning, agent bridge actions |
71
+ | **Project topic** | Bound project path | All coding work for that folder |
72
+ | **User-created topic** | Bound after name/path match | Ad-hoc projects or new folders |
73
+
74
+ Messages you send **inside a topic** are prompts for a session whose `cwd` is
75
+ that topic’s path. Menus, model/reasoning picks, `/sessions`, `/running`, and
76
+ Stop are **topic-scoped** so one project does not steal another’s session.
77
+
78
+ In topics the persistent reply keyboard is unreliable, so use the **topic
79
+ inline menu** (Stop + Running + …) or slash commands (`/new`, `/stop`, …).
80
+
81
+ ---
82
+
83
+ ## Binding a topic to a project
84
+
85
+ ### Auto-bind (exact name only)
86
+
87
+ If you create a topic whose title **exactly** matches a catalog project name
88
+ (case-insensitive), the bot binds it immediately and confirms the path.
89
+
90
+ Fuzzy / partial matching is **not** used (it used to pick the wrong folder).
91
+
92
+ ### Manual bind
93
+
94
+ If there is no exact catalog match, the bot asks you to send:
95
+
96
+ - an **absolute directory path**, or
97
+ - an **exact** catalog project name
98
+
99
+ Examples:
100
+
101
+ ```text
102
+ H:\Lucru\Domains\MyApp
103
+ MyApp
104
+ ```
105
+
106
+ ### Agent bind (Telegram bridge)
107
+
108
+ From **AI Chat / General**, the agent can create topics and bind paths via a
109
+ fenced JSON block (see [Agent bridge](#agent-bridge-cross-topic-actions)).
110
+ Absolute paths that **do not exist yet are created on disk**, then bound
111
+ (new-project flow).
112
+
113
+ ### One path, one topic
114
+
115
+ A catalog path is only bound to **one** topic. If the same exact name/path is
116
+ already used, the bot says so and asks for another path or name.
117
+
118
+ ---
119
+
120
+ ## Day-to-day usage
121
+
122
+ 1. Open the **project topic** (or create one and bind it).
123
+ 2. Chat normally — each message is a Grok prompt in that project.
124
+ 3. **`/new`** or the menu **New** button starts a fresh session in that topic.
125
+ 4. **Stop** / `/stop` / `/cancel` only cancels **this topic’s** in-flight turn —
126
+ never the shared `grok agent` process (other topics keep running).
127
+ 5. Attach photos, documents, and (with STT configured) voice the same as in DM.
128
+ 6. User prompts are re-posted as **prompt anchors** with a searchable
129
+ `#prompt_…` tag; replies and Done messages thread to that anchor.
130
+
131
+ ### Multi-project orchestration
132
+
133
+ In **AI Chat**, ask the agent to open a project elsewhere, e.g. “Create a topic
134
+ for MyApp at `H:\Projects\MyApp` and scaffold a README there.” The agent emits
135
+ bridge actions; the bot creates the topic, binds the path, and can
136
+ `send_prompt` into that topic without you switching threads manually.
137
+
138
+ ---
139
+
140
+ ## Agent bridge (cross-topic actions)
141
+
142
+ On the **first prompt of a session** the bot teaches the agent a small protocol:
143
+ emit a fenced `json` block with a `"telegram"` array (up to **9** actions per
144
+ turn; up to **5** `send_prompt`). The bridge strips the fence from the chat and
145
+ may feed results back as a quiet system turn (not a second Done).
146
+
147
+ | Action | Purpose |
148
+ |---|---|
149
+ | `create_topic` | New forum topic; optional `path` binds immediately |
150
+ | `set_path` | Bind/rebind topic by title or `#threadId` |
151
+ | `send_prompt` | Inject a prompt into another topic (`ran` / `queued`; optional `new_session`) |
152
+ | `search_memory` | Search topic + session indexes |
153
+ | `list_bots` | List allowlisted sibling bots |
154
+ | `bot_command` | Call `/command@bot` and wait for that bot to settle |
155
+
156
+ Example (from General / AI Chat):
157
+
158
+ ```json
159
+ {
160
+ "telegram": [
161
+ {
162
+ "action": "create_topic",
163
+ "name": "MyApp",
164
+ "path": "H:\\Projects\\MyApp"
165
+ },
166
+ {
167
+ "action": "send_prompt",
168
+ "topic": "MyApp",
169
+ "prompt": "1) scaffold\n2) tests\n3) README"
170
+ }
171
+ ]
172
+ }
173
+ ```
174
+
175
+ `topic` may be the exact title, `#threadId`, `general`, or `ai chat`.
176
+
177
+ ---
178
+
179
+ ## Sibling bots (optional)
180
+
181
+ To let the agent call other Telegram bots you control:
182
+
183
+ ```ini
184
+ ALLOWED_TELEGRAM_BOTS=helperbot,other_bot
185
+ # Optional catalogs for list_bots / teaching:
186
+ # TELEGRAM_BOT_COMMANDS=helperbot:status,help;otherbot:start|Start,info
187
+ # TELEGRAM_BOT_REPLY_TIMEOUT_MS=45000
188
+ # TELEGRAM_BOT_SETTLE_MS=2000
189
+ ```
190
+
191
+ Only usernames on the allowlist can be invoked. Timeouts return `ok=false` and
192
+ do **not** count as Done.
193
+
194
+ ---
195
+
196
+ ## Access control
197
+
198
+ | Setting | Effect |
199
+ |---|---|
200
+ | `ALLOWED_USERS` set | Only listed user IDs can prompt (DM **and** group topics) |
201
+ | Not allowlisted | Updates ignored **silently** in the group |
202
+ | Empty allowlist | Anyone can use the bot — **do not combine with `TOPIC_GROUP_ID`** |
203
+
204
+ ---
205
+
206
+ ## Troubleshooting
207
+
208
+ | Symptom | What to check |
209
+ |---|---|
210
+ | Topics never created | Bot admin + Manage Topics; Topics enabled; `TOPIC_GROUP_ID` exact (negative id); `/forum_setup` |
211
+ | “Group ignored” | Status text from `/forum_setup` (`not_admin`, `not_forum`, …) |
212
+ | Wrong folder bound | Title must **exactly** match catalog name; re-bind with absolute path |
213
+ | Agent can’t create topics | Forum must be **ready**; work from AI Chat / General for orchestration |
214
+ | Unauthorized spam / silent ignore | Confirm your id in `ALLOWED_USERS`; others are silent by design |
215
+ | Stop kills everything | Should not — upgrade if an old build killed the shared agent; Stop is session-scoped |
216
+ | Large catalog slow | Bulk create is paced and 429-retried; re-run `/forum_setup` to continue |
217
+
218
+ ---
219
+
220
+ ## Related
221
+
222
+ - [README](../README.md) — full feature list and config table
223
+ - [INSTALL.md](./INSTALL.md) — first-time setup
224
+ - [UPGRADE.md](./UPGRADE.md) — updating an existing install
225
+ - `.env.example` — all forum / bridge env vars with comments
package/docs/INSTALL.md CHANGED
@@ -41,6 +41,9 @@ grok-tg run # run in the foreground (Ctrl-C to stop)
41
41
 
42
42
  > ⚠️ **Set `ALLOWED_USERS`** in `.env` to your Telegram user ID(s). Empty means
43
43
  > *anyone* who finds the bot can run commands on your machine.
44
+ >
45
+ > Optional: drive one project per **forum topic** with `TOPIC_GROUP_ID` — see
46
+ > **[GROUP.md](./GROUP.md)** after the bot is running.
44
47
 
45
48
  ### Startup options (`grok-tg <command>`)
46
49
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grok-telegram-bot",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Control the official Grok Build CLI from Telegram over the Agent Client Protocol (ACP). Sign in with your xAI account, switch projects, resume sessions, stream responses with diffs, queue follow-ups, manage multiple sign-ins, and run 24/7 as a cross-platform background service.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Cross-module intentional-exit flag so beforeExit keep-alive and the polling
3
+ * loop do not fight updater re-exec / fatal exits / SIGINT.
4
+ */
5
+ let intentional = false;
6
+ let reason = "";
7
+
8
+ /** Mark that the process is exiting on purpose (do not keep-alive). */
9
+ export function markIntentionalShutdown(why: string): void {
10
+ intentional = true;
11
+ reason = why;
12
+ }
13
+
14
+ export function isIntentionalShutdown(): boolean {
15
+ return intentional;
16
+ }
17
+
18
+ export function intentionalShutdownReason(): string {
19
+ return reason;
20
+ }