kiro-telegram-bot 1.6.0 โ†’ 1.7.1

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/CHANGELOG.md CHANGED
@@ -7,6 +7,103 @@ 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.1] - 2026-06-24
11
+
12
+ The **"sign in your way"** release โ€” `/reauth` now lets you pick how you log in
13
+ (Builder ID, Google, GitHub or IAM Identity Center) on one tidy status card, and
14
+ the live task-progress bar climbs steadily instead of appearing only at the end.
15
+
16
+ ### Added
17
+
18
+ - **๐Ÿ” `/reauth` login-method picker.** Re-authentication now opens with a
19
+ **picker** โ€” **Builder ID** (free), **Google**, **GitHub**, or **IAM Identity
20
+ Center** (Pro) โ€” driven on a **single, self-animated status message** with
21
+ inline **Cancel ยท Retry ยท Change method ยท Restart agent** controls, so the chat
22
+ no longer fills with raw spinner frames. **IAM Identity Center** sign-in is now
23
+ fully supported: the bot asks for your **start URL + region** and drives the
24
+ CLI's interactive prompts inside a pseudo-terminal (optional
25
+ `@homebridge/node-pty-prebuilt-multiarch` dependency; a clear message tells you
26
+ to run `npm install` if it's missing). The device-verification URL + code still
27
+ stream to the chat for every method. Power users can skip the picker by passing
28
+ flags directly, e.g. `/reauth --license pro --identity-provider <url> --region <region>`.
29
+
30
+ ### Changed
31
+
32
+ - **๐Ÿ“ˆ Stricter, steadier task-progress reporting.** The agent instruction behind
33
+ the `{progress: N%}` marker is now far more rigorous: a marker is required on
34
+ **every** message (not only the last), the number must be **computed from real
35
+ step completion** and is **monotonic** (never decreases within a task), and
36
+ **100 %** is reserved for work that is fully complete *and verified*. The bar
37
+ now advances in realistic increments instead of jumping to a value at the very
38
+ end.
39
+
40
+ ### Fixed
41
+
42
+ - **๐Ÿ” `/reauth` agent-restart race** (`agent restart failed: kiro-cli acp exited
43
+ (code null)`). Logging out and restarting could let the **old** agent process's
44
+ exit fail the **new** connection's `initialize` and even trigger a competing
45
+ auto-restart. The ACP client now **fully tears down** the previous process
46
+ (ignoring the exit of a process it has already replaced) **before** spawning a
47
+ fresh one, and `/reauth` takes the agent down and **waits** before logging out โ€”
48
+ so a deliberate restart is clean and the new identity sticks.
49
+ - **๐Ÿชช Stale identity after re-login.** On logout the bot now also **clears Kiro's
50
+ cached auth token** (`~/.aws/sso/cache/kiro-auth-token.json`), so the next login
51
+ performs a genuine device-flow authentication instead of silently reusing the
52
+ previous account's refreshable token.
53
+
54
+ ## [1.7.0] - 2026-06-23
55
+
56
+ The **"take control"** release โ€” stop a runaway session by PID, re-authenticate
57
+ Kiro from your phone, watch a live task-progress bar, and install on Windows
58
+ without admin.
59
+
60
+ ### Added
61
+
62
+ - **๐Ÿ›‘ Kill a session / PID from its card (`/sessions`, `/active`).** Every
63
+ **live** session card now has a **`๐Ÿ›‘ Kill ยท pid N`** button that terminates
64
+ that session's process โ€” and its whole child tree on Windows (`taskkill /T`).
65
+ It's guarded by an inline **confirm** (Kill / Cancel) since it's destructive,
66
+ the bot's **own** agent process is never offered (killing it would take the
67
+ bot down), and the session state is re-read at every step so a session that
68
+ already stopped reports "no longer running" instead of a phantom kill. The
69
+ existing `/killall` (stop every active session at once) is unchanged and now
70
+ shares the same kill logic.
71
+ - **๐Ÿ” Re-authenticate Kiro from Telegram (`/reauth`).** Logs out
72
+ (`kiro-cli logout`) and starts a fresh **device-flow** login
73
+ (`kiro-cli login --use-device-flow`) โ€” the verification URL + code are
74
+ **streamed into the chat** so you complete it on your own device โ€” then
75
+ **restarts the agent** so it picks up the new credentials. Refused while a
76
+ turn is in flight (logging out would break it) and serialised so two runs
77
+ can't overlap. Pass-through flags are supported, e.g.
78
+ `/reauth --license free` or `/reauth --license pro --region <r> --identity-provider <url>`.
79
+ - **๐Ÿ“ˆ Live task-progress bar (`SHOW_PROGRESS`, on by default).** The agent is
80
+ asked to end each message with a `{progress: N%}` marker; the bot **parses and
81
+ hides** it and renders a **green 0โ€“100 % loading bar** (`๐ŸŸฉ๐ŸŸฉ๐ŸŸฉโฌœโฌœโฌœ 50%`,
82
+ all-green โœ… at 100 %) at the bottom of the **live message**, in the pinned
83
+ **status panel**, and on **`/running` and `/sessions` cards** โ€” so you can see
84
+ how far along the current task is. Markers (and the instruction) are also
85
+ stripped from history, unread replays, previews and fork-priming, so the raw
86
+ plumbing never shows. Disable with `SHOW_PROGRESS=false`.
87
+ - **๐Ÿ”€ "Switch to this session" on background pings.** A **`๐Ÿ“จ From other
88
+ session`** Done/error notification now carries a **๐Ÿ”€ Switch to this session**
89
+ button that brings that session to the foreground in one tap.
90
+
91
+ ### Changed
92
+
93
+ - **๐ŸชŸ Windows install no longer needs admin.** `kiro-tg install` used to fail
94
+ with **`schtasks create failed: ERROR: Access is denied`** for a normal user,
95
+ because registering a **logon-triggered** Scheduled Task is a privileged
96
+ operation. The installer now falls back to a hidden per-user **Startup-folder**
97
+ launcher (runs at logon, **no elevation**) when the task can't be created; an
98
+ **elevated** run still uses the nicer hidden Scheduled Task. `install`,
99
+ `start`, `stop`, `status` and `uninstall` understand both mechanisms, and a
100
+ pre-launch running-check prevents a **double-launch** (two pollers on one bot
101
+ token would otherwise trigger Telegram 409 Conflict).
102
+ - **๐Ÿ”• No interim "Done" ping from a busy background session.** A background
103
+ ("other session") turn that still has **queued follow-ups** no longer pings an
104
+ intermediate "Done" โ€” only the final, queue-empty turn announces completion,
105
+ so a session working through a queue doesn't spam you between steps.
106
+
10
107
  ## [1.6.0] - 2026-06-23
