kiro-telegram-bot 1.6.0 → 1.7.2

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.
package/.env.example CHANGED
@@ -61,6 +61,17 @@ AGENT_IMAGES_MAX=8
61
61
  # so the chat isn't silent during delegated/parallel work. true/false
62
62
  SHOW_SUBAGENTS=true
63
63
 
64
+ # Task-progress bar. SHOW_PROGRESS asks the agent to end each message with a
65
+ # {progress: N%} marker, which the bot hides and renders as a green 0–100% bar
66
+ # on the live message, session cards, and the status panel.
67
+ # That marker is only an instruction the model can ignore (common on long,
68
+ # tool-heavy turns or weaker/free models), leaving the bar empty. PROGRESS_FALLBACK
69
+ # then shows a bot-computed bar derived from REAL activity (completed tool calls,
70
+ # streamed output, elapsed time) whenever the agent emits no marker, so a live bar
71
+ # still advances. The agent's own marker, when present, always takes precedence.
72
+ SHOW_PROGRESS=true
73
+ PROGRESS_FALLBACK=true
74
+
64
75
  # When you control several sessions at once and switch between them, deliver a
65
76
  # session's "Done" summary even while that session is in the background (you're
66
77
  # viewing another one) — clearly marked "From other session" with a short
package/CHANGELOG.md CHANGED
@@ -7,6 +7,190 @@ 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
+ ## [1.7.2] - 2026-06-25
11
+
12
+ The **"steady & solo"** release — a self-computing progress bar that never spams
13
+ empty bubbles, a single-instance guard that clears ghost processes, a
14
+ path-independent `~/.kiro/tg/` config home, a polished pinned status panel, and
15
+ fixes for the false idle-timeout during subagent (translation) work and the bot
16
+ rejecting its own pin messages as "Not authorized".
17
+
18
+ ### Added
19
+
20
+ - **📈 Bot-computed task-progress fallback (`PROGRESS_FALLBACK`).** The
21
+ `{progress: N%}` bar previously depended entirely on the agent emitting the
22
+ marker — and that marker is only an *instruction* the model can ignore, so
23
+ weaker/free models and long, tool-heavy turns often emitted none, leaving the
24
+ bar empty for the whole turn. Now, when `SHOW_PROGRESS` is on but no marker
25
+ arrives, the bot renders a **computed** bar derived from **real activity**
26
+ (completed tool calls, streamed output, elapsed time): it starts low, climbs in
27
+ realistic increments via a saturating curve capped at 90 % while running, and
28
+ fills to 100 % when the turn completes successfully. The estimate is monotonic
29
+ by construction, and the agent's own marker — when present — always takes
30
+ precedence (the fallback stops contributing the moment a real value arrives).
31
+ The bar is only ever **appended to real streamed content** — it never produces
32
+ a standalone/empty bubble — and the live status panel shows it on its own.
33
+ Disable with `PROGRESS_FALLBACK=false`.
34
+ - **🏠 Canonical, path-independent config home (`~/.kiro/tg/`).** The `.env`
35
+ (plus `logs/`, `data/`) now lives in `~/.kiro/tg/` by default, so the bot loads
36
+ the **same** configuration no matter which folder you start it from — no more
37
+ "works from this directory, broken from that one". Resolution order is
38
+ `--instance` → `KIRO_TG_DIR` → a `.env` in the current folder (so existing
39
+ per-folder checkouts keep working) → `~/.kiro/tg`. `kiro-tg setup` writes there
40
+ by default, and **`kiro-tg setup --path`** prints the resolved `.env` location.
41
+ - **🔒 Single-instance guard, per bot token (`KIRO_TG_SINGLE_INSTANCE`).** On
42
+ startup the bot takes a token-scoped lock under `~/.kiro/tg/locks/`; if a
43
+ still-alive **ghost/duplicate** is already polling Telegram with that token, it
44
+ is terminated (and its child tree on Windows) so the fresh process — with your
45
+ current `.env` — becomes the sole `getUpdates` consumer.
46
+
47
+ ### Changed
48
+
49
+ - **🧭 Polished status panel.** The pinned status message was redesigned for
50
+ readability: the redundant "Kiro — Status" header is gone, the **progress bar
51
+ is the first line** (so the collapsed pin preview shows how far along the
52
+ current task is), and the cramped space-padded columns are replaced with clean
53
+ emoji-led fields separated by ` | ` across three short lines — activity
54
+ (`state | queue | sessions | watching | subagents`), location
55
+ (`project | session | context`) and config (`agent | reasoning | model`).
56
+ Counters that don't apply (empty queue, single session) are hidden instead of
57
+ shown as `0`.
58
+ - **🧹 Progress clears when a turn ends.** The task-progress value is now reset
59
+ when a turn finishes, stops, or errors, so the bar is removed from the status
60
+ panel, session cards and switch messages once the work is done (the finished
61
+ streamed message keeps its own frozen bar as a record).
62
+ - **🫥 Status panel only while working.** The pinned status panel now appears
63
+ while a turn is running (or a follow-up is queued) and is **removed when the
64
+ session goes idle**, so the chat stays clean between tasks. The full state is
65
+ still available on demand via **Status** in the menu (`/status`).
66
+
67
+ ### Fixed
68
+
69
+ - **⛔ Spurious "Not authorized" from the bot's own pin messages.** The auth
70
+ gate replied "⛔ Not authorized" to **every** update whose sender wasn't an
71
+ allowed user — including the bot's **own** service messages. Since the status
72
+ panel is pinned/unpinned, each pin emits a `pinned_message` service update
73
+ authored by the bot, so the gate kept rejecting itself (interleaved with
74
+ normal replies). The gate now ignores updates that aren't a real user action
75
+ (the bot's own/`is_bot` updates, service messages, and updates with no
76
+ `from`), and those pin service messages are deleted on arrival so they no
77
+ longer clutter the chat. Genuine unauthorized users still get one clear reply.
78
+ - **⛔ Phantom "Not authorized" from a ghost process.** A leftover bot started
79
+ from another folder kept answering with a stale `.env` (e.g. an outdated
80
+ `ALLOWED_USERS`), rejecting you while the new process couldn't poll (Telegram
81
+ 409 Conflict). The single-instance guard above clears the ghost on startup. A
82
+ plain `kiro-tg run` still **yields** to an already-running background service
83
+ rather than fighting it (no restart/kill loop).
84
+ - **⏱️ False "No agent activity … giving up" during subagent delegation.** The
85
+ prompt idle-timeout tracked activity per session, but subagents (e.g. parallel
86
+ translation crews) stream on their own session ids, so a main turn that
87
+ delegated heavy work looked "silent" and was killed after ~15 min even though
88
+ the agent was busy — and the next message then collided with the still-running
89
+ turn as `-32603 … dispatch failure`. The watchdog now uses a **process-wide
90
+ activity clock** (any session/subagent stream, metadata, or subagent status
91
+ refreshes it), so a delegating turn stays alive while its subagents work; only
92
+ a genuinely silent agent trips it. When it does fire (idle or the hard cap),
93
+ the agent's turn is now **cancelled** so the session is immediately reusable.
94
+ `dispatch failure` and common connection/stream errors are also now classified
95
+ as **transient**, so they retry/auto-fork instead of surfacing as a dead end.
96
+
97
+ ## [1.7.1] - 2026-06-24
98
+
99
+ The **"sign in your way"** release — `/reauth` now lets you pick how you log in
100
+ (Builder ID, Google, GitHub or IAM Identity Center) on one tidy status card, and
101
+ the live task-progress bar climbs steadily instead of appearing only at the end.
102
+
103
+ ### Added
104
+
105
+ - **🔐 `/reauth` login-method picker.** Re-authentication now opens with a
106
+ **picker** — **Builder ID** (free), **Google**, **GitHub**, or **IAM Identity
107
+ Center** (Pro) — driven on a **single, self-animated status message** with
108
+ inline **Cancel · Retry · Change method · Restart agent** controls, so the chat
109
+ no longer fills with raw spinner frames. **IAM Identity Center** sign-in is now
110
+ fully supported: the bot asks for your **start URL + region** and drives the
111
+ CLI's interactive prompts inside a pseudo-terminal (optional
112
+ `@homebridge/node-pty-prebuilt-multiarch` dependency; a clear message tells you
113
+ to run `npm install` if it's missing). The device-verification URL + code still
114
+ stream to the chat for every method. Power users can skip the picker by passing
115
+ flags directly, e.g. `/reauth --license pro --identity-provider <url> --region <region>`.
116
+
117
+ ### Changed
118
+
119
+ - **📈 Stricter, steadier task-progress reporting.** The agent instruction behind
120
+ the `{progress: N%}` marker is now far more rigorous: a marker is required on
121
+ **every** message (not only the last), the number must be **computed from real
122
+ step completion** and is **monotonic** (never decreases within a task), and
123
+ **100 %** is reserved for work that is fully complete *and verified*. The bar
124
+ now advances in realistic increments instead of jumping to a value at the very
125
+ end.
126
+
127
+ ### Fixed
128
+
129
+ - **🔁 `/reauth` agent-restart race** (`agent restart failed: kiro-cli acp exited
130
+ (code null)`). Logging out and restarting could let the **old** agent process's
131
+ exit fail the **new** connection's `initialize` and even trigger a competing
132
+ auto-restart. The ACP client now **fully tears down** the previous process
133
+ (ignoring the exit of a process it has already replaced) **before** spawning a
134
+ fresh one, and `/reauth` takes the agent down and **waits** before logging out —
135
+ so a deliberate restart is clean and the new identity sticks.
136
+ - **🪪 Stale identity after re-login.** On logout the bot now also **clears Kiro's
137
+ cached auth token** (`~/.aws/sso/cache/kiro-auth-token.json`), so the next login
138
+ performs a genuine device-flow authentication instead of silently reusing the
139
+ previous account's refreshable token.
140
+
141
+ ## [1.7.0] - 2026-06-23
142
+
143
+ The **"take control"** release — stop a runaway session by PID, re-authenticate
144
+ Kiro from your phone, watch a live task-progress bar, and install on Windows
145
+ without admin.
146
+
147
+ ### Added
148
+
149
+ - **🛑 Kill a session / PID from its card (`/sessions`, `/active`).** Every
150
+ **live** session card now has a **`🛑 Kill · pid N`** button that terminates
151
+ that session's process — and its whole child tree on Windows (`taskkill /T`).
152
+ It's guarded by an inline **confirm** (Kill / Cancel) since it's destructive,
153
+ the bot's **own** agent process is never offered (killing it would take the
154
+ bot down), and the session state is re-read at every step so a session that
155
+ already stopped reports "no longer running" instead of a phantom kill. The
156
+ existing `/killall` (stop every active session at once) is unchanged and now
157
+ shares the same kill logic.
158
+ - **🔐 Re-authenticate Kiro from Telegram (`/reauth`).** Logs out
159
+ (`kiro-cli logout`) and starts a fresh **device-flow** login
160
+ (`kiro-cli login --use-device-flow`) — the verification URL + code are
161
+ **streamed into the chat** so you complete it on your own device — then
162
+ **restarts the agent** so it picks up the new credentials. Refused while a
163
+ turn is in flight (logging out would break it) and serialised so two runs
164
+ can't overlap. Pass-through flags are supported, e.g.
165
+ `/reauth --license free` or `/reauth --license pro --region <r> --identity-provider <url>`.
166
+ - **📈 Live task-progress bar (`SHOW_PROGRESS`, on by default).** The agent is
167
+ asked to end each message with a `{progress: N%}` marker; the bot **parses and
168
+ hides** it and renders a **green 0–100 % loading bar** (`🟩🟩🟩⬜⬜⬜ 50%`,
169
+ all-green ✅ at 100 %) at the bottom of the **live message**, in the pinned
170
+ **status panel**, and on **`/running` and `/sessions` cards** — so you can see
171
+ how far along the current task is. Markers (and the instruction) are also
172
+ stripped from history, unread replays, previews and fork-priming, so the raw
173
+ plumbing never shows. Disable with `SHOW_PROGRESS=false`.
174
+ - **🔀 "Switch to this session" on background pings.** A **`📨 From other
175
+ session`** Done/error notification now carries a **🔀 Switch to this session**
176
+ button that brings that session to the foreground in one tap.
177
+
178
+ ### Changed
179
+
180
+ - **🪟 Windows install no longer needs admin.** `kiro-tg install` used to fail
181
+ with **`schtasks create failed: ERROR: Access is denied`** for a normal user,
182
+ because registering a **logon-triggered** Scheduled Task is a privileged
183
+ operation. The installer now falls back to a hidden per-user **Startup-folder**
184
+ launcher (runs at logon, **no elevation**) when the task can't be created; an
185
+ **elevated** run still uses the nicer hidden Scheduled Task. `install`,
186
+ `start`, `stop`, `status` and `uninstall` understand both mechanisms, and a
187
+ pre-launch running-check prevents a **double-launch** (two pollers on one bot
188
+ token would otherwise trigger Telegram 409 Conflict).
189
+ - **🔕 No interim "Done" ping from a busy background session.** A background
190
+ ("other session") turn that still has **queued follow-ups** no longer pings an
191
+ intermediate "Done" — only the final, queue-empty turn announces completion,
192
+ so a session working through a queue doesn't spam you between steps.
193
+
10
194
  ## [1.6.0] - 2026-06-23
