grok-telegram-bot 2.0.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 (106) hide show
  1. package/.env.example +135 -0
  2. package/CHANGELOG.md +598 -0
  3. package/LICENSE +21 -0
  4. package/README.md +644 -0
  5. package/bin/grok-tg.mjs +21 -0
  6. package/docs/INSTALL.md +153 -0
  7. package/docs/UPGRADE.md +253 -0
  8. package/docs/ops/RELEASE_CHECKLIST.md +39 -0
  9. package/package.json +74 -0
  10. package/scripts/setup.mjs +116 -0
  11. package/src/agents/catalog.ts +58 -0
  12. package/src/app/accounts.ts +162 -0
  13. package/src/app/auth-service.ts +136 -0
  14. package/src/app/grok-credentials.ts +103 -0
  15. package/src/app/instance-lock.ts +139 -0
  16. package/src/app/json-store.ts +54 -0
  17. package/src/app/reasoning.ts +30 -0
  18. package/src/app/settings-store.ts +38 -0
  19. package/src/app/stt.ts +53 -0
  20. package/src/app/types.ts +56 -0
  21. package/src/app/updater.ts +234 -0
  22. package/src/app/usage.ts +38 -0
  23. package/src/app/version.ts +41 -0
  24. package/src/bot/account-rotator.ts +52 -0
  25. package/src/bot/auth.ts +38 -0
  26. package/src/bot/bot.ts +225 -0
  27. package/src/bot/chat-controller.ts +317 -0
  28. package/src/bot/commands.ts +52 -0
  29. package/src/bot/deps.ts +67 -0
  30. package/src/bot/file-ingest.ts +190 -0
  31. package/src/bot/handlers/accounts.ts +220 -0
  32. package/src/bot/handlers/auth.ts +64 -0
  33. package/src/bot/handlers/control.ts +103 -0
  34. package/src/bot/handlers/document.ts +112 -0
  35. package/src/bot/handlers/history.ts +63 -0
  36. package/src/bot/handlers/kill.ts +54 -0
  37. package/src/bot/handlers/mcp.ts +206 -0
  38. package/src/bot/handlers/menu.ts +220 -0
  39. package/src/bot/handlers/message.ts +103 -0
  40. package/src/bot/handlers/photo.ts +123 -0
  41. package/src/bot/handlers/projects.ts +183 -0
  42. package/src/bot/handlers/running.ts +181 -0
  43. package/src/bot/handlers/session-card.ts +81 -0
  44. package/src/bot/handlers/session-kill.ts +95 -0
  45. package/src/bot/handlers/sessions.ts +148 -0
  46. package/src/bot/handlers/system.ts +51 -0
  47. package/src/bot/handlers/tasks.ts +224 -0
  48. package/src/bot/handlers/usage.ts +38 -0
  49. package/src/bot/handlers/voice.ts +55 -0
  50. package/src/bot/image-return.ts +69 -0
  51. package/src/bot/menu/ephemeral.ts +117 -0
  52. package/src/bot/menu/keyboard.ts +49 -0
  53. package/src/bot/menu/refresh.ts +13 -0
  54. package/src/bot/menu/status-panel.ts +173 -0
  55. package/src/bot/permission-service.ts +149 -0
  56. package/src/bot/prompt-content.ts +64 -0
  57. package/src/bot/prompt-retry.ts +70 -0
  58. package/src/bot/reauth-controller.ts +297 -0
  59. package/src/bot/registry.ts +186 -0
  60. package/src/bot/reply-context.ts +77 -0
  61. package/src/bot/session-fork.ts +35 -0
  62. package/src/bot/session-runtime.ts +1048 -0
  63. package/src/bot/telegram-io.ts +109 -0
  64. package/src/bot/typing.ts +35 -0
  65. package/src/bot/wizard/task-wizard.ts +214 -0
  66. package/src/cli.ts +126 -0
  67. package/src/config.ts +248 -0
  68. package/src/grok/client.ts +617 -0
  69. package/src/grok/models.ts +50 -0
  70. package/src/grok/session-log.ts +148 -0
  71. package/src/grok/transport.ts +51 -0
  72. package/src/grok/types.ts +136 -0
  73. package/src/index.ts +84 -0
  74. package/src/logger.ts +78 -0
  75. package/src/mcp/config.ts +120 -0
  76. package/src/mcp/probe.ts +218 -0
  77. package/src/mcp/types.ts +68 -0
  78. package/src/projects/manager.ts +99 -0
  79. package/src/render/chunk.ts +57 -0
  80. package/src/render/diff.ts +48 -0
  81. package/src/render/escape.ts +22 -0
  82. package/src/render/file-summary.ts +111 -0
  83. package/src/render/hashtags.ts +34 -0
  84. package/src/render/markdown.ts +130 -0
  85. package/src/render/progress-estimate.ts +63 -0
  86. package/src/render/progress.ts +80 -0
  87. package/src/render/subagent.ts +75 -0
  88. package/src/render/tool-call.ts +196 -0
  89. package/src/service/index.ts +24 -0
  90. package/src/service/linux.ts +85 -0
  91. package/src/service/macos.ts +101 -0
  92. package/src/service/platform.ts +64 -0
  93. package/src/service/types.ts +36 -0
  94. package/src/service/windows.ts +198 -0
  95. package/src/sessions/history.ts +225 -0
  96. package/src/sessions/process.ts +30 -0
  97. package/src/sessions/store.ts +133 -0
  98. package/src/sessions/tail.ts +86 -0
  99. package/src/sessions/types.ts +26 -0
  100. package/src/stream/streamer.ts +261 -0
  101. package/src/tasks/runner.ts +82 -0
  102. package/src/tasks/schedule.ts +142 -0
  103. package/src/tasks/scheduler.ts +53 -0
  104. package/src/tasks/store.ts +80 -0
  105. package/src/tasks/types.ts +33 -0
  106. package/tsconfig.json +19 -0