11
108
 
12
109
  The **"always-on & self-healing"** release โ€” the bot keeps itself up to date,
@@ -300,6 +397,8 @@ from a single chat and switch between them, on a redesigned, compact menu.
300
397
  diffs, MarkdownV2 rendering, scheduled tasks, multi-image prompts, and a
301
398
  cross-platform 24/7 background service.
302
399
 
400
+ [1.7.1]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.7.1
401
+ [1.7.0]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.7.0
303
402
  [1.6.0]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.6.0
304
403
  [1.5.1]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.5.1
305
404
  [1.5.0]: https://github.com/artickc/kiro-telegram-bot/releases/tag/v1.5.0
package/README.md CHANGED
@@ -27,6 +27,7 @@ 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
32
  | ๐Ÿงญ **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
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. |
@@ -34,6 +35,8 @@ and extended into a full multi-session client.
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) | โœ… | โŒ |
@@ -139,10 +145,16 @@ The platform is auto-detected:
139
145
 
140
146
  | OS | Mechanism | Starts on |
141
147
  |---|---|---|
142
- | Windows | Hidden Scheduled Task | logon |
148
+ | Windows | Hidden Scheduled Task (elevated) ยท per-user **Startup folder** (no admin) | logon |
143
149
  | Linux | systemd **user** service (+ linger) | boot |
144
150
  | macOS | launchd LaunchAgent | login |
145
151
 
152
+ On Windows, registering a logon-triggered Scheduled Task needs admin, so from a
153
+ normal terminal `kiro-tg install` falls back to a hidden launcher in your
154
+ per-user **Startup folder** (starts at logon, no elevation). Run it from an
155
+ **elevated** terminal to use the Scheduled Task instead; either way `status`,
156
+ `stop`, `restart` and `uninstall` work the same.
157
+
146
158
  ```bash
147
159
  npm run install:service # install + start, enable autostart
148
160
  npm run service -- status # show install + running state
@@ -182,6 +194,7 @@ Logs are written to `logs/kiro-telegram-bot.log` (rotated at 5 MB).
182
194
  /unwatch Stop following a live session
183
195
  /model <id> Switch the model for this session
184
196
  /restart Restart the Kiro agent
197
+ /reauth Log out & log in to Kiro (device flow) ยท /reauth --license free|pro โ€ฆ
185
198
  /help Show help
186
199
  ```
187
200
 
@@ -199,10 +212,10 @@ Sessions ยท Agent ยท Model ยท Reasoning ยท Tasks ยท Status ยท Usage ยท Stop ยท K
199
212
  The bar can be hidden (๐Ÿ™ˆ) and restored (โŒจ๏ธ Show bar or `/menu`).
200
213
 
201
214
  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).
