@fonz/tgcc 0.0.1 → 0.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.
@@ -0,0 +1,435 @@
1
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync, openSync, readSync, closeSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ // ── Session Store ──
5
+ export class SessionStore {
6
+ state;
7
+ filePath;
8
+ logger;
9
+ constructor(filePath, logger) {
10
+ this.filePath = filePath;
11
+ this.logger = logger;
12
+ this.state = this.load();
13
+ }
14
+ load() {
15
+ try {
16
+ if (existsSync(this.filePath)) {
17
+ return JSON.parse(readFileSync(this.filePath, 'utf-8'));
18
+ }
19
+ }
20
+ catch (err) {
21
+ this.logger.warn({ err }, 'Failed to load state file — starting fresh');
22
+ }
23
+ return { agents: {} };
24
+ }
25
+ save() {
26
+ try {
27
+ const dir = dirname(this.filePath);
28
+ if (!existsSync(dir))
29
+ mkdirSync(dir, { recursive: true });
30
+ writeFileSync(this.filePath, JSON.stringify(this.state, null, 2));
31
+ }
32
+ catch (err) {
33
+ this.logger.error({ err }, 'Failed to save state file');
34
+ }
35
+ }
36
+ ensureUser(agentId, userId) {
37
+ if (!this.state.agents[agentId]) {
38
+ this.state.agents[agentId] = { users: {} };
39
+ }
40
+ if (!this.state.agents[agentId].users[userId]) {
41
+ this.state.agents[agentId].users[userId] = {
42
+ currentSessionId: null,
43
+ lastActivity: new Date().toISOString(),
44
+ model: '',
45
+ repo: '',
46
+ permissionMode: '',
47
+ sessions: [],
48
+ knownSessionIds: [],
49
+ };
50
+ }
51
+ return this.state.agents[agentId].users[userId];
52
+ }
53
+ getUser(agentId, userId) {
54
+ return this.ensureUser(agentId, userId);
55
+ }
56
+ setCurrentSession(agentId, userId, sessionId) {
57
+ const user = this.ensureUser(agentId, userId);
58
+ user.currentSessionId = sessionId;
59
+ user.lastActivity = new Date().toISOString();
60
+ // Track as known TGCC session
61
+ if (!user.knownSessionIds.includes(sessionId)) {
62
+ user.knownSessionIds.push(sessionId);
63
+ }
64
+ // Add to session list if not already there
65
+ if (!user.sessions.find(s => s.id === sessionId)) {
66
+ user.sessions.push({
67
+ id: sessionId,
68
+ startedAt: new Date().toISOString(),
69
+ lastActivity: new Date().toISOString(),
70
+ messageCount: 0,
71
+ totalCostUsd: 0,
72
+ });
73
+ }
74
+ this.save();
75
+ }
76
+ updateSessionActivity(agentId, userId, cost) {
77
+ const user = this.ensureUser(agentId, userId);
78
+ user.lastActivity = new Date().toISOString();
79
+ const session = user.sessions.find(s => s.id === user.currentSessionId);
80
+ if (session) {
81
+ session.lastActivity = new Date().toISOString();
82
+ session.messageCount++;
83
+ if (cost !== undefined)
84
+ session.totalCostUsd = cost;
85
+ }
86
+ this.save();
87
+ }
88
+ setModel(agentId, userId, model) {
89
+ const user = this.ensureUser(agentId, userId);
90
+ user.model = model;
91
+ this.save();
92
+ }
93
+ setRepo(agentId, userId, repo) {
94
+ const user = this.ensureUser(agentId, userId);
95
+ user.repo = repo;
96
+ this.save();
97
+ }
98
+ setPermissionMode(agentId, userId, mode) {
99
+ const user = this.ensureUser(agentId, userId);
100
+ user.permissionMode = mode;
101
+ this.save();
102
+ }
103
+ setSessionTitle(agentId, userId, sessionId, title) {
104
+ const user = this.ensureUser(agentId, userId);
105
+ const session = user.sessions.find(s => s.id === sessionId);
106
+ if (session && !session.title) {
107
+ session.title = title.slice(0, 40);
108
+ this.save();
109
+ }
110
+ }
111
+ updateJsonlTracking(agentId, userId, size, mtimeMs) {
112
+ const user = this.ensureUser(agentId, userId);
113
+ user.jsonlTracking = { size, mtimeMs };
114
+ this.save();
115
+ }
116
+ getJsonlTracking(agentId, userId) {
117
+ const user = this.ensureUser(agentId, userId);
118
+ return user.jsonlTracking;
119
+ }
120
+ clearJsonlTracking(agentId, userId) {
121
+ const user = this.ensureUser(agentId, userId);
122
+ delete user.jsonlTracking;
123
+ this.save();
124
+ }
125
+ clearSession(agentId, userId) {
126
+ const user = this.ensureUser(agentId, userId);
127
+ user.currentSessionId = null;
128
+ delete user.jsonlTracking;
129
+ this.save();
130
+ }
131
+ deleteSession(agentId, userId, sessionId) {
132
+ const user = this.ensureUser(agentId, userId);
133
+ const idx = user.sessions.findIndex(s => s.id === sessionId);
134
+ if (idx === -1)
135
+ return false;
136
+ user.sessions.splice(idx, 1);
137
+ user.knownSessionIds = user.knownSessionIds.filter(id => id !== sessionId);
138
+ if (user.currentSessionId === sessionId) {
139
+ user.currentSessionId = null;
140
+ }
141
+ this.save();
142
+ return true;
143
+ }
144
+ getRecentSessions(agentId, userId, limit = 10) {
145
+ const user = this.ensureUser(agentId, userId);
146
+ return user.sessions.slice(-limit).reverse();
147
+ }
148
+ getFullState() {
149
+ return this.state;
150
+ }
151
+ }
152
+ // ── Session JSONL path resolution ──
153
+ /**
154
+ * Get the path to a CC session's JSONL file.
155
+ * CC stores sessions at ~/.claude/projects/<repo-slug>/<sessionId>.jsonl
156
+ */
157
+ export function getSessionJsonlPath(sessionId, repo) {
158
+ const slug = computeProjectSlug(repo);
159
+ return join(homedir(), '.claude', 'projects', slug, `${sessionId}.jsonl`);
160
+ }
161
+ /**
162
+ * Read new JSONL entries from a byte offset and summarize the turns.
163
+ * Returns a formatted catch-up message or null if nothing meaningful was found.
164
+ */
165
+ export function summarizeJsonlDelta(jsonlPath, fromByteOffset, maxChars = 2000) {
166
+ let rawBytes;
167
+ try {
168
+ const stat = statSync(jsonlPath);
169
+ if (stat.size <= fromByteOffset)
170
+ return null;
171
+ const bytesToRead = stat.size - fromByteOffset;
172
+ rawBytes = Buffer.alloc(bytesToRead);
173
+ const fd = openSync(jsonlPath, 'r');
174
+ try {
175
+ readSync(fd, rawBytes, 0, bytesToRead, fromByteOffset);
176
+ }
177
+ finally {
178
+ closeSync(fd);
179
+ }
180
+ }
181
+ catch {
182
+ return null;
183
+ }
184
+ const lines = rawBytes.toString('utf-8').split('\n').filter(Boolean);
185
+ const turns = [];
186
+ // Track seen assistant message UUIDs to deduplicate partial updates
187
+ const seenAssistantUuids = new Map(); // uuid → index in turns
188
+ for (const line of lines) {
189
+ let entry;
190
+ try {
191
+ entry = JSON.parse(line);
192
+ }
193
+ catch {
194
+ continue;
195
+ }
196
+ const entryType = entry.type;
197
+ const msg = entry.message;
198
+ if (!msg)
199
+ continue;
200
+ if (entryType === 'user' && msg.role === 'user') {
201
+ const content = msg.content;
202
+ let text;
203
+ if (typeof content === 'string') {
204
+ text = content;
205
+ }
206
+ else if (Array.isArray(content)) {
207
+ const textBlock = content.find((b) => b.type === 'text');
208
+ if (textBlock)
209
+ text = textBlock.text;
210
+ }
211
+ if (text) {
212
+ turns.push({ role: 'user', text: text.slice(0, 200) });
213
+ }
214
+ }
215
+ else if (entryType === 'assistant' && msg.role === 'assistant') {
216
+ const uuid = entry.uuid;
217
+ const content = msg.content;
218
+ if (!content || !Array.isArray(content))
219
+ continue;
220
+ // Extract text and tools from this assistant message
221
+ const texts = [];
222
+ const tools = [];
223
+ for (const block of content) {
224
+ if (block.type === 'text' && typeof block.text === 'string') {
225
+ const trimmed = block.text.trim();
226
+ if (trimmed)
227
+ texts.push(trimmed);
228
+ }
229
+ else if (block.type === 'tool_use') {
230
+ tools.push(block.name);
231
+ }
232
+ }
233
+ // Deduplicate: CC emits partial assistant messages with the same UUID
234
+ // as it streams. Keep updating the same turn entry.
235
+ if (uuid && seenAssistantUuids.has(uuid)) {
236
+ const idx = seenAssistantUuids.get(uuid);
237
+ const existing = turns[idx];
238
+ if (texts.length > 0)
239
+ existing.text = texts.join(' ').slice(0, 200);
240
+ if (tools.length > 0)
241
+ existing.tools = [...new Set([...(existing.tools ?? []), ...tools])];
242
+ }
243
+ else {
244
+ const turn = { role: 'assistant' };
245
+ if (texts.length > 0)
246
+ turn.text = texts.join(' ').slice(0, 200);
247
+ if (tools.length > 0)
248
+ turn.tools = tools;
249
+ if (uuid)
250
+ seenAssistantUuids.set(uuid, turns.length);
251
+ turns.push(turn);
252
+ }
253
+ }
254
+ }
255
+ // Filter out empty assistant turns (only had thinking blocks, etc.)
256
+ const meaningful = turns.filter(t => t.text || (t.tools && t.tools.length > 0));
257
+ if (meaningful.length === 0)
258
+ return null;
259
+ return formatStaleSummary(meaningful, maxChars);
260
+ }
261
+ function formatStaleSummary(turns, maxChars) {
262
+ const turnCount = turns.filter(t => t.role === 'assistant').length;
263
+ const header = `ℹ️ <b>Session was updated from another client</b> (${turnCount} CC turn${turnCount !== 1 ? 's' : ''} since your last message here):\n\n`;
264
+ const lines = [];
265
+ // Build from newest to oldest so we can truncate old ones
266
+ for (const turn of turns) {
267
+ if (turn.role === 'user') {
268
+ const preview = truncateText(turn.text ?? '', 80);
269
+ lines.push(`• <b>You:</b> "${preview}"`);
270
+ }
271
+ else {
272
+ const parts = [];
273
+ if (turn.tools && turn.tools.length > 0) {
274
+ parts.push(`Used ${turn.tools.join(', ')}`);
275
+ }
276
+ if (turn.text) {
277
+ const preview = truncateText(turn.text, 120);
278
+ parts.push(`"${preview}"`);
279
+ }
280
+ lines.push(`• <b>CC:</b> ${parts.join(' — ') || '(no text)'}`);
281
+ }
282
+ }
283
+ // Truncate from the front (oldest) if too long
284
+ let body = lines.join('\n');
285
+ while (body.length + header.length + 20 > maxChars && lines.length > 2) {
286
+ lines.shift();
287
+ body = `…\n${lines.join('\n')}`;
288
+ }
289
+ return header + body + '\n\n_Reconnecting..._';
290
+ }
291
+ function truncateText(text, maxLen) {
292
+ // Collapse whitespace
293
+ const clean = text.replace(/\s+/g, ' ').trim();
294
+ if (clean.length <= maxLen)
295
+ return clean;
296
+ return clean.slice(0, maxLen - 1) + '…';
297
+ }
298
+ export function computeProjectSlug(repoPath) {
299
+ // CC stores at ~/.claude/projects/<slug>/sessions/
300
+ // Slug is the path with / replaced by - and leading -
301
+ return repoPath.replace(/\//g, '-');
302
+ }
303
+ export function findMissedSessions(repo, knownSessionIds, lastActivity) {
304
+ const slug = computeProjectSlug(repo);
305
+ const sessionsDir = join(homedir(), '.claude', 'projects', slug, 'sessions');
306
+ if (!existsSync(sessionsDir))
307
+ return [];
308
+ const knownSet = new Set(knownSessionIds);
309
+ const entries = readdirSync(sessionsDir);
310
+ const missed = [];
311
+ for (const entry of entries) {
312
+ const entryPath = join(sessionsDir, entry);
313
+ try {
314
+ const stat = statSync(entryPath);
315
+ if (!stat.isDirectory())
316
+ continue;
317
+ if (stat.mtime <= lastActivity)
318
+ continue;
319
+ if (knownSet.has(entry))
320
+ continue;
321
+ // List files in this session dir
322
+ const files = readdirSync(entryPath);
323
+ missed.push({ id: entry, mtime: stat.mtime, files });
324
+ }
325
+ catch {
326
+ continue;
327
+ }
328
+ }
329
+ return missed.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
330
+ }
331
+ export function parseSessionSummary(sessionDir) {
332
+ // Read session conversation data and produce a summary
333
+ try {
334
+ const files = readdirSync(sessionDir);
335
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
336
+ if (jsonFiles.length === 0)
337
+ return 'Empty session';
338
+ // Read the conversation file
339
+ for (const f of jsonFiles) {
340
+ try {
341
+ const content = JSON.parse(readFileSync(join(sessionDir, f), 'utf-8'));
342
+ return extractSessionHighlights(content);
343
+ }
344
+ catch {
345
+ continue;
346
+ }
347
+ }
348
+ return `Session with ${files.length} file(s)`;
349
+ }
350
+ catch {
351
+ return 'Could not read session';
352
+ }
353
+ }
354
+ function extractSessionHighlights(data) {
355
+ if (!data || typeof data !== 'object')
356
+ return 'Unknown session format';
357
+ const highlights = [];
358
+ const toolsUsed = new Set();
359
+ const filesEdited = new Set();
360
+ let turnCount = 0;
361
+ // Try to parse as array of messages or as an object with messages
362
+ const messages = Array.isArray(data)
363
+ ? data
364
+ : data.messages ?? [];
365
+ for (const msg of messages) {
366
+ if (!msg || typeof msg !== 'object')
367
+ continue;
368
+ const m = msg;
369
+ if (m.role === 'assistant') {
370
+ turnCount++;
371
+ const content = m.content;
372
+ if (Array.isArray(content)) {
373
+ for (const block of content) {
374
+ if (!block || typeof block !== 'object')
375
+ continue;
376
+ const b = block;
377
+ if (b.type === 'tool_use') {
378
+ toolsUsed.add(b.name);
379
+ // Extract file paths from tool inputs
380
+ const input = b.input;
381
+ if (input?.file_path)
382
+ filesEdited.add(input.file_path);
383
+ if (input?.path)
384
+ filesEdited.add(input.path);
385
+ }
386
+ if (b.type === 'text' && typeof b.text === 'string' && highlights.length < 3) {
387
+ const text = b.text.slice(0, 100);
388
+ if (text.trim())
389
+ highlights.push(text);
390
+ }
391
+ }
392
+ }
393
+ }
394
+ }
395
+ const parts = [];
396
+ parts.push(`${turnCount} turn(s)`);
397
+ if (toolsUsed.size > 0)
398
+ parts.push(`Tools: ${[...toolsUsed].join(', ')}`);
399
+ if (filesEdited.size > 0)
400
+ parts.push(`Files: ${[...filesEdited].slice(0, 5).join(', ')}`);
401
+ if (highlights.length > 0)
402
+ parts.push(`Topic: ${highlights[0]}`);
403
+ return parts.join(' | ');
404
+ }
405
+ export function formatCatchupMessage(repo, missed) {
406
+ if (missed.length === 0) {
407
+ return "You're up to date — no external CC activity since your last message.";
408
+ }
409
+ const slug = computeProjectSlug(repo);
410
+ const sessionsDir = join(homedir(), '.claude', 'projects', slug, 'sessions');
411
+ const lines = [`<b>External CC activity</b> (${missed.length} session(s)):\n`];
412
+ for (const session of missed.slice(0, 5)) {
413
+ const age = formatAge(session.mtime);
414
+ const summary = parseSessionSummary(join(sessionsDir, session.id));
415
+ lines.push(`<code>${session.id.slice(0, 8)}</code> (${age})`);
416
+ lines.push(` ${summary}\n`);
417
+ }
418
+ if (missed.length > 5) {
419
+ lines.push(`...and ${missed.length - 5} more session(s).`);
420
+ }
421
+ lines.push(`\nUse /resume <id> to continue any of these sessions.`);
422
+ return lines.join('\n');
423
+ }
424
+ function formatAge(date) {
425
+ const diffMs = Date.now() - date.getTime();
426
+ const mins = Math.floor(diffMs / 60000);
427
+ if (mins < 60)
428
+ return `${mins}m ago`;
429
+ const hours = Math.floor(mins / 60);
430
+ if (hours < 24)
431
+ return `${hours}h ago`;
432
+ const days = Math.floor(hours / 24);
433
+ return `${days}d ago`;
434
+ }
435
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import type { StreamInnerEvent } from './cc-protocol.js';
2
+ export interface TelegramSender {
3
+ sendMessage(chatId: number | string, text: string, parseMode?: string): Promise<number>;
4
+ editMessage(chatId: number | string, messageId: number, text: string, parseMode?: string): Promise<void>;
5
+ sendPhoto?(chatId: number | string, imageBuffer: Buffer, caption?: string): Promise<number>;
6
+ }
7
+ export interface TurnUsage {
8
+ inputTokens: number;
9
+ outputTokens: number;
10
+ cacheReadTokens: number;
11
+ cacheCreationTokens: number;
12
+ costUsd: number | null;
13
+ }
14
+ export interface StreamAccumulatorOptions {
15
+ chatId: number | string;
16
+ sender: TelegramSender;
17
+ editIntervalMs?: number;
18
+ splitThreshold?: number;
19
+ }
20
+ /** Escape characters that are special in Telegram HTML. */
21
+ export declare function escapeHtml(text: string): string;
22
+ /**
23
+ * Convert markdown-ish text to Telegram-safe HTML.
24
+ * Handles code blocks, inline code, bold, italic, strikethrough, links.
25
+ * Falls back to HTML-escaped plain text for anything it can't convert.
26
+ */
27
+ export declare function markdownToHtml(text: string): string;
28
+ /**
29
+ * Make text safe for Telegram HTML parse mode during streaming.
30
+ * Closes unclosed HTML tags from partial markdown conversion.
31
+ */
32
+ export declare function makeHtmlSafe(text: string): string;
33
+ /** @deprecated Use makeHtmlSafe instead */
34
+ export declare function makeMarkdownSafe(text: string): string;
35
+ export declare class StreamAccumulator {
36
+ private chatId;
37
+ private sender;
38
+ private editIntervalMs;
39
+ private splitThreshold;
40
+ private tgMessageId;
41
+ private buffer;
42
+ private thinkingBuffer;
43
+ private imageBase64Buffer;
44
+ private currentBlockType;
45
+ private lastEditTime;
46
+ private editTimer;
47
+ private thinkingIndicatorShown;
48
+ private toolIndicators;
49
+ private messageIds;
50
+ private finished;
51
+ private sendQueue;
52
+ private turnUsage;
53
+ constructor(options: StreamAccumulatorOptions);
54
+ get allMessageIds(): number[];
55
+ /** Set usage stats for the current turn (called from bridge on result event) */
56
+ setTurnUsage(usage: TurnUsage): void;
57
+ handleEvent(event: StreamInnerEvent): Promise<void>;
58
+ private onContentBlockStart;
59
+ private onContentBlockDelta;
60
+ /** Send or edit a message. If rawHtml is true, text is already HTML-safe. */
61
+ private sendOrEdit;
62
+ private _doSendOrEdit;
63
+ private sendImage;
64
+ private showToolIndicator;
65
+ private throttledEdit;
66
+ /** Build the full message text including thinking blockquote prefix and usage footer */
67
+ private buildFullText;
68
+ private doEdit;
69
+ private splitMessage;
70
+ finalize(): Promise<void>;
71
+ /** Soft reset: clear buffer/state but keep tgMessageId so next turn edits the same message */
72
+ softReset(): void;
73
+ /** Full reset: also clears tgMessageId (next send creates a new message) */
74
+ reset(): void;
75
+ }
76
+ /** Format usage stats as an HTML italic footer line */
77
+ export declare function formatUsageFooter(usage: TurnUsage): string;
78
+ export declare function isSubAgentTool(toolName: string): boolean;
79
+ export interface SubAgentInfo {
80
+ toolUseId: string;
81
+ toolName: string;
82
+ blockIndex: number;
83
+ tgMessageId: number | null;
84
+ status: 'running' | 'completed' | 'failed';
85
+ inputPreview: string;
86
+ }
87
+ export interface SubAgentSender {
88
+ replyToMessage(chatId: number | string, text: string, replyToMessageId: number, parseMode?: string): Promise<number>;
89
+ editMessage(chatId: number | string, messageId: number, text: string, parseMode?: string): Promise<void>;
90
+ }
91
+ export interface SubAgentTrackerOptions {
92
+ chatId: number | string;
93
+ sender: SubAgentSender;
94
+ /** Returns the main streaming message ID to reply to */
95
+ getMainMessageId: () => number | null;
96
+ }
97
+ export declare class SubAgentTracker {
98
+ private chatId;
99
+ private sender;
100
+ private getMainMessageId;
101
+ private agents;
102
+ private blockToAgent;
103
+ private sendQueue;
104
+ constructor(options: SubAgentTrackerOptions);
105
+ get activeAgents(): SubAgentInfo[];
106
+ handleEvent(event: StreamInnerEvent): Promise<void>;
107
+ private onBlockStart;
108
+ private onInputDelta;
109
+ private onBlockStop;
110
+ reset(): void;
111
+ }
112
+ export declare function splitText(text: string, maxLength?: number): string[];