@@ -0,0 +1,153 @@
1
+ # 📦 Install guide
2
+
3
+ Get the Grok Telegram Bot running in a few minutes. Pick one of three ways:
4
+
5
+ - **[Option A — npm (recommended)](#option-a--npm-recommended)** — one command,
6
+ global `grok-tg` CLI, easiest to update.
7
+ - **[Option B — 1-click installer](#option-b--1-click-installer)** — download a
8
+ release zip and double-click the installer.
9
+ - **[Option C — manual / from source](#option-c--manual--from-source)** — clone
10
+ the repo (best for contributors).
11
+
12
+ ## Prerequisites
13
+
14
+ - **Grok CLI** installed and authenticated — run `grok chat` once to confirm.
15
+ - **Node.js 20+**.
16
+ - A **bot token** from [@BotFather](https://t.me/BotFather).
17
+ - Your **Telegram user ID** from [@userinfobot](https://t.me/userinfobot).
18
+
19
+ ---
20
+
21
+ ## Option A — npm (recommended)
22
+
23
+ Install the CLI once, globally. It ships with the `tsx` runtime, so there's no
24
+ build step.
25
+
26
+ ```bash
27
+ npm install -g grok-telegram-bot
28
+ ```
29
+
30
+ This gives you the **`grok-tg`** command (alias: `grok-telegram-bot`). Everything
31
+ operates on the **current folder** — your `.env`, `logs/` and `data/` live there,
32
+ so keep one folder per bot instance:
33
+
34
+ ```bash
35
+ mkdir my-bot && cd my-bot # a home for this bot's config + logs + data
36
+ grok-tg setup # auto-detects grok, writes ./.env
37
+ # (or pass values directly: grok-tg setup <BOT_TOKEN> <YOUR_USER_ID>)
38
+ # edit .env: set TELEGRAM_BOT_TOKEN and ALLOWED_USERS
39
+ grok-tg run # run in the foreground (Ctrl-C to stop)
40
+ ```
41
+
42
+ > ⚠️ **Set `ALLOWED_USERS`** in `.env` to your Telegram user ID(s). Empty means
43
+ > *anyone* who finds the bot can run commands on your machine.
44
+
45
+ ### Startup options (`grok-tg <command>`)
46
+
47
+ | Command | What it does |
48
+ |---|---|
49
+ | `grok-tg setup [token] [userId]` | Create/update `.env` in this folder (auto-detects `grok` + project roots). |
50
+ | `grok-tg run` | Run the bot in the foreground. |
51
+ | `grok-tg install` | Install + start a **24/7 background service** that autostarts on boot/login. |
52
+ | `grok-tg status` | Show install + running state of the service. |
53
+ | `grok-tg logs [n]` | Tail the last `n` log lines (default 100). |
54
+ | `grok-tg stop` / `restart` / `start` | Control the running service. |
55
+ | `grok-tg uninstall` | Stop + remove the background service. |
56
+ | `grok-tg help` | Show all commands. |
57
+
58
+ The background service is **user-level** and auto-detected per platform — a
59
+ hidden Scheduled Task on Windows, a `systemd` **user** service on Linux (with
60
+ linger for boot-without-login), and a launchd **LaunchAgent** on macOS. It runs
61
+ the bot bound to the folder you installed it from, so its `.env`/`logs`/`data`
62
+ stay in that folder.
63
+
64
+ Update later with `npm install -g grok-telegram-bot@latest` (global npm installs
65
+ also auto-update when idle). Full upgrade steps for every install type are in
66
+ **[UPGRADE.md](./UPGRADE.md)**.
67
+
68
+ > **Try without installing:** `npx grok-telegram-bot setup` then
69
+ > `npx grok-telegram-bot run` works too (slower first run).
70
+
71
+ ---
72
+
73
+ ## Option B — 1-click installer
74
+
75
+ Every [release](https://github.com/artickc/grok-telegram-bot/releases) ships a
76
+ clean `grok-telegram-bot-<version>.zip` (no `node_modules`, `.env`, logs or data)
77
+ that contains the 1-click installers.
78
+
79
+ 1. **Download** the latest `grok-telegram-bot-<version>.zip` and unzip it (or
80
+ `git clone` the repo).
81
+ 2. **Run the installer for your OS** from the unzipped folder. It installs
82
+ dependencies, auto-detects `grok`, writes `.env`, asks for your bot
83
+ token, and optionally sets up the 24/7 background service.
84
+
85
+ **Windows** — double-click `install.cmd`, or in a terminal:
86
+
87
+ ```powershell
88
+ .\install.cmd
89
+ ```
90
+
91
+ **Linux / macOS**:
92
+
93
+ ```bash
94
+ chmod +x install.sh && ./install.sh
95
+ ```
96
+
97
+ 3. **Set access control.** Open `.env` and set `ALLOWED_USERS` to your Telegram
98
+ user ID(s).
99
+
100
+ ---
101
+
102
+ ## Option C — manual / from source
103
+
104
+ Best for contributors (run with auto-reload, no build step).
105
+
106
+ ```bash
107
+ git clone https://github.com/artickc/grok-telegram-bot.git
108
+ cd grok-telegram-bot
109
+ npm install
110
+ npm run setup # auto-detects grok + project roots, writes .env
111
+ # edit .env: set TELEGRAM_BOT_TOKEN and ALLOWED_USERS
112
+ npm start # or: npm run dev (auto-reload)
113
+ ```
114
+
115
+ Run it 24/7 as a background service:
116
+
117
+ ```bash
118
+ npm run install:service # install + start, enable autostart on boot/login
119
+ npm run service -- status # show install + running state
120
+ npm run service -- logs 200 # tail the log file
121
+ npm run uninstall:service # stop + remove
122
+ ```
123
+
124
+ No build step — TypeScript runs directly via `tsx`.
125
+
126
+ ---
127
+
128
+ ## Updating
129
+
130
+ Already installed and want the newest version? See **[UPGRADE.md](./UPGRADE.md)**
131
+ — it covers upgrading npm installs (automatic or `npm install -g
132
+ grok-telegram-bot@latest`), 1-click/zip installs (replace files, keep your
133
+ `.env`/`data/`), and git/source checkouts (`git pull && npm install`), plus how
134
+ to restart after upgrading.
135
+
136
+ ## Configuration
137
+
138
+ All options live in `.env`. See the **Configuration** table in the
139
+ [README](../README.md) for every variable and its default. By default the bot
140
+ keeps `.env`, `logs/` and `data/` in the folder you run it from (override log
141
+ location with `LOG_DIR` / `LOG_FILE` and data with `DATA_DIR`).
142
+
143
+ ## Troubleshooting
144
+
145
+ - **Bot doesn't respond** — confirm your ID is in `ALLOWED_USERS` and the token
146
+ is correct; check `logs/grok-telegram-bot.log` (run `grok-tg logs`).
147
+ - **`grok` not found** — set `GROK_CLI_PATH` in `.env` to the binary's full
148
+ path.
149
+ - **`grok-tg: command not found`** — ensure your global npm bin dir is on `PATH`
150
+ (`npm bin -g`), or use `npx grok-telegram-bot <command>`.
151
+ - **"high volume of traffic" / transient errors** — the bot auto-retries with
152
+ backoff (6s → 60s) and shows the real error; switch model with the 🧩 menu or
153
+ `/model <id>` if a model stays busy.
@@ -0,0 +1,253 @@
1
+ # ⬆️ Upgrade guide
2
+
3
+ How to update Grok Telegram Bot to the newest version — for bots installed **via
4
+ npm** and for bots installed **without npm** (1-click zip installer or a
5
+ git/source checkout).
6
+
7
+ > **Your config is safe.** Upgrading only replaces the bot's *code*. Your
8
+ > settings, credentials and history — `.env`, `data/` (accounts, tasks, ephemeral
9
+ > state) and `logs/` — live **outside** the code and are never overwritten by an
10
+ > upgrade. Global npm installs keep them in `~/.grok/tg/`; zip/source installs
11
+ > keep them in the bot's folder.
12
+
13
+ Jump to your install type:
14
+
15
+ - **[Which install do I have?](#which-install-do-i-have)**
16
+ - **[A — Upgrade an npm install](#a--upgrade-an-npm-install)** (auto or manual)
17
+ - **[B — Upgrade a 1-click / zip install (no npm)](#b--upgrade-a-1-click--zip-install-no-npm)**
18
+ - **[C — Upgrade a git / source install](#c--upgrade-a-git--source-install)**
19
+ - **[Restart after upgrading](#restart-after-upgrading)**
20
+ - **[Switch a non-npm install over to npm](#switch-a-non-npm-install-over-to-npm)**
21
+ - **[Pin a version / roll back](#pin-a-version--roll-back)**
22
+ - **[Troubleshooting](#troubleshooting)**
23
+
24
+ ---
25
+
26
+ ## Which install do I have?
27
+
28
+ Check the current version and where the bot is running from:
29
+
30
+ ```bash
31
+ grok-tg --version 2>/dev/null || npm ls -g grok-telegram-bot
32
+ npm root -g # global npm modules dir — npm installs live under here
33
+ ```
34
+
35
+ - If `grok-telegram-bot` shows up under `npm root -g`, you have an **npm install** → **[Option A](#a--upgrade-an-npm-install)**.
36
+ - If you ran `install.cmd` / `install.sh` from an unzipped release folder, you have a **zip install** → **[Option B](#b--upgrade-a-1-click--zip-install-no-npm)**.
37
+ - If you `git clone`d the repo, you have a **source install** → **[Option C](#c--upgrade-a-git--source-install)**.
38
+
39
+ The latest published version is always on the
40
+ [**Releases**](https://github.com/artickc/grok-telegram-bot/releases) page and in
41
+ [CHANGELOG.md](../CHANGELOG.md).
42
+
43
+ ---
44
+
45
+ ## A — Upgrade an npm install
46
+
47
+ ### Automatic (default)
48
+
49
+ Global npm installs **update themselves**. With `AUTO_UPDATE=true` (the default),
50
+ the bot checks npm hourly and, **when it's fully idle** (no turn or task running,
51
+ no other active Grok session), it runs `npm install -g grok-telegram-bot@latest`,
52
+ restarts, and posts the new version's changelog in your chat (tagged `#update`).
53
+
54
+ You don't have to do anything. To control it, set in your `.env`:
55
+
56
+ ```ini
57
+ AUTO_UPDATE=true # set false to disable self-updates
58
+ UPDATE_CHECK_MS=3600000 # how often to check npm (ms)
59
+ ```
60
+
61
+ > Auto-update only applies to **global npm** installs. Zip/source checkouts are
62
+ > left untouched (see B and C).
63
+
64
+ ### Manual
65
+
66
+ To upgrade right now (or if you disabled auto-update):
67
+
68
+ ```bash
69
+ npm install -g grok-telegram-bot@latest
70
+ ```
71
+
72
+ Then restart the running bot so it loads the new code — see
73
+ **[Restart after upgrading](#restart-after-upgrading)**.
74
+
75
+ Your `.env`, `data/` and `logs/` in `~/.grok/tg/` (or your `GROK_TG_DIR`) are
76
+ untouched.
77
+
78
+ ---
79
+
80
+ ## B — Upgrade a 1-click / zip install (no npm)
81
+
82
+ Zip installs **do not auto-update** — you replace the files yourself. The steps
83
+ are the same ones you used to install, plus keeping your config. Your `.env`,
84
+ `data/` and `logs/` live **inside the bot's folder**, so the goal is to swap the
85
+ code while preserving those.
86
+
87
+ 1. **Stop the service** (from your current bot folder):
88
+
89
+ ```bash
90
+ npm run service -- stop # or: grok-tg stop
91
+ ```
92
+
93
+ 2. **Download** the latest `grok-telegram-bot-<version>.zip` from the
94
+ [Releases](https://github.com/artickc/grok-telegram-bot/releases) page and
95
+ **unzip it into a fresh folder**.
96
+
97
+ 3. **Carry your config across** — copy these from the OLD folder into the NEW one:
98
+
99
+ - `.env` (your token, allowed users, settings) — **required**
100
+ - `data/` (saved accounts, scheduled tasks) — recommended
101
+ - `logs/` — optional
102
+
103
+ **Windows (PowerShell)**
104
+
105
+ ```powershell
106
+ Copy-Item ..\old-bot\.env .\ -Force
107
+ Copy-Item ..\old-bot\data .\ -Recurse -Force
108
+ ```
109
+
110
+ **Linux / macOS**
111
+
112
+ ```bash
113
+ cp ../old-bot/.env ./ && cp -r ../old-bot/data ./
114
+ ```
115
+
116
+ 4. **Install deps + service** from the new folder:
117
+
118
+ ```bash
119
+ # Windows: .\install.cmd Linux/macOS: ./install.sh
120
+ # or manually:
121
+ npm install
122
+ npm run install:service # re-registers the service to the new folder
123
+ ```
124
+
125
+ `install.cmd` / `install.sh` detect the copied `.env` and skip re-asking for
126
+ your token.
127
+
128
+ > **Tip:** upgrading zip installs by hand every release is tedious. Consider
129
+ > **[switching to npm](#switch-a-non-npm-install-over-to-npm)** for one-command
130
+ > (and automatic) updates.
131
+
132
+ ---
133
+
134
+ ## C — Upgrade a git / source install
135
+
136
+ A source checkout upgrades with `git`. Your `.env`, `data/` and `logs/` are
137
+ git-ignored, so they survive a pull untouched.
138
+
139
+ ```bash
140
+ cd grok-telegram-bot
141
+ git pull # fetch the latest code
142
+ npm install # pick up any new/updated dependencies
143
+ ```
144
+
145
+ Then restart the bot — see **[Restart after upgrading](#restart-after-upgrading)**.
146
+
147
+ If you're on a fork or have local changes, stash them first (`git stash`), pull,
148
+ `npm install`, then `git stash pop`.
149
+
150
+ ---
151
+
152
+ ## Restart after upgrading
153
+
154
+ New code only takes effect once the running process restarts. Pick what matches
155
+ how you run the bot:
156
+
157
+ | How you run it | Restart command |
158
+ |---|---|
159
+ | Background service (npm) | `grok-tg restart` |
160
+ | Background service (zip/source) | `npm run service -- restart` |
161
+ | Foreground (`grok-tg run` / `npm start`) | stop with Ctrl-C, start again |
162
+
163
+ Confirm it's healthy afterwards:
164
+
165
+ ```bash
166
+ grok-tg status # or: npm run service -- status
167
+ grok-tg logs 100 # or: npm run service -- logs 100
168
+ ```
169
+
170
+ > Auto-update (Option A) restarts for you, so a manual restart is only needed
171
+ > after a **manual** upgrade.
172
+
173
+ ---
174
+
175
+ ## Switch a non-npm install over to npm
176
+
177
+ Recommended if you're tired of manual zip upgrades — npm gives you one-command
178
+ and automatic updates.
179
+
180
+ 1. **Install the CLI globally:**
181
+
182
+ ```bash
183
+ npm install -g grok-telegram-bot
184
+ ```
185
+
186
+ 2. **Move your config to the canonical home** `~/.grok/tg/` (run `grok-tg setup
187
+ --path` to print the exact location), so npm runs find the same settings:
188
+
189
+ **Windows (PowerShell)**
190
+
191
+ ```powershell
192
+ $dst = "$env:USERPROFILE\.grok\tg"; New-Item -ItemType Directory -Force $dst | Out-Null
193
+ Copy-Item .\.env "$dst\" -Force
194
+ Copy-Item .\data "$dst\" -Recurse -Force
195
+ ```
196
+
197
+ **Linux / macOS**
198
+
199
+ ```bash
200
+ mkdir -p ~/.grok/tg && cp .env ~/.grok/tg/ && cp -r data ~/.grok/tg/
201
+ ```
202
+
203
+ (Alternatively keep your folder and point at it with `GROK_TG_DIR`.)
204
+
205
+ 3. **Remove the old service and install the npm one:**
206
+
207
+ ```bash
208
+ # in the OLD folder:
209
+ npm run uninstall:service
210
+ # then, from anywhere:
211
+ grok-tg install
212
+ ```
213
+
214
+ From now on, upgrade with `npm install -g grok-telegram-bot@latest` (or let
215
+ auto-update handle it).
216
+
217
+ ---
218
+
219
+ ## Pin a version / roll back
220
+
221
+ Install any specific version (e.g. to roll back a bad upgrade):
222
+
223
+ ```bash
224
+ npm install -g grok-telegram-bot@1.7.2
225
+ ```
226
+
227
+ To stop the bot from moving off a pinned version, set `AUTO_UPDATE=false` in
228
+ `.env` and restart. For zip/source installs, download the matching release zip or
229
+ `git checkout v1.7.2`.
230
+
231
+ ---
232
+
233
+ ## Troubleshooting
234
+
235
+ - **Still on the old version after upgrading** — you didn't restart. Run
236
+ `grok-tg restart` (npm) or `npm run service -- restart` (zip/source), then
237
+ check `grok-tg status`.
238
+ - **`grok-tg: command not found`** — ensure your global npm bin dir is on `PATH`
239
+ (`npm bin -g`), or use `npx grok-telegram-bot <command>`.
240
+ - **Auto-update never fires** — it only runs for **global npm** installs, and
241
+ only while the bot is **idle**; check `AUTO_UPDATE` is `true` and see the log
242
+ (`grok-tg logs 200`) for a `waiting for idle` line.
243
+ - **Lost settings after a zip upgrade** — you upgraded into a new folder without
244
+ copying `.env`/`data/`. Copy them from the old folder (Option B, step 3) and
245
+ restart.
246
+ - **Two bots replying / "⛔ Not authorized"** — an old process is still polling.
247
+ The bot is single-instance per token, so just start the new one
248
+ (`grok-tg restart`) and it terminates the ghost.
249
+
250
+ ---
251
+
252
+ See also: **[docs/INSTALL.md](./INSTALL.md)** for first-time setup and
253
+ [CHANGELOG.md](../CHANGELOG.md) for what changed in each version.
@@ -0,0 +1,39 @@
1
+ # Release checklist
2
+
3
+ A release ships a **batch of merged pull requests** as one versioned tag. The
4
+ heavy lifting (zip + notes + publish) is automated by
5
+ `.github/workflows/release.yml`; this checklist covers the manual steps.
6
+
7
+ ## 1. Pre-flight (on `main`)
8
+
9
+ - [ ] All intended PRs for this batch are **merged into `main`**.
10
+ - [ ] `git checkout main && git pull` — local `main` matches origin.
11
+ - [ ] `npm ci && npm run typecheck` passes with no errors.
12
+ - [ ] Manual smoke test where relevant (`npm start`, basic Telegram round-trip).
13
+
14
+ ## 2. Changelog & version
15
+
16
+ - [ ] Add a new `## [X.Y.Z] - YYYY-MM-DD` section to `CHANGELOG.md` with the
17
+ user-facing features/fixes (this becomes the GitHub Release notes).
18
+ - [ ] Add the matching link reference at the bottom of `CHANGELOG.md`.
19
+ - [ ] Choose the bump per SemVer: `patch` (fixes), `minor` (features),
20
+ `major` (breaking).
21
+
22
+ ## 3. Tag & publish
23
+
24
+ ```bash
25
+ npm version minor # bumps package.json, commits, creates the v* tag
26
+ git push --follow-tags # pushing the tag triggers the Release workflow
27
+ ```
28
+
29
+ - [ ] Watch the **Release** workflow in the Actions tab finish green.
30
+ - [ ] Confirm the GitHub Release exists with:
31
+ - [ ] the correct title (`vX.Y.Z`),
32
+ - [ ] notes matching the CHANGELOG section,
33
+ - [ ] the attached `grok-telegram-bot-X.Y.Z.zip`,
34
+ - [ ] GitHub's auto-generated Source code archives.
35
+
36
+ ## 4. Post-release
37
+
38
+ - [ ] Announce / update any docs that reference the version.
39
+ - [ ] Open the next batch of feature branches off the new `main`.
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "grok-telegram-bot",
3
+ "version": "2.0.0",
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
+ "type": "module",
6
+ "main": "src/index.ts",
7
+ "bin": {
8
+ "grok-tg": "bin/grok-tg.mjs",
9
+ "grok-telegram-bot": "bin/grok-tg.mjs"
10
+ },
11
+ "files": [
12
+ "src",
13
+ "bin",
14
+ "scripts",
15
+ "tsconfig.json",
16
+ ".env.example",
17
+ "CHANGELOG.md",
18
+ "docs"
19
+ ],
20
+ "engines": {
21
+ "node": ">=20"
22
+ },
23
+ "scripts": {
24
+ "start": "tsx src/index.ts",
25
+ "dev": "tsx watch src/index.ts",
26
+ "typecheck": "tsc --noEmit",
27
+ "test": "node --import tsx --test test/**/*.test.ts",
28
+ "prepublishOnly": "npm run typecheck",
29
+ "setup": "node scripts/setup.mjs",
30
+ "service": "tsx src/cli.ts",
31
+ "install:service": "tsx src/cli.ts install",
32
+ "uninstall:service": "tsx src/cli.ts uninstall",
33
+ "service:status": "tsx src/cli.ts status",
34
+ "service:logs": "tsx src/cli.ts logs"
35
+ },
36
+ "keywords": [
37
+ "grok",
38
+ "grok-cli",
39
+ "xai",
40
+ "telegram",
41
+ "telegram-bot",
42
+ "ai-agent",
43
+ "ai-coding-assistant",
44
+ "mobile-coding",
45
+ "chatops",
46
+ "devtools",
47
+ "daemon",
48
+ "cross-platform",
49
+ "grammy"
50
+ ],
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "git+https://github.com/artickc/grok-telegram-bot.git"
54
+ },
55
+ "homepage": "https://github.com/artickc/grok-telegram-bot#readme",
56
+ "bugs": {
57
+ "url": "https://github.com/artickc/grok-telegram-bot/issues"
58
+ },
59
+ "license": "MIT",
60
+ "dependencies": {
61
+ "diff": "^7.0.0",
62
+ "dotenv": "^16.4.7",
63
+ "grammy": "^1.30.0",
64
+ "tsx": "^4.19.2"
65
+ },
66
+ "optionalDependencies": {
67
+ "@homebridge/node-pty-prebuilt-multiarch": "0.13.1"
68
+ },
69
+ "devDependencies": {
70
+ "@types/diff": "^7.0.0",
71
+ "@types/node": "^22.10.0",
72
+ "typescript": "^5.7.2"
73
+ }
74
+ }
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Easy setup: creates/updates the bot's .env, auto-detects the `grok` binary
4
+ * and sensible PROJECT_ROOTS, and optionally writes the bot token / user id:
5
+ *
6
+ * node scripts/setup.mjs [--path] [--instance <dir>] [<TELEGRAM_BOT_TOKEN> [ALLOWED_USER_ID]]
7
+ *
8
+ * By default the .env lives in the canonical, path-independent home
9
+ * `~/.grok/tg/.env`, so the bot loads the SAME config no matter where it's
10
+ * started from. `--path` just prints the resolved .env path and exits.
11
+ */
12
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
13
+ import { homedir } from "node:os";
14
+ import { dirname, join, resolve } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+
17
+ const root = join(dirname(fileURLToPath(import.meta.url)), "..");
18
+ const examplePath = join(root, ".env.example");
19
+ const CANONICAL_DIR = join(homedir(), ".grok", "tg");
20
+
21
+ function expandHome(p) {
22
+ if (p === "~") return homedir();
23
+ if (p.startsWith("~/") || p.startsWith("~\\")) return join(homedir(), p.slice(2));
24
+ return p;
25
+ }
26
+
27
+ /** Mirror of config.ts resolveInstanceDir() so setup writes EXACTLY where the
28
+ * bot will read from. Keep the two in sync. */
29
+ function resolveInstanceDir() {
30
+ const flag = process.argv.indexOf("--instance");
31
+ if (flag !== -1 && process.argv[flag + 1]) return resolve(process.argv[flag + 1]);
32
+ const envDir = (process.env.GROK_TG_DIR || process.env.GROK_TG_CWD || "").trim();
33
+ if (envDir) return resolve(expandHome(envDir));
34
+ if (existsSync(join(process.cwd(), ".env"))) return process.cwd();
35
+ return CANONICAL_DIR;
36
+ }
37
+
38
+ const argv = process.argv.slice(2);
39
+ let pathOnly = false;
40
+ const positionals = [];
41
+ for (let i = 0; i < argv.length; i++) {
42
+ const a = argv[i];
43
+ if (a === "--path") pathOnly = true;
44
+ else if (a === "--instance") i++;
45
+ else positionals.push(a);
46
+ }
47
+ const [tokenArg, userArg] = positionals;
48
+
49
+ const instanceDir = resolveInstanceDir();
50
+ const envPath = join(instanceDir, ".env");
51
+
52
+ if (pathOnly) {
53
+ console.log(envPath);
54
+ process.exit(0);
55
+ }
56
+
57
+ mkdirSync(instanceDir, { recursive: true });
58
+
59
+ function detectGrok() {
60
+ const home = homedir();
61
+ const exe = process.platform === "win32" ? "grok.exe" : "grok";
62
+ const candidates = [
63
+ join(home, ".grok", "bin", exe),
64
+ join(home, ".local", "bin", "grok"),
65
+ "/usr/local/bin/grok",
66
+ "/opt/homebrew/bin/grok",
67
+ ];
68
+ return candidates.find((p) => existsSync(p)) || "";
69
+ }
70
+
71
+ function detectRoots() {
72
+ const guesses = ["H:\\Lucru\\Domains", "C:\\Lucru\\Domains", join(homedir(), "projects")];
73
+ return guesses.filter((p) => existsSync(p));
74
+ }
75
+
76
+ let env = existsSync(envPath) ? readFileSync(envPath, "utf-8") : readFileSync(examplePath, "utf-8");
77
+
78
+ function setVar(key, value) {
79
+ if (value === undefined || value === "") return;
80
+ const re = new RegExp(`^${key}=.*$`, "m");
81
+ const line = `${key}=${value}`;
82
+ env = re.test(env) ? env.replace(re, line) : `${env.trimEnd()}\n${line}\n`;
83
+ }
84
+
85
+ const grok = detectGrok();
86
+ if (grok) {
87
+ setVar("GROK_CLI_PATH", grok);
88
+ console.log(`\u2713 Found grok: ${grok}`);
89
+ } else {
90
+ console.log("! grok not auto-detected \u2014 set GROK_CLI_PATH in .env or ensure it's on PATH.");
91
+ }
92
+
93
+ const roots = detectRoots();
94
+ if (roots.length) {
95
+ setVar("PROJECT_ROOTS", roots.join(","));
96
+ console.log(`\u2713 PROJECT_ROOTS: ${roots.join(", ")}`);
97
+ }
98
+
99
+ if (tokenArg) {
100
+ setVar("TELEGRAM_BOT_TOKEN", tokenArg);
101
+ console.log("\u2713 Wrote TELEGRAM_BOT_TOKEN");
102
+ }
103
+ if (userArg) {
104
+ setVar("ALLOWED_USERS", userArg);
105
+ console.log(`\u2713 Wrote ALLOWED_USERS=${userArg}`);
106
+ }
107
+
108
+ writeFileSync(envPath, env, "utf-8");
109
+ console.log(`\n\u2713 .env written to ${envPath}`);
110
+ console.log(" (loaded from here no matter which folder you start the bot in)");
111
+
112
+ if (!/^TELEGRAM_BOT_TOKEN=.+/m.test(env)) {
113
+ console.log("\nNext: open .env, paste your bot token from @BotFather, then sign in with `grok login` (or /reauth). Then run `grok-tg run`.");
114
+ } else {
115
+ console.log("\nReady! Sign in with `grok login` if you haven't, then run `grok-tg run` (or `npm start`).");
116
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Discover Grok sub-agents. Grok ships built-in sub-agents (general, explore,
3
+ * vision, verify, computer) and supports custom ones defined under `subAgents`
4
+ * in `~/.grok/user-settings.json`. There is no headless `--agent` flag, so the
5
+ * bot surfaces these for visibility; the model delegates to them via its own
6
+ * `task`/`delegate` tools during a turn.
7
+ */
8
+ import { readFileSync } from "node:fs";
9
+ import { homedir } from "node:os";
10
+ import { join } from "node:path";
11
+ import { createLogger } from "../logger.js";
12
+
13
+ const log = createLogger("agents");
14
+
15
+ export interface AgentInfo {
16
+ name: string;
17
+ description?: string;
18
+ scope: "project" | "global" | "builtin";
19
+ }
20
+
21
+ const BUILTINS: AgentInfo[] = [
22
+ { name: "general", description: "General-purpose sub-agent", scope: "builtin" },
23
+ { name: "explore", description: "Read-only codebase exploration", scope: "builtin" },
24
+ { name: "vision", description: "Image understanding", scope: "builtin" },
25
+ { name: "verify", description: "Build/run/test verification", scope: "builtin" },
26
+ ];
27
+
28
+ interface SubAgentEntry {
29
+ name?: string;
30
+ instruction?: string;
31
+ description?: string;
32
+ }
33
+
34
+ function readSubAgents(path: string, scope: "project" | "global", out: Map<string, AgentInfo>): void {
35
+ let raw: string;
36
+ try {
37
+ raw = readFileSync(path, "utf-8");
38
+ } catch {
39
+ return;
40
+ }
41
+ try {
42
+ const json = JSON.parse(raw) as { subAgents?: SubAgentEntry[] };
43
+ for (const a of json.subAgents ?? []) {
44
+ if (!a.name || out.has(a.name)) continue;
45
+ out.set(a.name, { name: a.name, description: a.description || a.instruction, scope });
46
+ }
47
+ } catch (e) {
48
+ log.debug(`skip ${path}:`, (e as Error).message);
49
+ }
50
+ }
51
+
52
+ export function listAgents(projectPath?: string): AgentInfo[] {
53
+ const found = new Map<string, AgentInfo>();
54
+ if (projectPath) readSubAgents(join(projectPath, ".grok", "settings.json"), "project", found);
55
+ readSubAgents(join(homedir(), ".grok", "user-settings.json"), "global", found);
56
+ const custom = [...found.values()].sort((a, b) => a.name.localeCompare(b.name));
57
+ return [...BUILTINS, ...custom];
58
+ }