215
+ **project, agent, reasoning effort, model, session id, context %, task progress,
216
+ activity and queue** (and how many sessions the chat controls), updating live.
217
+ Pick **Agent**, **Reasoning** or **Model** from the inline menu (reasoning steers
218
+ how thoroughly the agent works: Minimal โ†’ Max).
206
219
 
207
220
  ## โฐ Scheduled tasks
208
221
 
@@ -237,6 +250,25 @@ prompt. Configure any OpenAI/Whisper-compatible endpoint via `STT_API_URL` in
237
250
  `.env`; leave `STT_LANGUAGE` blank for automatic detection (English, Russian,
238
251
  Romanian/Moldovan, and ~100 more).
239
252
 
253
+ ## ๐Ÿ“ˆ Task progress
254
+
255
+ The bot asks the agent to end each message with a `{progress: N%}` marker, then
256
+ **hides the marker** and renders a **green loading bar** from 0โ€“100 %
257
+ (`๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ๐ŸŸฉ๐ŸŸฉโฌœโฌœโฌœโฌœโฌœ 50%`, all-green โœ… at 100 %) so you can see how far along the
258
+ current task is. The bar appears at the bottom of the **live message**, in the
259
+ pinned **status panel**, and on **`/running` and `/sessions` cards**. Markers are
260
+ also stripped from history, replays and previews, so the raw plumbing never
261
+ shows. Turn it off with `SHOW_PROGRESS=false`.
262
+
263
+ ## ๐Ÿ” Re-authenticating Kiro
264
+
265
+ Run **`/reauth`** to log out and start a fresh **device-flow** login without
266
+ touching a terminal: the verification URL + code are streamed into the chat
267
+ (open them on any device), and once you're logged in the agent is restarted to
268
+ pick up the new credentials. It's refused while a turn is running, and you can
269
+ pass login flags through, e.g. `/reauth --license free` or
270
+ `/reauth --license pro --region <r> --identity-provider <url>`.
271
+
240
272
  ---
241
273
 
242
274
  ## ๐Ÿงญ Working on several sessions at once
@@ -248,7 +280,8 @@ while the others keep working quietly. When you switch to a session you see its
248
280
  recent context and **every message that arrived while you were away** (its
249
281
  unread, recovered from the session log). Leave a task running in A, hop to B,
250
282
  reply, and come back to A to read what it did. Close a session with โœ– (it isn't
251
- killed โ€” see `/killall` for that).
283
+ killed) โ€” or tap **๐Ÿ›‘ Kill ยท pid N** on its `/sessions` ยท `/active` card to stop
284
+ its process (and `/killall` to stop them all).
252
285
 
253
286
  ## ๐Ÿ”— Connecting to live sessions
254
287
 
@@ -283,6 +316,7 @@ Resuming an **idle** session loads it directly so you continue the exact thread.
283
316
  | `SHOW_EDIT_DIFFS` | no | `true` | Show unified diffs for edits. |
284
317
  | `DIFF_MAX_LINES` | no | `120` | Max diff lines shown inline. |
285
318
  | `SHOW_SUBAGENTS` | no | `true` | Stream subagent (crew) start/work/finish while the main agent waits. |
319
+ | `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. |
286
320
  | `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
321
  | `MCP_PROBE_TIMEOUT_MS` | no | `8000` | Per-server timeout for the `/mcp` live health-check. |
