@gonzih/cc-tg 0.2.13 → 0.2.15
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/bot.d.ts +1 -0
- package/dist/bot.js +46 -7
- package/package.json +8 -3
package/dist/bot.d.ts
CHANGED
package/dist/bot.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* One ClaudeProcess per chat_id — sessions are isolated per user.
|
|
4
4
|
*/
|
|
5
5
|
import TelegramBot from "node-telegram-bot-api";
|
|
6
|
-
import { existsSync, createWriteStream, mkdirSync, statSync } from "fs";
|
|
6
|
+
import { existsSync, createWriteStream, mkdirSync, statSync, readdirSync } from "fs";
|
|
7
7
|
import { resolve, basename, join } from "path";
|
|
8
8
|
import os from "os";
|
|
9
9
|
import { execSync } from "child_process";
|
|
@@ -358,10 +358,45 @@ export class CcTgBot {
|
|
|
358
358
|
}
|
|
359
359
|
else if (name === "Bash") {
|
|
360
360
|
const cmd = input.command ?? "";
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
361
|
+
if (/\byt-dlp\b|\bffmpeg\b/.test(cmd)) {
|
|
362
|
+
// Scan output dir for recently modified media files (template paths like /tmp/%(title)s.%(ext)s
|
|
363
|
+
// make the actual filename unknowable at tracking time)
|
|
364
|
+
const oFlagMatch = cmd.match(/-o\s+["']?([^\s"']+)/);
|
|
365
|
+
let scanDir = "/tmp/";
|
|
366
|
+
if (oFlagMatch) {
|
|
367
|
+
const oPath = oFlagMatch[1].replace(/["'].*$/, "");
|
|
368
|
+
const dirEnd = oPath.lastIndexOf("/");
|
|
369
|
+
if (dirEnd > 0)
|
|
370
|
+
scanDir = oPath.slice(0, dirEnd + 1);
|
|
371
|
+
}
|
|
372
|
+
const MEDIA_EXTS = new Set([".mp3", ".mp4", ".wav", ".ogg", ".flac", ".webm", ".m4a", ".aac"]);
|
|
373
|
+
const nowMs = Date.now();
|
|
374
|
+
try {
|
|
375
|
+
for (const entry of readdirSync(scanDir)) {
|
|
376
|
+
const dotIdx = entry.lastIndexOf(".");
|
|
377
|
+
if (dotIdx < 0)
|
|
378
|
+
continue;
|
|
379
|
+
const ext = entry.slice(dotIdx).toLowerCase();
|
|
380
|
+
if (!MEDIA_EXTS.has(ext))
|
|
381
|
+
continue;
|
|
382
|
+
const full = join(scanDir, entry);
|
|
383
|
+
try {
|
|
384
|
+
if (nowMs - statSync(full).mtimeMs <= 90_000) {
|
|
385
|
+
console.log(`[claude:files] tracked yt-dlp/ffmpeg output: ${full}`);
|
|
386
|
+
session.writtenFiles.add(full);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
catch { /* skip unreadable entries */ }
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch { /* scanDir doesn't exist or unreadable */ }
|
|
393
|
+
}
|
|
394
|
+
else {
|
|
395
|
+
// Other bash commands: try to extract output path from -o flag
|
|
396
|
+
const oFlag = cmd.match(/-o\s+["']?([^\s"']+\.[\w]{1,10})["']?/);
|
|
397
|
+
if (oFlag)
|
|
398
|
+
session.writtenFiles.add(resolve(cwd ?? process.cwd(), oFlag[1]));
|
|
399
|
+
}
|
|
365
400
|
// mv source dest — track dest
|
|
366
401
|
const mvMatch = cmd.match(/\bmv\s+\S+\s+["']?([^\s"']+)["']?$/);
|
|
367
402
|
if (mvMatch)
|
|
@@ -387,7 +422,7 @@ export class CcTgBot {
|
|
|
387
422
|
/credential/i, /secret/i, /password/i, /passwd/i, /\.env/i,
|
|
388
423
|
/api[_-]?key/i, /token/i, /private[_-]?key/i, /id_rsa/i,
|
|
389
424
|
/\.pem$/i, /\.key$/i, /\.pfx$/i, /\.p12$/i,
|
|
390
|
-
/gmail/i, /oauth/i, /
|
|
425
|
+
/gmail/i, /oauth/i, /\bauth\b/i,
|
|
391
426
|
];
|
|
392
427
|
return sensitivePatterns.some((p) => p.test(name));
|
|
393
428
|
}
|
|
@@ -395,11 +430,15 @@ export class CcTgBot {
|
|
|
395
430
|
// Extract file path candidates from result text
|
|
396
431
|
// Match: /absolute/path/file.ext or relative like ./foo/bar.csv or just foo.pdf
|
|
397
432
|
const pathPattern = /(?:^|[\s`'"(])(\/?[\w.\-/]+\.[\w]{1,10})(?:[\s`'")\n]|$)/gm;
|
|
433
|
+
const quotedPattern = /"([^"]+\.[a-zA-Z0-9]{1,10})"|'([^']+\.[a-zA-Z0-9]{1,10})'/g;
|
|
398
434
|
const candidates = new Set();
|
|
399
435
|
let match;
|
|
400
436
|
while ((match = pathPattern.exec(resultText)) !== null) {
|
|
401
437
|
candidates.add(match[1]);
|
|
402
438
|
}
|
|
439
|
+
while ((match = quotedPattern.exec(resultText)) !== null) {
|
|
440
|
+
candidates.add(match[1] ?? match[2]);
|
|
441
|
+
}
|
|
403
442
|
const safeDirs = ["/tmp/", "/var/folders/", os.homedir() + "/Downloads/"];
|
|
404
443
|
const isSafeDir = (p) => safeDirs.some(d => p.startsWith(d)) || p.startsWith(this.opts.cwd ?? process.cwd());
|
|
405
444
|
const toUpload = [];
|
|
@@ -741,7 +780,7 @@ function downloadToFile(url, destPath) {
|
|
|
741
780
|
}).on("error", reject);
|
|
742
781
|
});
|
|
743
782
|
}
|
|
744
|
-
function splitMessage(text, maxLen = 4096) {
|
|
783
|
+
export function splitMessage(text, maxLen = 4096) {
|
|
745
784
|
if (text.length <= maxLen)
|
|
746
785
|
return [text];
|
|
747
786
|
const chunks = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gonzih/cc-tg",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"description": "Claude Code Telegram bot — chat with Claude Code via Telegram",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc",
|
|
11
11
|
"start": "node dist/index.js",
|
|
12
|
-
"dev": "node --loader ts-node/esm src/index.ts"
|
|
12
|
+
"dev": "node --loader ts-node/esm src/index.ts",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:watch": "vitest",
|
|
15
|
+
"test:coverage": "vitest run --coverage"
|
|
13
16
|
},
|
|
14
17
|
"files": [
|
|
15
18
|
"dist/"
|
|
@@ -20,7 +23,9 @@
|
|
|
20
23
|
"devDependencies": {
|
|
21
24
|
"@types/node": "^22.0.0",
|
|
22
25
|
"@types/node-telegram-bot-api": "^0.64.0",
|
|
23
|
-
"
|
|
26
|
+
"@vitest/coverage-v8": "^4.1.0",
|
|
27
|
+
"typescript": "^5.5.0",
|
|
28
|
+
"vitest": "^4.1.0"
|
|
24
29
|
},
|
|
25
30
|
"repository": {
|
|
26
31
|
"type": "git",
|