11
195
 
12
196
  The **"always-on & self-healing"** release — the bot keeps itself up to date,
@@ -300,6 +484,8 @@ from a single chat and switch between them, on a redesigned, compact menu.
300
484
  diffs, MarkdownV2 rendering, scheduled tasks, multi-image prompts, and a
301
485
  cross-platform 24/7 background service.
302
486
 
487
+ [1.7.1]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.7.1
488
+ [1.7.0]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.7.0
303
489
  [1.6.0]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.6.0
304
490
  [1.5.1]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.5.1
305
491
  [1.5.0]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.5.0
package/README.md CHANGED
@@ -27,13 +27,16 @@ and extended into a full multi-session client.
27
27
  | 🗂 **Projects** | `/projects` browses your folders and runs Kiro in the one you pick. |
28
28
  | ♻️ **Resume sessions** | `/sessions` lists recent Kiro sessions; tap to resume via ACP `session/load`. |
29
29
  | 🟢 **Connect to live sessions** | `/active` shows sessions running **right now** on your PC. Watch them live, or continue them — see below. |
30
+ | 🛑 **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. |
30
31
  | 📡 **Live watch** | Follow a running session read-only in real time (tails its event log). |
31
- | 🧭 **Always-visible menu** | A persistent keyboard plus a pinned status panel that always shows your current **project, agent, reasoning effort, model, session and queue**. |
32
+ | 🧭 **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**. |
32
33
  | ⏰ **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. |