288
322
  | `MCP_PROBE_CONCURRENCY` | no | `6` | How many MCP health probes run at once. |
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.1",
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/src/acp/client.ts CHANGED
@@ -159,24 +159,31 @@ export class AcpClient extends EventEmitter {
159
159
  if (this.opts.agent) args.push("--agent", this.opts.agent);
160
160
 
161
161
  log.info(`spawning: ${this.opts.kiroCliPath} ${args.join(" ")}`);
162
- this.proc = spawn(this.opts.kiroCliPath, args, {
162
+ const proc = spawn(this.opts.kiroCliPath, args, {
163
163
  stdio: ["pipe", "pipe", "pipe"],
164
164
  cwd: this.opts.workspace,
165
165
  env: { ...process.env, KIRO_LOG_LEVEL: process.env.KIRO_LOG_LEVEL || "error" },
166
166
  }) as ChildProcessWithoutNullStreams;
167
-
168
- this.proc.on("exit", (code) => {
167
+ this.proc = proc;
168
+
169
+ proc.on("exit", (code) => {
170
+ // Ignore the exit of a process we've already replaced (a deliberate
171
+ // restart/stop). Its teardown must NOT fail the new process's pending
172
+ // requests nor trigger a competing auto-restart โ€” that race was the cause
173
+ // of "/reauth โ†’ agent restart failed: kiro-cli acp exited (code null)".
174
+ if (this.proc !== proc) return;
169
175
  log.warn(`kiro-cli acp exited (code ${code})`);
170
176
  this.failAllPending(new Error(`kiro-cli acp exited (code ${code})`));
171
177
  this.emit("exit", code);
172
178
  this.maybeRestart();
173
179
  });
174
- this.proc.on("error", (err) => {
180
+ proc.on("error", (err) => {
181
+ if (this.proc !== proc) return;
175
182
  log.error("failed to spawn kiro-cli:", err.message);
176
183
  this.failAllPending(err);
177
184
  });
178
185
 
179
- this.transport = new JsonRpcTransport(this.proc);
186
+ this.transport = new JsonRpcTransport(proc);
180
187
  this.transport.on("message", (m: JsonRpcMessage) => this.onMessage(m));
181
188
 
182
189
  const init = (await this.request("initialize", {
@@ -329,22 +336,87 @@ export class AcpClient extends EventEmitter {
329
336
 
330
337
  stop(): void {
331
338
  this.stopped = true;
332
- if (this.restartTimer) clearTimeout(this.restartTimer);
333
- this.proc?.kill();
334
- this.proc = undefined;
339
+ if (this.restartTimer) {
340
+ clearTimeout(this.restartTimer);
341
+ this.restartTimer = undefined;
342
+ }
343
+ void this.killCurrent();
335
344
  }
336
345
 
337
- /** Manually restart the agent (used by the /restart command). */
338
- async restart(): Promise<void> {
346
+ /**
347
+ * Stop the agent and WAIT for the process to fully exit, leaving it stopped
348
+ * (no auto-restart until start()/restart()). Used by /reauth to release the
349
+ * held session BEFORE logging out โ€” otherwise the live agent keeps refreshing
350
+ * and re-persisting the old token, silently restoring the previous identity.
351
+ */
352
+ async stopAndWait(): Promise<void> {
339
353
  this.stopped = true;
340
- if (this.restartTimer) clearTimeout(this.restartTimer);
341
- this.proc?.kill();
342
- this.proc = undefined;
354
+ if (this.restartTimer) {
355
+ clearTimeout(this.restartTimer);
356
+ this.restartTimer = undefined;
357
+ }
358
+ await this.killCurrent();
359
+ }
360
+
361
+ /**
362
+ * Manually restart the agent (used by /restart, /reauth and the MCP toggle).
363
+ * The old process is fully torn down BEFORE a fresh one is spawned, so its
364
+ * exit can't fail the new connection's `initialize` โ€” which previously
365
+ * surfaced as "agent restart failed: kiro-cli acp exited (code null)".
366
+ */
367
+ async restart(): Promise<void> {
368
+ if (this.restartTimer) {
369
+ clearTimeout(this.restartTimer);
370
+ this.restartTimer = undefined;
371
+ }
372
+ this.stopped = true; // suppress auto-restart while we swap processes
373
+ this.restartAttempts = 0;
374
+ await this.killCurrent();
343
375
  this.stopped = false;
344
376
  await this.connect();
345
377
  this.emit("restarted");
346
378
  }
347
379
 
380
+ /**
381
+ * Terminate the current process and wait for it to fully exit. Clearing
382
+ * `this.proc` first makes the connect()-registered exit/error handlers
383
+ * short-circuit, so a deliberate teardown is silent (no `exit` event, no
384
+ * auto-restart). In-flight requests are rejected here (the handler no longer
385
+ * will). Escalates to SIGKILL if the process lingers, and never hangs.
386
+ */
387
+ private killCurrent(): Promise<void> {
388
+ const proc = this.proc;
389
+ this.proc = undefined;
390
+ this.transport = undefined;
391
+ this.failAllPending(new Error("kiro-cli acp is restarting"));
392
+ if (!proc || proc.exitCode !== null || proc.signalCode !== null) {
393
+ return Promise.resolve();
394
+ }
395
+ return new Promise<void>((resolve) => {
396
+ let settled = false;
397
+ const done = (): void => {
398
+ if (settled) return;
399
+ settled = true;
400
+ clearTimeout(hard);
401
+ resolve();
402
+ };
403
+ const hard = setTimeout(() => {
404
+ try {
405
+ proc.kill("SIGKILL");
406
+ } catch {
407
+ /* ignore */
408
+ }
409
+ setTimeout(done, 500); // give the OS a beat, then proceed regardless
410
+ }, 4000);
411
+ proc.once("exit", done);
412
+ try {
413
+ proc.kill();
414
+ } catch {
415
+ done();
416
+ }
417
+ });
418
+ }
419
+
348
420
  // โ”€โ”€ JSON-RPC plumbing โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
349
421
 
350
422
  private request(method: string, params: unknown): Promise<unknown> {