Diff
1diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
2index 09704cea8708b23adfdecb7d67a3edcdbadf136f..993ba8493046ba96f9fc9bff12c1979a54ab3caf 100644
3--- a/.github/workflows/ci.yml
4+++ b/.github/workflows/ci.yml
5@@ -13,5 +13,6 @@ jobs:
6 - uses: actions/checkout@v6
7 - uses: oven-sh/setup-bun@v2
8 - run: bun install
9+ - run: bun run format:check
10 - run: bun lint
11 - run: bun typecheck
12diff --git a/CLAUDE.md b/CLAUDE.md
13index 764c1dd99db169bdf77e9b7ec47283aaf3280911..8baee3f4899ae5cb912240445ed41a0cf2994a22 100644
14--- a/CLAUDE.md
15+++ b/CLAUDE.md
16@@ -1,4 +1,3 @@
17-
18 Default to using Bun instead of Node.js.
19
20 - Use `bun <file>` instead of `node <file>` or `ts-node <file>`
21diff --git a/Makefile b/Makefile
22index 7f3424ec82d4a80e8ecd5a129e5b6c97ded20509..cab185b80d5aa40e31023c3a3220c2b55b01d869 100644
23--- a/Makefile
24+++ b/Makefile
25@@ -1,4 +1,4 @@
26-.PHONY: lint typecheck check
27+.PHONY: lint typecheck format format-check check
28
29 lint:
30 bun run lint
31@@ -6,4 +6,10 @@ lint:
32 typecheck:
33 bun run typecheck
34
35-check: lint typecheck
36+format:
37+ bun run format
38+
39+format-check:
40+ bun run format:check
41+
42+check: lint typecheck format-check
43diff --git a/README.md b/README.md
44index 3b3110476531a35ee97517b06d34a60c3e6342dc..210c939e95cef81e79b229cb8abe5a036511b830 100644
45--- a/README.md
46+++ b/README.md
47@@ -28,7 +28,7 @@ Add the plugin to your opencode config (`~/.config/opencode/config.json`):
48
49 ```json
50 {
51- "plugin": ["@theedgeofrage/opencode-telegram@latest"]
52+ "plugin": ["@theedgeofrage/opencode-telegram@latest"]
53 }
54 ```
55
56@@ -38,8 +38,8 @@ Create `~/.config/opencode/telegram.json`:
57
58 ```json
59 {
60- "token": "<telegram-bot-token>",
61- "allowedUsers": [123456789]
62+ "token": "<telegram-bot-token>",
63+ "allowedUsers": [123456789]
64 }
65 ```
66
67diff --git a/bun.lock b/bun.lock
68index f1e01e7a446a6942d7f81d5a7ac56e5fcb6d7d91..cfb9dcec35b4d0bfe5d22d86e54126253736c02c 100644
69--- a/bun.lock
70+++ b/bun.lock
71@@ -14,6 +14,7 @@
72 "@types/bun": "latest",
73 "@types/node": "^22.13.14",
74 "eslint": "^9.23.0",
75+ "prettier": "^3.8.2",
76 "typescript": "^5.8.2",
77 "typescript-eslint": "^8.27.0",
78 },
79@@ -210,6 +211,8 @@
80
81 "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
82
83+ "prettier": ["prettier@3.8.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q=="],
84+
85 "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
86
87 "resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
88diff --git a/package.json b/package.json
89index 4c49f42398a19f67cdbb7d502f5033d0a1b73235..061cdad3a6c7ef6c919904c32d8c45226762dd82 100644
90--- a/package.json
91+++ b/package.json
92@@ -15,6 +15,8 @@
93 "build": "tsc",
94 "typecheck": "tsc --noEmit",
95 "lint": "eslint .",
96+ "format": "prettier --write .",
97+ "format:check": "prettier --check .",
98 "prepublishOnly": "bun run build"
99 },
100 "dependencies": {
101@@ -23,11 +25,12 @@
102 "grammy": "^1.35.0"
103 },
104 "devDependencies": {
105+ "@eslint/js": "^9.23.0",
106+ "@types/bun": "latest",
107 "@types/node": "^22.13.14",
108 "eslint": "^9.23.0",
109- "@eslint/js": "^9.23.0",
110+ "prettier": "^3.8.2",
111 "typescript": "^5.8.2",
112- "typescript-eslint": "^8.27.0",
113- "@types/bun": "latest"
114+ "typescript-eslint": "^8.27.0"
115 }
116 }
117diff --git a/src/events.ts b/src/events.ts
118index a88835b15bd4586aa6a01df1c3cebc6fabaf69dd..2ac3c9bd5375522d1f1081d3292d951b30fa1f08 100644
119--- a/src/events.ts
120+++ b/src/events.ts
121@@ -1,4 +1,9 @@
122-import type { Event, EventMessageUpdated, EventMessagePartUpdated, Part } from "@opencode-ai/sdk";
123+import type {
124+ Event,
125+ EventMessageUpdated,
126+ EventMessagePartUpdated,
127+ Part,
128+} from "@opencode-ai/sdk";
129 import * as log from "./log.js";
130
131 // Server sends `permission.asked` with this shape, which diverges from the SDK's
132@@ -30,7 +35,12 @@ export function registerSession(
133 onPart: PartHandler,
134 onPermission: PermissionHandler,
135 ): void {
136- handlers.set(sessionId, { onPart, onPermission, parts: new Map(), assistantMessageIDs: new Set() });
137+ handlers.set(sessionId, {
138+ onPart,
139+ onPermission,
140+ parts: new Map(),
141+ assistantMessageIDs: new Set(),
142+ });
143 }
144
145 export function unregisterSession(sessionId: string): void {
146@@ -61,7 +71,9 @@ export function handleEvent(event: Event): void {
147
148 if (type === "permission.asked" || type === "permission.updated") {
149 const perm = event.properties as unknown as PermissionEvent;
150- log.info(`[events] ${type} session=${perm.sessionID} perm=${perm.id} permission=${perm.permission}`);
151+ log.info(
152+ `[events] ${type} session=${perm.sessionID} perm=${perm.id} permission=${perm.permission}`,
153+ );
154 const handler = handlers.get(perm.sessionID);
155 if (!handler) return;
156 handler.onPermission(perm);
157diff --git a/src/format.ts b/src/format.ts
158index 407b897a99785be61dd0faccc0ebca3324b9729d..e8096257f402dbcc901dc8a240df5f1704272cb3 100644
159--- a/src/format.ts
160+++ b/src/format.ts
161@@ -58,11 +58,14 @@ function formatToolPart(part: Extract<Part, { type: "tool" }>): string {
162
163 if (state.status === "completed" && state.output) {
164 let output = state.output;
165- if (output.length > 3000) output = output.slice(0, 3000) + "\n... (truncated)";
166+ if (output.length > 3000)
167+ output = output.slice(0, 3000) + "\n... (truncated)";
168 return "```\n" + escapeCodeContent(header + "\n" + output) + "\n```";
169 }
170 if (state.status === "error") {
171- return "```\n" + escapeCodeContent(header + "\nError: " + state.error) + "\n```";
172+ return (
173+ "```\n" + escapeCodeContent(header + "\nError: " + state.error) + "\n```"
174+ );
175 }
176 return "```\n" + escapeCodeContent(header) + "\n```";
177 }
178diff --git a/src/main.ts b/src/main.ts
179index fde5979698f5ea1ada071018dff2df166370caf0..6f8403c1c0e7db1d8e3519a09a2cd6abf396965b 100644
180--- a/src/main.ts
181+++ b/src/main.ts
182@@ -29,7 +29,9 @@ function loadConfig(): Config {
183 }
184 const users = json.allowedUsers;
185 if (!Array.isArray(users) || users.length === 0) {
186- throw new Error(`"allowedUsers" must be a non-empty array in ${configPath}`);
187+ throw new Error(
188+ `"allowedUsers" must be a non-empty array in ${configPath}`,
189+ );
190 }
191 return { token, allowedUsers: users.map(Number) };
192 }