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 +11 -0
- package/CHANGELOG.md +186 -0
- package/README.md +73 -16
- package/package.json +4 -1
- package/scripts/setup.mjs +51 -11
- package/src/acp/client.ts +110 -15
- package/src/app/auth-service.ts +325 -0
- package/src/app/instance-lock.ts +139 -0
- package/src/bot/auth.ts +14 -3
- package/src/bot/bot.ts +9 -0
- package/src/bot/chat-controller.ts +10 -0
- package/src/bot/commands.ts +1 -0
- package/src/bot/handlers/auth.ts +89 -0
- package/src/bot/handlers/control.ts +2 -2
- package/src/bot/handlers/kill.ts +1 -18
- package/src/bot/handlers/running.ts +2 -0
- package/src/bot/handlers/session-card.ts +16 -0
- package/src/bot/handlers/session-kill.ts +95 -0
- package/src/bot/handlers/sessions.ts +2 -1
- package/src/bot/menu/status-panel.ts +53 -16
- package/src/bot/prompt-content.ts +5 -0
- package/src/bot/reauth-controller.ts +462 -0
- package/src/bot/session-runtime.ts +55 -9
- package/src/cli.ts +5 -4
- package/src/config.ts +36 -14
- package/src/index.ts +15 -1
- package/src/render/device-flow.ts +76 -0
- package/src/render/progress-estimate.ts +63 -0
- package/src/render/progress.ts +80 -0
- package/src/service/windows.ts +116 -21
- package/src/sessions/history.ts +12 -1
- package/src/sessions/process.ts +30 -0
- package/src/stream/streamer.ts +73 -5
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
|
|
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
|
-
|
|
79
|
-
|
|
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
|
-
|
|
83
|
-
kiro-tg setup
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
202
|
-
**
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
the
|
|
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 —
|
|
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.
|
|
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
|
|
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,
|
|
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
|
-
|
|
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`).");
|