33
34
  | 🖼 **Multi-image prompts** | Send one or many photos (albums included) with a caption — all attached to the prompt for the agent to analyze. |
34
35
  | 📜 **History** | `/history` shows the latest messages of any session. |
35
36
  | 🧩 **MCP control** | `/mcp` lists MCP servers, **health-checks** them (which connected / failed and why), and **enables/disables** them — then restarts the agent to apply. |
36
37
  | 👥 **Subagent visibility** | When Kiro delegates to subagents and waits on them, you see each one **start / work / finish** plus a live `🤖 N running` summary — and subagent permission prompts route to your chat. |
38
+ | 📈 **Task progress bar** | The agent appends a `{progress: N%}` marker; the bot hides it and shows a **green 0–100% loading bar** on the live message, in the status panel, and on session cards (`SHOW_PROGRESS`). |
39
+ | 🔐 **Re-auth from chat** | `/reauth` logs out and runs a device-flow login (URL + code streamed to your chat), then restarts the agent — no terminal needed. |
37
40
  | ⌨️ **Typing indicator** | Stays on for the whole turn, even through long tool chains. |
38
41
  | 📥 **Queued follow-ups** | Message while Kiro is busy — it's queued and runs next. `/btw` runs it ASAP (now if idle, else right after the current task); `/flush` runs the queue now. |
