@coffer-org/plugin-telegram 1.1.0 → 1.2.0
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/dist/index.d.ts +0 -1
- package/dist/index.js +1 -11
- package/dist/runtime/bot.d.ts +4 -19
- package/dist/runtime/bot.js +93 -164
- package/dist/runtime/config.d.ts +12 -31
- package/dist/runtime/config.js +1 -25
- package/dist/runtime/index.d.ts +4 -27
- package/dist/runtime/index.js +3 -12
- package/package.json +12 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/runtime/bot.d.ts.map +0 -1
- package/dist/runtime/bot.js.map +0 -1
- package/dist/runtime/config.d.ts.map +0 -1
- package/dist/runtime/config.js.map +0 -1
- package/dist/runtime/index.d.ts.map +0 -1
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/threads.d.ts +0 -41
- package/dist/runtime/threads.d.ts.map +0 -1
- package/dist/runtime/threads.js +0 -63
- package/dist/runtime/threads.js.map +0 -1
- package/dist/runtime/workspace.d.ts +0 -18
- package/dist/runtime/workspace.d.ts.map +0 -1
- package/dist/runtime/workspace.js +0 -59
- package/dist/runtime/workspace.js.map +0 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Плагін telegram — воркер без vaults/modules. Маніфест ІЗОМОРФНИЙ: не імпортує
|
|
3
|
-
* node-рантайм (src/runtime/*), бо потрапляє у web-бандл через src/registry.ts.
|
|
4
|
-
* Запуск/зупинка бота — у серверних хуках (packages/server/src/plugin-hooks.ts).
|
|
5
|
-
*/
|
|
6
1
|
import { definePlugin } from '@coffer-org/sdk/plugin';
|
|
7
2
|
import { defineSettings } from '@coffer-org/sdk/settings';
|
|
8
3
|
import { field } from '@coffer-org/sdk/fields';
|
|
9
4
|
export default definePlugin({
|
|
10
5
|
id: 'telegram',
|
|
11
6
|
version: '1.0.0',
|
|
12
|
-
dependsOn: [],
|
|
7
|
+
dependsOn: ['orchestrator'],
|
|
13
8
|
settings: defineSettings({
|
|
14
9
|
label: 'telegram.settings.label',
|
|
15
10
|
fields: [
|
|
@@ -17,11 +12,6 @@ export default definePlugin({
|
|
|
17
12
|
field.password({ key: 'api_hash', label: 'telegram.settings.api_hash' }),
|
|
18
13
|
field.password({ key: 'bot_token', label: 'telegram.settings.bot_token' }),
|
|
19
14
|
field.tel({ key: 'phone', label: 'telegram.settings.phone' }),
|
|
20
|
-
field.string({ key: 'claude_model', label: 'telegram.settings.claude_model' }),
|
|
21
|
-
field.string({ key: 'trigger_prefix', label: 'telegram.settings.trigger_prefix' }),
|
|
22
|
-
field.int({ key: 'response_timeout', label: 'telegram.settings.response_timeout' }),
|
|
23
|
-
field.boolean({ key: 'skip_permissions', label: 'telegram.settings.skip_permissions' }),
|
|
24
15
|
],
|
|
25
16
|
}),
|
|
26
17
|
});
|
|
27
|
-
//# sourceMappingURL=index.js.map
|
package/dist/runtime/bot.d.ts
CHANGED
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/** Зібрати argv для `claude -p`. sessionId=null → нова сесія (json), інакше --resume. */
|
|
6
|
-
export function buildClaudeArgs(cfg: any, sessionId: any): any[];
|
|
7
|
-
/** Розпарсити stdout `claude --output-format json` → { text, sessionId }. */
|
|
8
|
-
export function parseClaudeResult(stdout: any): {
|
|
9
|
-
text: any;
|
|
10
|
-
sessionId: any;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Стартувати бота. Тихо не запускається, якщо немає креденшелів
|
|
14
|
-
* (сервер працює далі). Кидає лише на справжній збій підключення.
|
|
15
|
-
*/
|
|
16
|
-
export function startBot(opts?: {}): Promise<boolean>;
|
|
17
|
-
/** Зупинити бота (викликається з shutdown сервера). Безпечно за відсутності клієнта. */
|
|
18
|
-
export function stopBot(): Promise<void>;
|
|
19
|
-
//# sourceMappingURL=bot.d.ts.map
|
|
1
|
+
import type { LoadOpts } from './config.ts';
|
|
2
|
+
export type StartOpts = LoadOpts;
|
|
3
|
+
export declare function startBot(opts?: StartOpts): Promise<boolean>;
|
|
4
|
+
export declare function stopBot(): Promise<void>;
|
package/dist/runtime/bot.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import pkg from 'telegram';
|
|
3
|
+
import { TelegramClient, Api } from 'telegram';
|
|
4
|
+
import { LogLevel } from 'telegram/extensions/Logger.js';
|
|
6
5
|
import { StringSession } from 'telegram/sessions/index.js';
|
|
7
6
|
import { NewMessage } from 'telegram/events/index.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { loadThreads, saveThreads, resolveParent, getSession, recordSession, pruneThreads } from './threads.js';
|
|
11
|
-
const { TelegramClient } = pkg;
|
|
12
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
const MAX_MESSAGE_LENGTH = 4096;
|
|
7
|
+
import { handleIncoming } from '@coffer-org/plugin-orchestrator/runtime';
|
|
8
|
+
import { loadBotConfig, hasCredentials } from "./config.js";
|
|
14
9
|
const log = {
|
|
15
10
|
info: (m) => console.log(`[telegram-bot] ${new Date().toISOString().slice(0, 19)} ${m}`),
|
|
16
11
|
warn: (m) => console.warn(`[telegram-bot] ${new Date().toISOString().slice(0, 19)} WARN ${m}`),
|
|
@@ -28,202 +23,136 @@ function saveSessionString(file, s) {
|
|
|
28
23
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
29
24
|
fs.writeFileSync(file, s, 'utf-8');
|
|
30
25
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return { CLAUDE_CONFIG_DIR: cfg.claudeHomeDir };
|
|
34
|
-
}
|
|
35
|
-
/** Зібрати argv для `claude -p`. sessionId=null → нова сесія (json), інакше --resume. */
|
|
36
|
-
export function buildClaudeArgs(cfg, sessionId) {
|
|
37
|
-
const args = ['-p', '--model', cfg.claudeModel, '--output-format', 'json'];
|
|
38
|
-
if (cfg.skipPermissions)
|
|
39
|
-
args.push('--dangerously-skip-permissions');
|
|
40
|
-
if (sessionId)
|
|
41
|
-
args.push('--resume', sessionId);
|
|
42
|
-
args.push('--mcp-config', path.join(cfg.workspaceDir, '.mcp.json'));
|
|
43
|
-
return args;
|
|
44
|
-
}
|
|
45
|
-
/** Розпарсити stdout `claude --output-format json` → { text, sessionId }. */
|
|
46
|
-
export function parseClaudeResult(stdout) {
|
|
47
|
-
try {
|
|
48
|
-
const obj = JSON.parse(stdout);
|
|
49
|
-
return { text: (obj.result ?? '').trim() || '(порожня відповідь)', sessionId: obj.session_id ?? null };
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
return { text: stdout.trim() || '(порожня відповідь)', sessionId: null };
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Запустити `claude` headless в ІЗОЛЬОВАНОМУ runtime: cwd=workspace,
|
|
57
|
-
* CLAUDE_CONFIG_DIR=claude-home (0 глобальних плагінів/скілів), тільки coffer MCP.
|
|
58
|
-
* @returns {Promise<{text:string|null, sessionId:string|null}>}
|
|
59
|
-
*/
|
|
60
|
-
function runClaude(prompt, cfg, sessionId) {
|
|
61
|
-
return new Promise((resolve) => {
|
|
62
|
-
const args = buildClaudeArgs(cfg, sessionId);
|
|
63
|
-
const proc = spawn('claude', args, {
|
|
64
|
-
cwd: cfg.workspaceDir,
|
|
65
|
-
env: { ...process.env, ...claudeEnv(cfg) },
|
|
66
|
-
});
|
|
67
|
-
let stdout = '';
|
|
68
|
-
let stderr = '';
|
|
69
|
-
const timer = setTimeout(() => {
|
|
70
|
-
log.warn(`claude таймаут ${cfg.responseTimeout}s — kill`);
|
|
71
|
-
proc.kill('SIGKILL');
|
|
72
|
-
}, cfg.responseTimeout * 1000);
|
|
73
|
-
proc.stdout.on('data', (d) => {
|
|
74
|
-
stdout += d.toString();
|
|
75
|
-
});
|
|
76
|
-
proc.stderr.on('data', (d) => {
|
|
77
|
-
stderr += d.toString();
|
|
78
|
-
});
|
|
79
|
-
proc.on('error', (e) => {
|
|
80
|
-
clearTimeout(timer);
|
|
81
|
-
log.error(`claude spawn: ${e.message}`);
|
|
82
|
-
resolve({ text: `⚠️ не вдалося запустити claude: ${e.message}`, sessionId: null });
|
|
83
|
-
});
|
|
84
|
-
proc.on('close', (code) => {
|
|
85
|
-
clearTimeout(timer);
|
|
86
|
-
if (code === 0) {
|
|
87
|
-
resolve(parseClaudeResult(stdout));
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
log.error(`claude exit ${code}: ${stderr.slice(0, 800)}`);
|
|
91
|
-
resolve({ text: stderr.trim() ? `⚠️ ${stderr.slice(0, 400)}` : null, sessionId: null });
|
|
92
|
-
});
|
|
93
|
-
proc.stdin.write(prompt);
|
|
94
|
-
proc.stdin.end();
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
async function sendLong(client, peer, text) {
|
|
98
|
-
let last;
|
|
99
|
-
for (let i = 0; i < text.length; i += MAX_MESSAGE_LENGTH) {
|
|
100
|
-
last = await client.sendMessage(peer, { message: text.slice(i, i + MAX_MESSAGE_LENGTH) });
|
|
101
|
-
if (i + MAX_MESSAGE_LENGTH < text.length)
|
|
102
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
103
|
-
}
|
|
104
|
-
return last;
|
|
105
|
-
}
|
|
106
|
-
let client; // активний клієнт (для stopBot)
|
|
107
|
-
/**
|
|
108
|
-
* Стартувати бота. Тихо не запускається, якщо немає креденшелів
|
|
109
|
-
* (сервер працює далі). Кидає лише на справжній збій підключення.
|
|
110
|
-
*/
|
|
26
|
+
let client;
|
|
27
|
+
let healthTimer;
|
|
111
28
|
export async function startBot(opts = {}) {
|
|
112
29
|
const cfg = loadBotConfig(opts);
|
|
113
30
|
if (!hasCredentials(cfg)) {
|
|
114
|
-
log.warn('
|
|
31
|
+
log.warn('no credentials (api_id/api_hash + bot_token|phone) — not starting. Fill in the plugin settings or set the TELEGRAM_* env vars');
|
|
115
32
|
return false;
|
|
116
33
|
}
|
|
117
|
-
ensureWorkspace(cfg, log);
|
|
118
34
|
const sessionFile = path.join(cfg.stateDir, '.sessions', 'claude_bot.session');
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
35
|
+
const tg = new TelegramClient(new StringSession(loadSessionString(sessionFile)), cfg.apiId, cfg.apiHash, {
|
|
36
|
+
connectionRetries: Infinity,
|
|
37
|
+
retryDelay: 2000,
|
|
38
|
+
autoReconnect: true,
|
|
122
39
|
});
|
|
123
|
-
|
|
124
|
-
|
|
40
|
+
client = tg;
|
|
41
|
+
tg.setLogLevel(LogLevel.NONE);
|
|
42
|
+
const authParams = (cfg.botToken
|
|
125
43
|
? { botAuthToken: cfg.botToken }
|
|
126
44
|
: { phoneNumber: async () => cfg.phone, onError: (e) => log.error(e.message) });
|
|
127
|
-
|
|
128
|
-
|
|
45
|
+
await tg.start(authParams);
|
|
46
|
+
saveSessionString(sessionFile, tg.session.save());
|
|
47
|
+
const me = (await tg.getMe());
|
|
129
48
|
const meId = me?.id?.toString();
|
|
130
|
-
log.info(
|
|
131
|
-
|
|
132
|
-
|
|
49
|
+
log.info(`connected as @${me?.username || me?.firstName || meId}`);
|
|
50
|
+
async function sendMd(peer, text) {
|
|
51
|
+
try {
|
|
52
|
+
return await tg.sendMessage(peer, { message: text, parseMode: 'md' });
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
try {
|
|
56
|
+
return await tg.sendMessage(peer, { message: text });
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async function editMd(peer, msgId, text) {
|
|
64
|
+
try {
|
|
65
|
+
await tg.editMessage(peer, { message: msgId, text, parseMode: 'md' });
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
try {
|
|
69
|
+
await tg.editMessage(peer, { message: msgId, text });
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function startTypingPeer(peer) {
|
|
76
|
+
const ping = () => tg.invoke(new Api.messages.SetTyping({ peer, action: new Api.SendMessageTypingAction() })).catch(() => { });
|
|
77
|
+
void ping();
|
|
78
|
+
const timer = setInterval(() => void ping(), 5000);
|
|
79
|
+
return () => clearInterval(timer);
|
|
80
|
+
}
|
|
81
|
+
tg.addEventHandler(async (event) => {
|
|
133
82
|
try {
|
|
134
83
|
const message = event.message;
|
|
135
84
|
if (!message)
|
|
136
85
|
return;
|
|
137
86
|
if (message.out)
|
|
138
|
-
return;
|
|
87
|
+
return;
|
|
139
88
|
if (message.senderId && meId && message.senderId.toString() === meId)
|
|
140
89
|
return;
|
|
141
90
|
const text = (message.text || message.message || '').trim();
|
|
142
91
|
if (!text)
|
|
143
92
|
return;
|
|
144
|
-
// Діагностика: бачимо КОЖНЕ вхідне повідомлення в логах сервера.
|
|
145
93
|
let chatLabel = String(event.chatId ?? '?');
|
|
146
94
|
let peer = event.chatId;
|
|
147
95
|
try {
|
|
148
|
-
const chat = await event.getChat();
|
|
96
|
+
const chat = (await event.getChat());
|
|
149
97
|
chatLabel = chat?.title || chat?.username || chatLabel;
|
|
150
|
-
|
|
98
|
+
if (chat)
|
|
99
|
+
peer = chat;
|
|
151
100
|
}
|
|
152
101
|
catch {
|
|
153
|
-
/* ignore */
|
|
154
102
|
}
|
|
155
103
|
log.info(`msg [${chatLabel}]: ${text.slice(0, 80)}`);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (placeholder) {
|
|
182
|
-
try {
|
|
183
|
-
await client.deleteMessages(peer, [placeholder.id], { revoke: true });
|
|
184
|
-
}
|
|
185
|
-
catch {
|
|
186
|
-
/* ignore */
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
let botMsgId = null;
|
|
190
|
-
if (responseText) {
|
|
191
|
-
const sent = await sendLong(client, peer, responseText);
|
|
192
|
-
botMsgId = sent?.id ?? null;
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
try {
|
|
196
|
-
await client.sendMessage(peer, { message: '⚠️ claude не повернув відповіді' });
|
|
197
|
-
}
|
|
198
|
-
catch {
|
|
199
|
-
/* ignore */
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
// Зберегти мапінг лише якщо є sessionId (нова або продовжена сесія).
|
|
203
|
-
if (sessionId) {
|
|
204
|
-
threads = recordSession(threads, { msgId: message.id, botMsgId, sessionId, now });
|
|
205
|
-
threads = pruneThreads(threads, now, 7);
|
|
206
|
-
saveThreads(threadsFile, threads);
|
|
207
|
-
}
|
|
104
|
+
const chatId = String(event.chatId ?? '?');
|
|
105
|
+
const userId = message.senderId?.toString() ?? '?';
|
|
106
|
+
const replyTo = message.replyTo?.replyToMsgId ?? null;
|
|
107
|
+
const connector = {
|
|
108
|
+
id: 'telegram',
|
|
109
|
+
capabilities: { streaming: true, typing: true, maxMessageLength: 4096 },
|
|
110
|
+
async sendMessage(_chatId, msgText) {
|
|
111
|
+
const sent = await sendMd(peer, msgText);
|
|
112
|
+
if (!sent)
|
|
113
|
+
return null;
|
|
114
|
+
return { msgId: String(sent.id) };
|
|
115
|
+
},
|
|
116
|
+
async editMessage(_chatId, msgId, msgText) {
|
|
117
|
+
await editMd(peer, Number(msgId), msgText);
|
|
118
|
+
},
|
|
119
|
+
startTyping(_chatId) {
|
|
120
|
+
return startTypingPeer(peer);
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
await handleIncoming(connector, {
|
|
124
|
+
chatId,
|
|
125
|
+
userId,
|
|
126
|
+
text,
|
|
127
|
+
replyToId: replyTo != null ? String(replyTo) : null,
|
|
128
|
+
});
|
|
208
129
|
}
|
|
209
130
|
catch (err) {
|
|
210
|
-
log.error(
|
|
131
|
+
log.error(`message handling: ${err instanceof Error ? err.message : String(err)}`);
|
|
211
132
|
}
|
|
212
133
|
}, new NewMessage({}));
|
|
213
|
-
|
|
134
|
+
clearInterval(healthTimer);
|
|
135
|
+
healthTimer = setInterval(() => {
|
|
136
|
+
if (!tg.connected) {
|
|
137
|
+
log.warn('watchdog: connection lost — reconnecting');
|
|
138
|
+
tg.connect().catch((e) => log.warn(`watchdog reconnect: ${e instanceof Error ? e.message : String(e)}`));
|
|
139
|
+
}
|
|
140
|
+
}, 30_000);
|
|
141
|
+
if (typeof healthTimer.unref === 'function')
|
|
142
|
+
healthTimer.unref();
|
|
143
|
+
log.info('listening for messages (gate policy — in the orchestrator settings)');
|
|
214
144
|
return true;
|
|
215
145
|
}
|
|
216
|
-
/** Зупинити бота (викликається з shutdown сервера). Безпечно за відсутності клієнта. */
|
|
217
146
|
export async function stopBot() {
|
|
147
|
+
clearInterval(healthTimer);
|
|
148
|
+
healthTimer = undefined;
|
|
218
149
|
if (!client)
|
|
219
150
|
return;
|
|
220
151
|
try {
|
|
221
152
|
await client.disconnect();
|
|
222
|
-
log.info('
|
|
153
|
+
log.info('stopped');
|
|
223
154
|
}
|
|
224
155
|
catch {
|
|
225
|
-
/* ignore */
|
|
226
156
|
}
|
|
227
157
|
client = undefined;
|
|
228
158
|
}
|
|
229
|
-
//# sourceMappingURL=bot.js.map
|
package/dist/runtime/config.d.ts
CHANGED
|
@@ -1,33 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* @param {{ env?: Record<string,string|undefined>, dbSettings?: Record<string,unknown> }} [opts]
|
|
4
|
-
*/
|
|
5
|
-
export function loadBotConfig(opts?: {
|
|
6
|
-
env?: Record<string, string | undefined>;
|
|
7
|
-
dbSettings?: Record<string, unknown>;
|
|
8
|
-
}): {
|
|
1
|
+
export declare const PLUGIN_ROOT: string;
|
|
2
|
+
export interface BotConfig {
|
|
9
3
|
apiId: number;
|
|
10
|
-
apiHash:
|
|
11
|
-
botToken:
|
|
12
|
-
phone:
|
|
13
|
-
claudeModel: {};
|
|
14
|
-
appRoot: string;
|
|
15
|
-
cofferUrl: {};
|
|
16
|
-
globalCredentials: string;
|
|
17
|
-
replyWindow: number;
|
|
18
|
-
runtimeDir: string;
|
|
19
|
-
workspaceDir: string;
|
|
20
|
-
claudeHomeDir: string;
|
|
4
|
+
apiHash: string;
|
|
5
|
+
botToken: string;
|
|
6
|
+
phone: string;
|
|
21
7
|
stateDir: string;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function hasCredentials(cfg:
|
|
29
|
-
/** Корінь app (packages/plugin-telegram/src/runtime → ../../../..). */
|
|
30
|
-
export const APP_ROOT: string;
|
|
31
|
-
/** Корінь plugin-telegram (src/runtime → ../..). */
|
|
32
|
-
export const PLUGIN_ROOT: string;
|
|
33
|
-
//# sourceMappingURL=config.d.ts.map
|
|
8
|
+
}
|
|
9
|
+
export interface LoadOpts {
|
|
10
|
+
env?: Record<string, string | undefined>;
|
|
11
|
+
dbSettings?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export declare function loadBotConfig(opts?: LoadOpts): BotConfig;
|
|
14
|
+
export declare function hasCredentials(cfg: Pick<BotConfig, 'apiId' | 'apiHash' | 'botToken' | 'phone'>): boolean;
|
package/dist/runtime/config.js
CHANGED
|
@@ -1,42 +1,18 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
1
|
import path from 'node:path';
|
|
3
2
|
import { fileURLToPath } from 'node:url';
|
|
4
3
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
-
/** Корінь app (packages/plugin-telegram/src/runtime → ../../../..). */
|
|
6
|
-
export const APP_ROOT = path.resolve(__dirname, '../../../..');
|
|
7
|
-
/** Корінь plugin-telegram (src/runtime → ../..). */
|
|
8
4
|
export const PLUGIN_ROOT = path.resolve(__dirname, '../..');
|
|
9
|
-
/**
|
|
10
|
-
* Звести конфіг бота: значення з DB-налаштувань, env має пріоритет.
|
|
11
|
-
* @param {{ env?: Record<string,string|undefined>, dbSettings?: Record<string,unknown> }} [opts]
|
|
12
|
-
*/
|
|
13
5
|
export function loadBotConfig(opts = {}) {
|
|
14
6
|
const env = opts.env ?? process.env;
|
|
15
|
-
const db = opts.dbSettings ?? {};
|
|
7
|
+
const db = (opts.dbSettings ?? {});
|
|
16
8
|
return {
|
|
17
9
|
apiId: Number(env.TELEGRAM_API_ID ?? db.api_id ?? 0) || 0,
|
|
18
10
|
apiHash: env.TELEGRAM_API_HASH ?? db.api_hash ?? '',
|
|
19
11
|
botToken: env.TELEGRAM_BOT_TOKEN ?? db.bot_token ?? '',
|
|
20
12
|
phone: env.TELEGRAM_PHONE ?? db.phone ?? '',
|
|
21
|
-
claudeModel: env.TELEGRAM_CLAUDE_MODEL ?? db.claude_model ?? 'haiku',
|
|
22
|
-
appRoot: APP_ROOT,
|
|
23
|
-
cofferUrl: env.COFFER_URL ?? db.coffer_url ?? 'http://localhost:7023',
|
|
24
|
-
// Авторизація: symlink на глобальний логін claude (баланс підписки). Окремого
|
|
25
|
-
// api_key немає — бот свідомо шарить уже налаштовану сесію ~/.claude.
|
|
26
|
-
globalCredentials: env.CLAUDE_GLOBAL_CREDENTIALS ?? path.join(os.homedir(), '.claude', '.credentials.json'),
|
|
27
|
-
replyWindow: Number(env.TELEGRAM_REPLY_WINDOW ?? db.reply_window ?? 1800) || 1800,
|
|
28
|
-
runtimeDir: path.join(PLUGIN_ROOT, 'runtime'),
|
|
29
|
-
workspaceDir: path.join(PLUGIN_ROOT, 'runtime', 'workspace'),
|
|
30
|
-
claudeHomeDir: path.join(PLUGIN_ROOT, 'runtime', 'claude-home'),
|
|
31
13
|
stateDir: path.join(PLUGIN_ROOT, 'runtime', 'state'),
|
|
32
|
-
workingDir: path.join(PLUGIN_ROOT, 'runtime', 'workspace'),
|
|
33
|
-
triggerPrefix: env.TELEGRAM_TRIGGER_PREFIX ?? db.trigger_prefix ?? '',
|
|
34
|
-
skipPermissions: db.skip_permissions !== false,
|
|
35
|
-
responseTimeout: Number(env.TELEGRAM_RESPONSE_TIMEOUT ?? db.response_timeout ?? 600) || 600,
|
|
36
14
|
};
|
|
37
15
|
}
|
|
38
|
-
/** Чи достатньо креденшелів для запуску: apiId+apiHash і (botToken або phone). */
|
|
39
16
|
export function hasCredentials(cfg) {
|
|
40
17
|
return Boolean(cfg.apiId && cfg.apiHash && (cfg.botToken || cfg.phone));
|
|
41
18
|
}
|
|
42
|
-
//# sourceMappingURL=config.js.map
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,30 +1,7 @@
|
|
|
1
1
|
import type { PluginHooks } from '@coffer-org/server/plugin-hooks';
|
|
2
|
-
import { startBot, stopBot } from './bot.
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
apiHash: string;
|
|
6
|
-
botToken: string;
|
|
7
|
-
phone: string;
|
|
8
|
-
claudeModel: string;
|
|
9
|
-
globalCredentials: string;
|
|
10
|
-
cofferUrl: string;
|
|
11
|
-
replyWindow: number;
|
|
12
|
-
appRoot: string;
|
|
13
|
-
runtimeDir: string;
|
|
14
|
-
workspaceDir: string;
|
|
15
|
-
claudeHomeDir: string;
|
|
16
|
-
stateDir: string;
|
|
17
|
-
workingDir: string;
|
|
18
|
-
triggerPrefix: string;
|
|
19
|
-
skipPermissions: boolean;
|
|
20
|
-
responseTimeout: number;
|
|
21
|
-
}
|
|
22
|
-
export interface StartOpts {
|
|
23
|
-
env?: Record<string, string | undefined>;
|
|
24
|
-
dbSettings?: Record<string, unknown>;
|
|
25
|
-
}
|
|
2
|
+
import { startBot, stopBot } from './bot.ts';
|
|
3
|
+
export type { BotConfig, LoadOpts } from './config.ts';
|
|
4
|
+
export type { StartOpts } from './bot.ts';
|
|
26
5
|
export { startBot, stopBot };
|
|
27
|
-
export { loadBotConfig, hasCredentials } from './config.
|
|
28
|
-
/** Серверні хуки telegram-бота (збирає loadServerHooks через discovery). */
|
|
6
|
+
export { loadBotConfig, hasCredentials } from './config.ts';
|
|
29
7
|
export declare const serverHooks: PluginHooks;
|
|
30
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,22 +1,13 @@
|
|
|
1
|
-
// TypeScript entry-point для plugin-hooks.ts (server-only, динамічний import).
|
|
2
|
-
// Реалізація — в bot.js / config.js (чистий ESM без TS-компілятора).
|
|
3
1
|
import { getPluginSettings } from '@coffer-org/server/plugin-runtime';
|
|
4
|
-
|
|
5
|
-
// @ts-ignore — bot.js є чистим ESM без .d.ts; resolve різниться між root-typecheck і tsc -b.
|
|
6
|
-
import { startBot, stopBot } from './bot.js';
|
|
2
|
+
import { startBot, stopBot } from "./bot.js";
|
|
7
3
|
export { startBot, stopBot };
|
|
8
|
-
|
|
9
|
-
// @ts-ignore — config.js є чистим ESM без .d.ts.
|
|
10
|
-
export { loadBotConfig, hasCredentials } from './config.js';
|
|
11
|
-
/** Серверні хуки telegram-бота (збирає loadServerHooks через discovery). */
|
|
4
|
+
export { loadBotConfig, hasCredentials } from "./config.js";
|
|
12
5
|
export const serverHooks = {
|
|
13
6
|
init: async () => {
|
|
14
7
|
const dbSettings = await getPluginSettings('telegram');
|
|
15
|
-
|
|
16
|
-
void startBot({ dbSettings }).catch((e) => console.warn(`[telegram] не стартував: ${e.message}`));
|
|
8
|
+
void startBot({ dbSettings }).catch((e) => console.warn(`[telegram] failed to start: ${e.message}`));
|
|
17
9
|
},
|
|
18
10
|
teardown: async () => {
|
|
19
11
|
await stopBot();
|
|
20
12
|
},
|
|
21
13
|
};
|
|
22
|
-
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coffer-org/plugin-telegram",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=24"
|
|
7
|
+
},
|
|
5
8
|
"files": [
|
|
6
9
|
"dist"
|
|
7
10
|
],
|
|
@@ -19,12 +22,14 @@
|
|
|
19
22
|
"build": "tsc -b tsconfig.build.json",
|
|
20
23
|
"prepack": "npm run build && node ../../scripts/swap-exports.mjs dist",
|
|
21
24
|
"postpack": "node ../../scripts/swap-exports.mjs src",
|
|
22
|
-
"test": "node --test \"src/runtime/*.test.
|
|
25
|
+
"test": "node --import tsx --test \"src/runtime/*.test.ts\""
|
|
23
26
|
},
|
|
24
27
|
"dependencies": {
|
|
25
|
-
"@coffer-org/
|
|
26
|
-
"@coffer-org/
|
|
27
|
-
"
|
|
28
|
-
"input": "^1.0.1"
|
|
29
|
-
|
|
28
|
+
"@coffer-org/plugin-orchestrator": "^1.2.0",
|
|
29
|
+
"@coffer-org/sdk": "^1.2.0",
|
|
30
|
+
"@coffer-org/server": "^1.2.0",
|
|
31
|
+
"input": "^1.0.1",
|
|
32
|
+
"telegram": "^2.26.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {}
|
|
30
35
|
}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,wBAiBG"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAE/C,eAAe,YAAY,CAAC;IAC1B,EAAE,EAAE,UAAU;IACd,OAAO,EAAE,OAAO;IAChB,SAAS,EAAE,EAAE;IACb,QAAQ,EAAE,cAAc,CAAC;QACvB,KAAK,EAAE,yBAAyB;QAChC,MAAM,EAAE;YACN,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC;YAC/D,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;YACxE,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;YAC1E,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;YAC7D,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,gCAAgC,EAAE,CAAC;YAC9E,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;YAClF,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;YACnF,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,kBAAkB,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;SACxF;KACF,CAAC;CACH,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../src/runtime/bot.js"],"names":[],"mappings":"AAkCA,+FAA+F;AAC/F;;EAEC;AAED,yFAAyF;AACzF,iEAMC;AAED,6EAA6E;AAC7E;;;EAOC;AA0DD;;;GAGG;AACH,sDAiHC;AAED,wFAAwF;AACxF,yCASC"}
|
package/dist/runtime/bot.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bot.js","sourceRoot":"","sources":["../../src/runtime/bot.js"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/runtime/config.js"],"names":[],"mappings":"AAYA;;;GAGG;AACH,qCAFW;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAC,MAAM,GAAC,SAAS,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAC,OAAO,CAAC,CAAA;CAAE;;;;;;;;;;;;;;;;;;EA2BxF;AAED,kFAAkF;AAClF,kDAEC;AAxCD,uEAAuE;AACvE,8BAA+D;AAE/D,oDAAoD;AACpD,iCAA4D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/runtime/config.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,uEAAuE;AACvE,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAE/D,oDAAoD;AACpD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAE5D;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAI,GAAG,EAAE;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACpC,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC;IAEjC,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;QACzD,OAAO,EAAE,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,QAAQ,IAAI,EAAE;QACnD,QAAQ,EAAE,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,SAAS,IAAI,EAAE;QACtD,KAAK,EAAE,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE;QAC3C,WAAW,EAAE,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC,YAAY,IAAI,OAAO;QACpE,OAAO,EAAE,QAAQ;QACjB,SAAS,EAAE,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,UAAU,IAAI,uBAAuB;QACrE,8EAA8E;QAC9E,sEAAsE;QACtE,iBAAiB,EAAE,GAAG,CAAC,yBAAyB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,mBAAmB,CAAC;QAC3G,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,qBAAqB,IAAI,EAAE,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,IAAI;QACjF,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;QAC7C,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC;QAC5D,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,CAAC;QAC/D,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC;QACpD,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC;QAC1D,aAAa,EAAE,GAAG,CAAC,uBAAuB,IAAI,EAAE,CAAC,cAAc,IAAI,EAAE;QACrE,eAAe,EAAE,EAAE,CAAC,gBAAgB,KAAK,KAAK;QAC9C,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,yBAAyB,IAAI,EAAE,CAAC,gBAAgB,IAAI,GAAG,CAAC,IAAI,GAAG;KAC5F,CAAC;AACJ,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,cAAc,CAAC,GAAG;IAChC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAG7B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,4EAA4E;AAC5E,eAAO,MAAM,WAAW,EAAE,WAWzB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,qEAAqE;AAGrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,6DAA6D;AAC7D,6FAA6F;AAC7F,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AA2B7C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AAC7B,6DAA6D;AAC7D,iDAAiD;AACjD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAgB;IACtC,IAAI,EAAE,KAAK,IAAI,EAAE;QACf,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,UAAU,CAAC,CAAC;QACvD,+EAA+E;QAC/E,KAAK,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE,CACjD,OAAO,CAAC,IAAI,CAAC,4BAA6B,CAAW,CAAC,OAAO,EAAE,CAAC,CACjE,CAAC;IACJ,CAAC;IACD,QAAQ,EAAE,KAAK,IAAI,EAAE;QACnB,MAAM,OAAO,EAAE,CAAC;IAClB,CAAC;CACF,CAAC"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/** Порожній стан гілок. */
|
|
2
|
-
export function emptyThreads(): {
|
|
3
|
-
map: {};
|
|
4
|
-
last: null;
|
|
5
|
-
};
|
|
6
|
-
/**
|
|
7
|
-
* Визначити parent-повідомлення для прив'язки сесії:
|
|
8
|
-
* - explicit reply → той msgId;
|
|
9
|
-
* - інакше, якщо last у вікні replyWindow (сек) → last.msgId (implicit reply);
|
|
10
|
-
* - інакше null (нова гілка → нова сесія).
|
|
11
|
-
*/
|
|
12
|
-
export function resolveParent(threads: any, { replyToMsgId, now }: {
|
|
13
|
-
replyToMsgId: any;
|
|
14
|
-
now: any;
|
|
15
|
-
}, replyWindowSec: any): any;
|
|
16
|
-
/** sessionId, прив'язаний до parent-повідомлення, або null. */
|
|
17
|
-
export function getSession(threads: any, parentId: any): any;
|
|
18
|
-
/**
|
|
19
|
-
* Записати: вхідне повідомлення і відповідь бота → та сама сесія
|
|
20
|
-
* (щоб reply на будь-яке з них продовжував гілку). Оновити last.
|
|
21
|
-
*/
|
|
22
|
-
export function recordSession(threads: any, { msgId, botMsgId, sessionId, now }: {
|
|
23
|
-
msgId: any;
|
|
24
|
-
botMsgId: any;
|
|
25
|
-
sessionId: any;
|
|
26
|
-
now: any;
|
|
27
|
-
}): {
|
|
28
|
-
map: any;
|
|
29
|
-
last: {
|
|
30
|
-
msgId: any;
|
|
31
|
-
ts: any;
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
/** Прибрати записи старші за ttlDays (щоб файл не ріс безмежно). */
|
|
35
|
-
export function pruneThreads(threads: any, now: any, ttlDays: any): {
|
|
36
|
-
map: {};
|
|
37
|
-
last: any;
|
|
38
|
-
};
|
|
39
|
-
export function loadThreads(file: any): any;
|
|
40
|
-
export function saveThreads(file: any, threads: any): void;
|
|
41
|
-
//# sourceMappingURL=threads.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../../src/runtime/threads.js"],"names":[],"mappings":"AAGA,2BAA2B;AAC3B;;;EAEC;AAED;;;;;GAKG;AACH;;;6BAKC;AAED,+DAA+D;AAC/D,6DAGC;AAED;;;GAGG;AACH;;;;;;;;;;;EAKC;AAED,oEAAoE;AACpE;;;EAOC;AAED,4CAQC;AAED,2DAGC"}
|
package/dist/runtime/threads.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
/** Порожній стан гілок. */
|
|
4
|
-
export function emptyThreads() {
|
|
5
|
-
return { map: {}, last: null };
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Визначити parent-повідомлення для прив'язки сесії:
|
|
9
|
-
* - explicit reply → той msgId;
|
|
10
|
-
* - інакше, якщо last у вікні replyWindow (сек) → last.msgId (implicit reply);
|
|
11
|
-
* - інакше null (нова гілка → нова сесія).
|
|
12
|
-
*/
|
|
13
|
-
export function resolveParent(threads, { replyToMsgId, now }, replyWindowSec) {
|
|
14
|
-
if (replyToMsgId != null)
|
|
15
|
-
return replyToMsgId;
|
|
16
|
-
const last = threads.last;
|
|
17
|
-
if (last && now - last.ts < replyWindowSec * 1000)
|
|
18
|
-
return last.msgId;
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
/** sessionId, прив'язаний до parent-повідомлення, або null. */
|
|
22
|
-
export function getSession(threads, parentId) {
|
|
23
|
-
if (parentId == null)
|
|
24
|
-
return null;
|
|
25
|
-
return threads.map[parentId]?.sessionId ?? null;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Записати: вхідне повідомлення і відповідь бота → та сама сесія
|
|
29
|
-
* (щоб reply на будь-яке з них продовжував гілку). Оновити last.
|
|
30
|
-
*/
|
|
31
|
-
export function recordSession(threads, { msgId, botMsgId, sessionId, now }) {
|
|
32
|
-
const map = { ...threads.map };
|
|
33
|
-
map[msgId] = { sessionId, ts: now };
|
|
34
|
-
if (botMsgId != null)
|
|
35
|
-
map[botMsgId] = { sessionId, ts: now };
|
|
36
|
-
return { map, last: { msgId: botMsgId ?? msgId, ts: now } };
|
|
37
|
-
}
|
|
38
|
-
/** Прибрати записи старші за ttlDays (щоб файл не ріс безмежно). */
|
|
39
|
-
export function pruneThreads(threads, now, ttlDays) {
|
|
40
|
-
const cutoff = now - ttlDays * 86_400_000;
|
|
41
|
-
const map = {};
|
|
42
|
-
for (const [k, v] of Object.entries(threads.map)) {
|
|
43
|
-
if (v.ts >= cutoff)
|
|
44
|
-
map[k] = v;
|
|
45
|
-
}
|
|
46
|
-
return { map, last: threads.last };
|
|
47
|
-
}
|
|
48
|
-
export function loadThreads(file) {
|
|
49
|
-
try {
|
|
50
|
-
const obj = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
51
|
-
if (obj && typeof obj === 'object' && obj.map)
|
|
52
|
-
return obj;
|
|
53
|
-
return emptyThreads();
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return emptyThreads();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
export function saveThreads(file, threads) {
|
|
60
|
-
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
61
|
-
fs.writeFileSync(file, JSON.stringify(threads), 'utf-8');
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=threads.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"threads.js","sourceRoot":"","sources":["../../src/runtime/threads.js"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Прив'язати auth: symlink claude-home/.credentials.json → глобальний логін
|
|
3
|
-
* (~/.claude/.credentials.json). Так бот шарить уже налаштовану сесію і витрачає
|
|
4
|
-
* баланс підписки, а не окремий рахунок. Перестворюється щоразу (ідемпотентно).
|
|
5
|
-
* Якщо глобального файлу нема (напр. macOS keychain) — пропускаємо з warn.
|
|
6
|
-
* Безпека: claude-home лежить під APP_ROOT, а в settings.json є deny Read(APP_ROOT/**),
|
|
7
|
-
* тому Read-tool бота не може прочитати цей токен; внутрішнє auth-завантаження claude
|
|
8
|
-
* працює повз tool-дозволи.
|
|
9
|
-
*/
|
|
10
|
-
export function linkCredentials(cfg: any, log?: Console): boolean;
|
|
11
|
-
/**
|
|
12
|
-
* Ідемпотентно підготувати ізольований runtime бота: створити папки, згенерувати
|
|
13
|
-
* конфіги з абсолютними шляхами (APP_ROOT) — .mcp.json (тільки coffer) та
|
|
14
|
-
* claude-home/settings.json (обмежені інструменти, deny на код app), і прив'язати
|
|
15
|
-
* auth (symlink на глобальний логін). CLAUDE.md і skills не чіпаємо — версіонуються в git.
|
|
16
|
-
*/
|
|
17
|
-
export function ensureWorkspace(cfg: any, log?: Console): void;
|
|
18
|
-
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/runtime/workspace.js"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,kEASC;AAED;;;;;GAKG;AACH,+DAiCC"}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
* Прив'язати auth: symlink claude-home/.credentials.json → глобальний логін
|
|
5
|
-
* (~/.claude/.credentials.json). Так бот шарить уже налаштовану сесію і витрачає
|
|
6
|
-
* баланс підписки, а не окремий рахунок. Перестворюється щоразу (ідемпотентно).
|
|
7
|
-
* Якщо глобального файлу нема (напр. macOS keychain) — пропускаємо з warn.
|
|
8
|
-
* Безпека: claude-home лежить під APP_ROOT, а в settings.json є deny Read(APP_ROOT/**),
|
|
9
|
-
* тому Read-tool бота не може прочитати цей токен; внутрішнє auth-завантаження claude
|
|
10
|
-
* працює повз tool-дозволи.
|
|
11
|
-
*/
|
|
12
|
-
export function linkCredentials(cfg, log = console) {
|
|
13
|
-
const target = path.join(cfg.claudeHomeDir, '.credentials.json');
|
|
14
|
-
fs.rmSync(target, { force: true });
|
|
15
|
-
if (fs.existsSync(cfg.globalCredentials)) {
|
|
16
|
-
fs.symlinkSync(cfg.globalCredentials, target);
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
log.warn?.(`[telegram-bot] global credentials не знайдено (${cfg.globalCredentials}) — claude буде "Not logged in"`);
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Ідемпотентно підготувати ізольований runtime бота: створити папки, згенерувати
|
|
24
|
-
* конфіги з абсолютними шляхами (APP_ROOT) — .mcp.json (тільки coffer) та
|
|
25
|
-
* claude-home/settings.json (обмежені інструменти, deny на код app), і прив'язати
|
|
26
|
-
* auth (symlink на глобальний логін). CLAUDE.md і skills не чіпаємо — версіонуються в git.
|
|
27
|
-
*/
|
|
28
|
-
export function ensureWorkspace(cfg, log = console) {
|
|
29
|
-
fs.mkdirSync(path.join(cfg.stateDir, '.sessions'), { recursive: true });
|
|
30
|
-
fs.mkdirSync(path.join(cfg.workspaceDir, '.claude', 'skills'), { recursive: true });
|
|
31
|
-
fs.mkdirSync(cfg.claudeHomeDir, { recursive: true });
|
|
32
|
-
const mcp = {
|
|
33
|
-
mcpServers: {
|
|
34
|
-
coffer: {
|
|
35
|
-
command: 'npx',
|
|
36
|
-
args: ['tsx', path.join(cfg.appRoot, 'packages', 'mcp', 'bin', 'stdio.ts')],
|
|
37
|
-
env: { COFFER_URL: cfg.cofferUrl },
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
fs.writeFileSync(path.join(cfg.workspaceDir, '.mcp.json'), JSON.stringify(mcp, null, 2) + '\n', 'utf-8');
|
|
42
|
-
// Абсолютний шлях у permission-патернах Claude Code анкериться ПОДВІЙНИМ слешем
|
|
43
|
-
// (//abs/path); одинарний `/` означає відносно проєкту і НЕ матчить. deny має
|
|
44
|
-
// пріоритет і застосовується навіть під --dangerously-skip-permissions.
|
|
45
|
-
// Read у default-режимі авто-дозволений, тож код app блокуємо явним deny.
|
|
46
|
-
// appRoot покриває і workspace, і claude-home (вони під ним) → Read-tool бота не
|
|
47
|
-
// дістане ні код, ні .credentials.json. Skills вантажаться через Skill-tool, не Read.
|
|
48
|
-
const appGlob = `//${cfg.appRoot.replace(/^\/+/, '')}/**`;
|
|
49
|
-
const settings = {
|
|
50
|
-
permissions: {
|
|
51
|
-
allow: ['mcp__coffer__*', 'WebSearch', 'WebFetch', 'Skill'],
|
|
52
|
-
deny: ['Bash', 'Edit', 'Write', `Read(${appGlob})`, `Glob(${appGlob})`, `Grep(${appGlob})`],
|
|
53
|
-
},
|
|
54
|
-
enableAllProjectMcpServers: false,
|
|
55
|
-
};
|
|
56
|
-
fs.writeFileSync(path.join(cfg.claudeHomeDir, 'settings.json'), JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
57
|
-
linkCredentials(cfg, log);
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=workspace.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/runtime/workspace.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,mBAAmB,CAAC,CAAC;IACjE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACzC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,GAAG,CAAC,IAAI,EAAE,CAAC,kDAAkD,GAAG,CAAC,iBAAiB,iCAAiC,CAAC,CAAC;IACrH,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO;IAChD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpF,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAErD,MAAM,GAAG,GAAG;QACV,UAAU,EAAE;YACV,MAAM,EAAE;gBACN,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;gBAC3E,GAAG,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,SAAS,EAAE;aACnC;SACF;KACF,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAEzG,gFAAgF;IAChF,8EAA8E;IAC9E,wEAAwE;IACxE,0EAA0E;IAC1E,iFAAiF;IACjF,sFAAsF;IACtF,MAAM,OAAO,GAAG,KAAK,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC;IAC1D,MAAM,QAAQ,GAAG;QACf,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC;YAC3D,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,CAAC;SAC5F;QACD,0BAA0B,EAAE,KAAK;KAClC,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAEnH,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC"}
|