kiro-telegram-bot 1.5.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.
Files changed (83) hide show
  1. package/.env.example +104 -0
  2. package/LICENSE +21 -0
  3. package/README.md +517 -0
  4. package/bin/kiro-tg.mjs +21 -0
  5. package/docs/INSTALL.md +143 -0
  6. package/docs/ops/RELEASE_CHECKLIST.md +39 -0
  7. package/package.json +70 -0
  8. package/scripts/mq.ts +25 -0
  9. package/scripts/setup.mjs +78 -0
  10. package/src/acp/client.ts +456 -0
  11. package/src/acp/server-handlers.ts +85 -0
  12. package/src/acp/transport.ts +50 -0
  13. package/src/acp/types.ts +136 -0
  14. package/src/agents/catalog.ts +44 -0
  15. package/src/app/json-store.ts +54 -0
  16. package/src/app/reasoning.ts +30 -0
  17. package/src/app/settings-store.ts +31 -0
  18. package/src/app/stt.ts +53 -0
  19. package/src/app/types.ts +48 -0
  20. package/src/app/usage.ts +32 -0
  21. package/src/bot/auth.ts +27 -0
  22. package/src/bot/bot.ts +154 -0
  23. package/src/bot/chat-controller.ts +251 -0
  24. package/src/bot/commands.ts +48 -0
  25. package/src/bot/deps.ts +47 -0
  26. package/src/bot/handlers/control.ts +94 -0
  27. package/src/bot/handlers/history.ts +58 -0
  28. package/src/bot/handlers/kill.ts +69 -0
  29. package/src/bot/handlers/mcp.ts +205 -0
  30. package/src/bot/handlers/menu.ts +204 -0
  31. package/src/bot/handlers/message.ts +93 -0
  32. package/src/bot/handlers/photo.ts +108 -0
  33. package/src/bot/handlers/projects.ts +83 -0
  34. package/src/bot/handlers/running.ts +104 -0
  35. package/src/bot/handlers/session-card.ts +65 -0
  36. package/src/bot/handlers/sessions.ts +131 -0
  37. package/src/bot/handlers/system.ts +51 -0
  38. package/src/bot/handlers/tasks.ts +223 -0
  39. package/src/bot/handlers/usage.ts +33 -0
  40. package/src/bot/handlers/voice.ts +53 -0
  41. package/src/bot/image-return.ts +69 -0
  42. package/src/bot/menu/keyboard.ts +47 -0
  43. package/src/bot/menu/refresh.ts +13 -0
  44. package/src/bot/menu/status-panel.ts +78 -0
  45. package/src/bot/permission-service.ts +149 -0
  46. package/src/bot/prompt-content.ts +49 -0
  47. package/src/bot/prompt-retry.ts +70 -0
  48. package/src/bot/registry.ts +178 -0
  49. package/src/bot/session-runtime.ts +670 -0
  50. package/src/bot/telegram-io.ts +109 -0
  51. package/src/bot/typing.ts +35 -0
  52. package/src/bot/wizard/task-wizard.ts +214 -0
  53. package/src/cli.ts +125 -0
  54. package/src/config.ts +190 -0
  55. package/src/index.ts +74 -0
  56. package/src/logger.ts +78 -0
  57. package/src/mcp/config.ts +103 -0
  58. package/src/mcp/probe.ts +218 -0
  59. package/src/mcp/types.ts +68 -0
  60. package/src/projects/manager.ts +88 -0
  61. package/src/render/chunk.ts +57 -0
  62. package/src/render/diff.ts +48 -0
  63. package/src/render/escape.ts +22 -0
  64. package/src/render/markdown.ts +126 -0
  65. package/src/render/subagent.ts +75 -0
  66. package/src/render/tool-call.ts +102 -0
  67. package/src/service/index.ts +24 -0
  68. package/src/service/linux.ts +83 -0
  69. package/src/service/macos.ts +91 -0
  70. package/src/service/platform.ts +59 -0
  71. package/src/service/types.ts +34 -0
  72. package/src/service/windows.ts +103 -0
  73. package/src/sessions/history.ts +181 -0
  74. package/src/sessions/store.ts +133 -0
  75. package/src/sessions/tail.ts +86 -0
  76. package/src/sessions/types.ts +26 -0
  77. package/src/stream/streamer.ts +167 -0
  78. package/src/tasks/runner.ts +82 -0
  79. package/src/tasks/schedule.ts +142 -0
  80. package/src/tasks/scheduler.ts +53 -0
  81. package/src/tasks/store.ts +80 -0
  82. package/src/tasks/types.ts +33 -0
  83. package/tsconfig.json +19 -0