39
42
  | ✏️ **Edit diffs** | File edits show as unified `diff` blocks with `+N -M` stats. |
@@ -52,6 +55,9 @@ and extended into a full multi-session client.
52
55
  | Switch between projects | ✅ | ❌ |
53
56
  | Resume saved sessions | ✅ | ❌ |
54
57
  | Attach to **live** PC sessions (watch / fork) | ✅ | ❌ |
58
+ | **Kill a session by PID** (or all at once) | ✅ | ❌ |
59
+ | **Live task-progress bars** (`{progress: N%}`) | ✅ | ❌ |
60
+ | **Re-authenticate from chat** (`/reauth`, device flow) | ✅ | ❌ |
55
61
  | Multiple isolated sessions | ✅ | ❌ (single shared) |
56
62
  | Queued follow-ups while busy | ✅ | ❌ |
57
63
  | **Scheduled tasks** (cron-like) | ✅ | ❌ |
@@ -75,20 +81,29 @@ the `tsx` runtime, no build step):
75
81
  npm install -g kiro-telegram-bot
76
82
  ```
77
83
 
78
- Everything operates on the **current folder** (its `.env`, `logs/`, `data/`), so
79
- keep one folder per bot:
84
+ By default your config lives in a **canonical, path-independent home**
85
+ `~/.kiro/tg/` (its `.env`, `logs/`, `data/`) — so the bot loads the **same**
86
+ `.env` no matter which folder you start it from. Run `kiro-tg setup --path` to
87
+ print the exact location. (A `.env` in the current folder is still honoured
88
+ first, so existing per-folder checkouts keep working.)
80
89
 
81
90
  ```bash
82
- mkdir my-bot && cd my-bot
83
- kiro-tg setup # auto-detects kiro-cli, writes ./.env
84
- # edit .env: set TELEGRAM_BOT_TOKEN and ALLOWED_USERS
91
+ kiro-tg setup # auto-detects kiro-cli, writes ~/.kiro/tg/.env
92
+ kiro-tg setup --path # print the .env location
93
+ # edit that .env: set TELEGRAM_BOT_TOKEN and ALLOWED_USERS
85
94
  kiro-tg run # foreground …
86
95
  kiro-tg install # … or install as a 24/7 background service
87
96
  ```
88
97
 
89
- Startup options: `kiro-tg setup | run | install | status | logs [n] | stop |
90
- restart | uninstall`. Or try it without installing: `npx kiro-telegram-bot
91
- setup`. See **[docs/INSTALL.md](./docs/INSTALL.md)** for the full guide.
98
+ The bot is **single-instance per token**: starting it again terminates any
99
+ ghost/duplicate that was still polling Telegram (the usual cause of a stale
100
+ "⛔ Not authorized"), so the fresh process with your current `.env` wins. A
101
+ plain `kiro-tg run` yields to an already-running background service instead.
102
+
103
+ Startup options: `kiro-tg setup [--path] | run | install | status | logs [n] |
104
+ stop | restart | uninstall`. Or try it without installing: `npx
105
+ kiro-telegram-bot setup`. See **[docs/INSTALL.md](./docs/INSTALL.md)** for the
106
+ full guide.
92
107
 
93
108
  ---
94
109
 
@@ -139,10 +154,16 @@ The platform is auto-detected:
139
154
 
140
155
  | OS | Mechanism | Starts on |
141
156
  |---|---|---|
142
- | Windows | Hidden Scheduled Task | logon |
157
+ | Windows | Hidden Scheduled Task (elevated) · per-user **Startup folder** (no admin) | logon |
143
158
  | Linux | systemd **user** service (+ linger) | boot |
144
159
  | macOS | launchd LaunchAgent | login |
145
160
 
161
+ On Windows, registering a logon-triggered Scheduled Task needs admin, so from a
162
+ normal terminal `kiro-tg install` falls back to a hidden launcher in your
163
+ per-user **Startup folder** (starts at logon, no elevation). Run it from an
164
+ **elevated** terminal to use the Scheduled Task instead; either way `status`,
165
+ `stop`, `restart` and `uninstall` work the same.
166
+
146
167
  ```bash
147
168
  npm run install:service # install + start, enable autostart
148
169
  npm run service -- status # show install + running state