@@ -0,0 +1,143 @@
1
+ # šŸ“¦ Install guide
2
+
3
+ Get the Kiro 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 `kiro-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
+ - **Kiro CLI** installed and authenticated — run `kiro-cli 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 kiro-telegram-bot
28
+ ```
29
+
30
+ This gives you the **`kiro-tg`** command (alias: `kiro-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
+ kiro-tg setup # auto-detects kiro-cli, writes ./.env
37
+ # (or pass values directly: kiro-tg setup <BOT_TOKEN> <YOUR_USER_ID>)
38
+ # edit .env: set TELEGRAM_BOT_TOKEN and ALLOWED_USERS
39
+ kiro-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 (`kiro-tg <command>`)
46
+
47
+ | Command | What it does |
48
+ |---|---|
49
+ | `kiro-tg setup [token] [userId]` | Create/update `.env` in this folder (auto-detects `kiro-cli` + project roots). |
50
+ | `kiro-tg run` | Run the bot in the foreground. |
51
+ | `kiro-tg install` | Install + start a **24/7 background service** that autostarts on boot/login. |
52
+ | `kiro-tg status` | Show install + running state of the service. |
53
+ | `kiro-tg logs [n]` | Tail the last `n` log lines (default 100). |
54
+ | `kiro-tg stop` / `restart` / `start` | Control the running service. |
55
+ | `kiro-tg uninstall` | Stop + remove the background service. |
56
+ | `kiro-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 kiro-telegram-bot@latest`.
65
+
66
+ > **Try without installing:** `npx kiro-telegram-bot setup` then
67
+ > `npx kiro-telegram-bot run` works too (slower first run).
68
+
69
+ ---
70
+
71
+ ## Option B — 1-click installer
72
+
73
+ Every [release](https://github.com/artickc/kiro-telegram-bot/releases) ships a
74
+ clean `kiro-telegram-bot-<version>.zip` (no `node_modules`, `.env`, logs or data)
75
+ that contains the 1-click installers.
76
+
77
+ 1. **Download** the latest `kiro-telegram-bot-<version>.zip` and unzip it (or
78
+ `git clone` the repo).
79
+ 2. **Run the installer for your OS** from the unzipped folder. It installs
80
+ dependencies, auto-detects `kiro-cli`, writes `.env`, asks for your bot
81
+ token, and optionally sets up the 24/7 background service.
82
+
83
+ **Windows** — double-click `install.cmd`, or in a terminal:
84
+
85
+ ```powershell
86
+ .\install.cmd
87
+ ```
88
+
89
+ **Linux / macOS**:
90
+
91
+ ```bash
92
+ chmod +x install.sh && ./install.sh
93
+ ```
94
+
95
+ 3. **Set access control.** Open `.env` and set `ALLOWED_USERS` to your Telegram
96
+ user ID(s).
97
+
98
+ ---
99
+
100
+ ## Option C — manual / from source
101
+
102
+ Best for contributors (run with auto-reload, no build step).
103
+
104
+ ```bash
105
+ git clone https://github.com/artickc/kiro-telegram-bot.git
106
+ cd kiro-telegram-bot
107
+ npm install
108
+ npm run setup # auto-detects kiro-cli + project roots, writes .env
109
+ # edit .env: set TELEGRAM_BOT_TOKEN and ALLOWED_USERS
110
+ npm start # or: npm run dev (auto-reload)
111
+ ```
112
+
113
+ Run it 24/7 as a background service:
114
+
115
+ ```bash
116
+ npm run install:service # install + start, enable autostart on boot/login
117
+ npm run service -- status # show install + running state
118
+ npm run service -- logs 200 # tail the log file
119
+ npm run uninstall:service # stop + remove
120
+ ```
121
+
122
+ No build step — TypeScript runs directly via `tsx`.
123
+
124
+ ---
125
+
126
+ ## Configuration
127
+
128
+ All options live in `.env`. See the **Configuration** table in the
129
+ [README](../README.md) for every variable and its default. By default the bot
130
+ keeps `.env`, `logs/` and `data/` in the folder you run it from (override log
131
+ location with `LOG_DIR` / `LOG_FILE` and data with `DATA_DIR`).
132
+
133
+ ## Troubleshooting
134
+
135
+ - **Bot doesn't respond** — confirm your ID is in `ALLOWED_USERS` and the token
136
+ is correct; check `logs/kiro-telegram-bot.log` (run `kiro-tg logs`).
137
+ - **`kiro-cli` not found** — set `KIRO_CLI_PATH` in `.env` to the binary's full
138
+ path.
139
+ - **`kiro-tg: command not found`** — ensure your global npm bin dir is on `PATH`
140
+ (`npm bin -g`), or use `npx kiro-telegram-bot <command>`.
141
+ - **"high volume of traffic" / transient errors** — the bot auto-retries with
142
+ backoff (6s → 60s) and shows the real error; switch model with the 🧩 menu or
143
+ `/model <id>` if a model stays busy.
@@ -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 `kiro-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,70 @@
1
+ {
2
+ "name": "kiro-telegram-bot",
3
+ "version": "1.5.1",
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
+ "type": "module",
6
+ "main": "src/index.ts",
7
+ "bin": {
8
+ "kiro-tg": "bin/kiro-tg.mjs",
9
+ "kiro-telegram-bot": "bin/kiro-tg.mjs"
10
+ },
11
+ "files": [
12
+ "src",
13
+ "bin",
14
+ "scripts",
15
+ "tsconfig.json",
16
+ ".env.example",
17
+ "docs"
18
+ ],
19
+ "engines": {
20
+ "node": ">=20"
21
+ },
22
+ "scripts": {
23
+ "start": "tsx src/index.ts",
24
+ "dev": "tsx watch src/index.ts",
25
+ "typecheck": "tsc --noEmit",
26
+ "prepublishOnly": "npm run typecheck",
27
+ "setup": "node scripts/setup.mjs",
28
+ "service": "tsx src/cli.ts",
29
+ "install:service": "tsx src/cli.ts install",
30
+ "uninstall:service": "tsx src/cli.ts uninstall",
31
+ "service:status": "tsx src/cli.ts status",
32
+ "service:logs": "tsx src/cli.ts logs"
33
+ },
34
+ "keywords": [
35
+ "kiro",
36
+ "kiro-cli",
37
+ "acp",
38
+ "agent-client-protocol",
39
+ "telegram",
40
+ "telegram-bot",
41
+ "ai-agent",
42
+ "ai-coding-assistant",
43
+ "mobile-coding",
44
+ "chatops",
45
+ "devtools",
46
+ "daemon",
47
+ "cross-platform",
48
+ "grammy"
49
+ ],
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "git+https://github.com/artickc/kiro-telegram-bot.git"
53
+ },
54
+ "homepage": "https://github.com/artickc/kiro-telegram-bot#readme",
55
+ "bugs": {
56
+ "url": "https://github.com/artickc/kiro-telegram-bot/issues"
57
+ },
58
+ "license": "MIT",
59
+ "dependencies": {
60
+ "diff": "^7.0.0",
61
+ "dotenv": "^16.4.7",
62
+ "grammy": "^1.30.0",
63
+ "tsx": "^4.19.2"
64
+ },
65
+ "devDependencies": {
66
+ "@types/diff": "^7.0.0",
67
+ "@types/node": "^22.10.0",
68
+ "typescript": "^5.7.2"
69
+ }
70
+ }
package/scripts/mq.ts ADDED
@@ -0,0 +1,25 @@
1
+ import { homedir } from "node:os";
2
+ import { join } from "node:path";
3
+ import { spawn } from "node:child_process";
4
+ const kiro = join(homedir(),"AppData","Local","Kiro-Cli","kiro-cli.exe");
5
+ function run(label:string, fn:(send:(m:string,p:any)=>void, getSid:()=>string)=>void, waitMs=5000): Promise<void> {
6
+ return new Promise((resolve)=>{
7
+ const p = spawn(kiro,["acp","--trust-all-tools"],{stdio:["pipe","pipe","pipe"]});
8
+ let buf=""; let id=0; const pend=new Map<number,string>(); let sid=""; let exited=false;
9
+ const send=(method:string,params:any)=>{ const i=++id; pend.set(i,method); try{p.stdin.write(JSON.stringify({jsonrpc:"2.0",id:i,method,params})+"\n");}catch{} };
10
+ p.on("exit",(c)=>{ exited=true; console.log(` [${label}] PROCESS EXITED code=${c}`); });
11
+ p.stdout.setEncoding("utf8");
12
+ p.stdout.on("data",(c:string)=>{ buf+=c; let n; while((n=buf.indexOf("\n"))!==-1){ const line=buf.slice(0,n).trim(); buf=buf.slice(n+1); if(!line)continue; let m:any; try{m=JSON.parse(line)}catch{continue;}
13
+ if(m.id!==undefined && pend.has(m.id) && m.method===undefined){ const meth=pend.get(m.id)!; pend.delete(m.id); if(meth==="session/new"){ sid=m.result.sessionId; fn(send,()=>sid); } else if(meth!=="initialize"){ console.log(` [${label}] ${meth} =>`, JSON.stringify(m.result??{error:m.error}).slice(0,500)); } }
14
+ else if(m.method && /model/i.test(JSON.stringify(m))){ console.log(` [${label}] NOTIF ${m.method} =>`, JSON.stringify(m.params).slice(0,500)); }
15
+ }});
16
+ send("initialize",{protocolVersion:1,clientCapabilities:{fs:{readTextFile:true,writeTextFile:true},terminal:true},clientInfo:{name:"p",version:"1"}});
17
+ setTimeout(()=>send("session/new",{cwd:process.cwd(),mcpServers:[]}),600);
18
+ setTimeout(()=>{ if(!exited)p.kill(); resolve(); }, waitMs);
19
+ });
20
+ }
21
+ await run("REAL", (send,getSid)=> send("session/set_model",{sessionId:getSid(),modelId:"claude-opus-4.8"}));
22
+ await run("INVALID", (send,getSid)=> send("session/set_model",{sessionId:getSid(),modelId:"nope-xyz-1"}));
23
+ await run("EXEC", (send,getSid)=> send("_kiro.dev/commands/execute",{sessionId:getSid(),command:"/model"}), 5000);
24
+ await run("OPTS", (send,getSid)=>{ send("_kiro.dev/commands/options",{sessionId:getSid(),commandName:"/model"}); send("_kiro.dev/commands/options",{sessionId:getSid(),name:"/model",arguments:""}); }, 5000);
25
+ process.exit(0);
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
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:
6
+ *
7
+ * node scripts/setup.mjs <TELEGRAM_BOT_TOKEN> [ALLOWED_USER_ID]
8
+ */
9
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
10
+ import { homedir } from "node:os";
11
+ import { join, dirname } from "node:path";
12
+ import { fileURLToPath } from "node:url";
13
+
14
+ 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
+ const examplePath = join(root, ".env.example");
20
+
21
+ const [, , tokenArg, userArg] = process.argv;
22
+
23
+ function detectKiro() {
24
+ const candidates = [
25
+ join(homedir(), "AppData", "Local", "Kiro-Cli", "kiro-cli.exe"),
26
+ join(homedir(), ".local", "bin", "kiro-cli"),
27
+ "/usr/local/bin/kiro-cli",
28
+ ];
29
+ return candidates.find((p) => existsSync(p)) || "";
30
+ }
31
+
32
+ function detectRoots() {
33
+ const guesses = ["H:\\Lucru\\Domains", "C:\\Lucru\\Domains", join(homedir(), "projects")];
34
+ return guesses.filter((p) => existsSync(p));
35
+ }
36
+
37
+ let env = existsSync(envPath)
38
+ ? readFileSync(envPath, "utf-8")
39
+ : readFileSync(examplePath, "utf-8");
40
+
41
+ function setVar(key, value) {
42
+ if (value === undefined || value === "") return;
43
+ const re = new RegExp(`^${key}=.*$`, "m");
44
+ const line = `${key}=${value}`;
45
+ env = re.test(env) ? env.replace(re, line) : `${env.trimEnd()}\n${line}\n`;
46
+ }
47
+
48
+ const kiro = detectKiro();
49
+ if (kiro) {
50
+ setVar("KIRO_CLI_PATH", kiro);
51
+ console.log(`āœ“ Found kiro-cli: ${kiro}`);
52
+ } else {
53
+ console.log("! kiro-cli not auto-detected — set KIRO_CLI_PATH in .env or ensure it's on PATH.");
54
+ }
55
+
56
+ const roots = detectRoots();
57
+ if (roots.length) {
58
+ setVar("PROJECT_ROOTS", roots.join(","));
59
+ console.log(`āœ“ PROJECT_ROOTS: ${roots.join(", ")}`);
60
+ }
61
+
62
+ if (tokenArg) {
63
+ setVar("TELEGRAM_BOT_TOKEN", tokenArg);
64
+ console.log("āœ“ Wrote TELEGRAM_BOT_TOKEN");
65
+ }
66
+ if (userArg) {
67
+ setVar("ALLOWED_USERS", userArg);
68
+ console.log(`āœ“ Wrote ALLOWED_USERS=${userArg}`);
69
+ }
70
+
71
+ writeFileSync(envPath, env, "utf-8");
72
+ console.log(`\nāœ“ .env written to ${envPath}`);
73
+
74
+ if (!/^TELEGRAM_BOT_TOKEN=.+/m.test(env)) {
75
+ console.log("\nNext: open .env and paste your bot token from @BotFather, then run `kiro-tg run` (or `npm start`).");
76
+ } else {
77
+ console.log("\nReady! Run `kiro-tg run` (or `npm start`).");
78
+ }