@@ -182,6 +203,7 @@ Logs are written to `logs/kiro-telegram-bot.log` (rotated at 5 MB).
182
203
  /unwatch Stop following a live session
183
204
  /model <id> Switch the model for this session
184
205
  /restart Restart the Kiro agent
206
+ /reauth Log out & log in to Kiro (device flow) · /reauth --license free|pro …
185
207
  /help Show help
186
208
  ```
187
209
 
@@ -198,11 +220,13 @@ A tiny **persistent bar** sits under the message box — **☰ Menu · 🧭 Runn
198
220
  Sessions · Agent · Model · Reasoning · Tasks · Status · Usage · Stop · Kill all.
199
221
  The bar can be hidden (🙈) and restored (⌨️ Show bar or `/menu`).
200
222
 
201
- A **pinned status panel** at the top of the chat always shows your current
202
- **project, agent, reasoning effort, model, session id, context %, activity and
203
- queue** (and how many sessions the chat controls), updating live. Pick **Agent**,
204
- **Reasoning** or **Model** from the inline menu (reasoning steers how thoroughly
205
- the agent works: Minimal Max).
223
+ While a task is running, a **pinned status panel** appears at the top of the chat
224
+ showing your current **task progress, activity, queue, project, session, context
225
+ %, agent, reasoning effort and model** (and how many sessions the chat controls),
226
+ updating live — and it's **removed when the session goes idle** so the chat stays
227
+ clean between tasks (use **Status** in the menu to see it on demand any time).
228
+ Pick **Agent**, **Reasoning** or **Model** from the inline menu (reasoning steers
229
+ how thoroughly the agent works: Minimal → Max).
206
230
 
207
231
  ## ⏰ Scheduled tasks
208
232
 
@@ -237,6 +261,34 @@ prompt. Configure any OpenAI/Whisper-compatible endpoint via `STT_API_URL` in
237
261
  `.env`; leave `STT_LANGUAGE` blank for automatic detection (English, Russian,
238
262
  Romanian/Moldovan, and ~100 more).
239
263
 
264
+ ## 📈 Task progress
265
+
266
+ The bot asks the agent to end each message with a `{progress: N%}` marker, then
267
+ **hides the marker** and renders a **green loading bar** from 0–100 %
268
+ (`🟩🟩🟩🟩🟩⬜⬜⬜⬜⬜ 50%`, all-green ✅ at 100 %) so you can see how far along the
269
+ current task is. The bar appears at the bottom of the **live message**, in the
270
+ pinned **status panel**, and on **`/running` and `/sessions` cards**. Markers are
271
+ also stripped from history, replays and previews, so the raw plumbing never
272
+ shows. Turn it off with `SHOW_PROGRESS=false`.
273
+
274
+ That marker is only an instruction the model can ignore — weaker/free models and
275
+ long, tool-heavy turns often emit none, which used to leave the bar empty for the
276
+ whole turn. So when `SHOW_PROGRESS` is on but no marker arrives, the bot falls
277
+ back to a **computed** bar derived from real activity (completed tool calls,
278
+ streamed output, elapsed time): it starts low, climbs as work advances, and fills
279
+ to 100 % when the turn completes. The agent's own marker, when present, always
280
+ takes precedence and the value never decreases. Disable the fallback with
281
+ `PROGRESS_FALLBACK=false`.
282
+
283
+ ## 🔐 Re-authenticating Kiro
284
+
285
+ Run **`/reauth`** to log out and start a fresh **device-flow** login without
286
+ touching a terminal: the verification URL + code are streamed into the chat
287
+ (open them on any device), and once you're logged in the agent is restarted to
288
+ pick up the new credentials. It's refused while a turn is running, and you can
289
+ pass login flags through, e.g. `/reauth --license free` or
290
+ `/reauth --license pro --region <r> --identity-provider <url>`.
291
+
240
292
  ---
241
293
 
242
294
  ## 🧭 Working on several sessions at once
@@ -248,7 +300,8 @@ while the others keep working quietly. When you switch to a session you see its
248
300
  recent context and **every message that arrived while you were away** (its
249
301
  unread, recovered from the session log). Leave a task running in A, hop to B,
250
302
  reply, and come back to A to read what it did. Close a session with ✖ (it isn't
251
- killed — see `/killall` for that).
303
+ killed)or tap **🛑 Kill · pid N** on its `/sessions` · `/active` card to stop
304
+ its process (and `/killall` to stop them all).
252
305
 
253
306
  ## 🔗 Connecting to live sessions
254
307
 
@@ -274,6 +327,7 @@ Resuming an **idle** session loads it directly so you continue the exact thread.
274
327
  | `ALLOWED_USERS` | recommended | *(all)* | Comma-separated Telegram user IDs. Empty = anyone (unsafe). |
275
328
  | `KIRO_CLI_PATH` | no | auto / `kiro-cli` | Path to the `kiro-cli` binary. |
276
329
  | `KIRO_WORKSPACE` | no | cwd | Default working directory. |
330
+ | `KIRO_TG_DIR` | no | `~/.kiro/tg` | Folder holding this instance's `.env`, `logs/`, `data/`. Resolution: `--instance` → `KIRO_TG_DIR` → a `.env` in the current folder → `~/.kiro/tg`. So a `.env` created once is loaded from any startup path. |
277
331
  | `KIRO_AGENT` | no | — | Custom agent from `.kiro/agents/`. |
278
332
  | `KIRO_TRUST_ALL_TOOLS` | no | `true` | Run tools without prompts. |
279
333
  | `PROJECT_ROOTS` | no | workspace parent + home | Roots for `/projects`. |
@@ -283,10 +337,13 @@ Resuming an **idle** session loads it directly so you continue the exact thread.
283
337
  | `SHOW_EDIT_DIFFS` | no | `true` | Show unified diffs for edits. |
284
338
  | `DIFF_MAX_LINES` | no | `120` | Max diff lines shown inline. |
285
339
  | `SHOW_SUBAGENTS` | no | `true` | Stream subagent (crew) start/work/finish while the main agent waits. |
340
+ | `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. |
341
+ | `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. |
286
342
  | `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. |
287
343
  | `MCP_PROBE_TIMEOUT_MS` | no | `8000` | Per-server timeout for the `/mcp` live health-check. |
288
344
  | `MCP_PROBE_CONCURRENCY` | no | `6` | How many MCP health probes run at once. |
289
345
  | `ACP_AUTO_RESTART` | no | `true` | Auto-restart the agent if it exits. |
346
+ | `KIRO_TG_SINGLE_INSTANCE` | no | `true` | Enforce one running bot **per token**: on startup a still-alive ghost/duplicate (an old process polling Telegram with a stale `.env`, the usual cause of a phantom "⛔ Not authorized") is terminated so the fresh process wins. A manual `run` yields to an already-running background service instead of fighting it. |
290
347
  | `AUTO_UPDATE` | no | `true` | Hourly check npm and, when a newer version exists **and the bot is idle** (no turn/task running, no other active Kiro session), auto-update + restart + post the release notes (tagged `#update`). Global npm installs only. |
291
348
  | `UPDATE_CHECK_MS` | no | `3600000` | How often to check npm for updates (ms). |
292
349
  | `PROMPT_RETRY_ATTEMPTS` | no | `5` | Max retries for a transient agent error (e.g. high-traffic / `Internal error`) before any output streamed, with `6s → 12s → 24s → 48s → 60s` backoff. The real error shows each attempt; a summary after the last. `0` disables. |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kiro-telegram-bot",
3
- "version": "1.6.0",
3
+ "version": "1.7.2",
4
4
  "description": "Control Kiro CLI from Telegram over the Agent Client Protocol (ACP). Switch projects, resume and attach to live coding sessions, stream responses with diffs, queue follow-ups, and run 24/7 as a cross-platform background service.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -63,6 +63,9 @@
63
63
  "grammy": "^1.30.0",
64
64
  "tsx": "^4.19.2"
65
65
  },
66
+ "optionalDependencies": {
67
+ "@homebridge/node-pty-prebuilt-multiarch": "0.13.1"
68
+ },
66
69
  "devDependencies": {
67
70
  "@types/diff": "^7.0.0",
68
71
  "@types/node": "^22.10.0",
package/scripts/setup.mjs CHANGED
@@ -1,24 +1,63 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Easy setup: creates .env from .env.example, auto-detects the kiro-cli binary
4
- * and sensible PROJECT_ROOTS, and optionally writes the bot token / user id
5
- * passed as arguments:
3
+ * Easy setup: creates/updates the bot's .env, auto-detects the kiro-cli binary
4
+ * and sensible PROJECT_ROOTS, and optionally writes the bot token / user id:
6
5
  *
7
- * node scripts/setup.mjs <TELEGRAM_BOT_TOKEN> [ALLOWED_USER_ID]
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
+ * `~/.kiro/tg/.env`, so the bot loads the SAME config no matter where it's
10
+ * started from. A `.env` already present in the current folder (an explicit
11
+ * per-folder checkout) is used instead. `--path` just prints the resolved .env
12
+ * path and exits (nothing is written).
8
13
  */
9
- import { existsSync, readFileSync, writeFileSync } from "node:fs";
14
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
10
15
  import { homedir } from "node:os";
11
- import { join, dirname } from "node:path";
16
+ import { dirname, join, resolve } from "node:path";
12
17
  import { fileURLToPath } from "node:url";
13
18
 
14
19
  const root = join(dirname(fileURLToPath(import.meta.url)), "..");
15
- // .env lives in the instance dir (the user's folder); the template ships in the
16
- // package. For a cloned/zip checkout run in place these are the same folder.
17
- const instanceDir = process.env.KIRO_TG_CWD?.trim() || process.cwd();
18
- const envPath = join(instanceDir, ".env");
19
20
  const examplePath = join(root, ".env.example");
21
+ const CANONICAL_DIR = join(homedir(), ".kiro", "tg");
22
+
23
+ function expandHome(p) {
24
+ if (p === "~") return homedir();
25
+ if (p.startsWith("~/") || p.startsWith("~\\")) return join(homedir(), p.slice(2));
26
+ return p;
27
+ }
28
+
29
+ /** Mirror of config.ts resolveInstanceDir() so setup writes EXACTLY where the
30
+ * bot will read from. Keep the two in sync. */
31
+ function resolveInstanceDir() {
32
+ const flag = process.argv.indexOf("--instance");
33
+ if (flag !== -1 && process.argv[flag + 1]) return resolve(process.argv[flag + 1]);
34
+ const envDir = (process.env.KIRO_TG_DIR || process.env.KIRO_TG_CWD || "").trim();
35
+ if (envDir) return resolve(expandHome(envDir));
36
+ if (existsSync(join(process.cwd(), ".env"))) return process.cwd();
37
+ return CANONICAL_DIR;
38
+ }
39
+
40
+ // Parse args: flags (--path, --instance <dir>) vs positional token/user.
41
+ const argv = process.argv.slice(2);
42
+ let pathOnly = false;
43
+ const positionals = [];
44
+ for (let i = 0; i < argv.length; i++) {
45
+ const a = argv[i];
46
+ if (a === "--path") pathOnly = true;
47
+ else if (a === "--instance") i++; // value consumed by resolveInstanceDir()
48
+ else positionals.push(a);
49
+ }
50
+ const [tokenArg, userArg] = positionals;
51
+
52
+ const instanceDir = resolveInstanceDir();
53
+ const envPath = join(instanceDir, ".env");
54
+
55
+ if (pathOnly) {
56
+ console.log(envPath);
57
+ process.exit(0);
58
+ }
20
59
 
21
- const [, , tokenArg, userArg] = process.argv;
60
+ mkdirSync(instanceDir, { recursive: true });
22
61
 
23
62
  function detectKiro() {
24
63
  const candidates = [
@@ -70,6 +109,7 @@ if (userArg) {
70
109
 
71
110
  writeFileSync(envPath, env, "utf-8");
72
111
  console.log(`\n✓ .env written to ${envPath}`);
112
+ console.log(" (loaded from here no matter which folder you start the bot in)");
73
113
 
74
114
  if (!/^TELEGRAM_BOT_TOKEN=.+/m.test(env)) {
75
115
  console.log("\nNext: open .env and paste your bot token from @BotFather, then run `kiro-tg run` (or `npm start`).");