@gonzih/cc-tg 0.9.15 → 0.9.17
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/README.md +36 -0
- package/dist/bot.d.ts +35 -4
- package/dist/bot.js +536 -337
- package/dist/cron.d.ts +7 -1
- package/dist/cron.js +24 -3
- package/dist/formatter.d.ts +14 -12
- package/dist/formatter.js +72 -36
- package/dist/index.js +77 -21
- package/dist/notifier.d.ts +37 -0
- package/dist/notifier.js +154 -0
- package/dist/tokens.d.ts +22 -0
- package/dist/tokens.js +56 -0
- package/dist/usage-limit.js +2 -3
- package/dist/voice.js +28 -26
- package/package.json +4 -3
package/dist/tokens.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth token pool management.
|
|
3
|
+
*
|
|
4
|
+
* Supports CLAUDE_CODE_OAUTH_TOKENS (comma-separated list of tokens).
|
|
5
|
+
* Falls back to CLAUDE_CODE_OAUTH_TOKEN for single-token / backwards compat.
|
|
6
|
+
*/
|
|
7
|
+
let tokens = [];
|
|
8
|
+
let currentIndex = 0;
|
|
9
|
+
let initialized = false;
|
|
10
|
+
/**
|
|
11
|
+
* Load tokens from env vars. Called on startup; also re-callable in tests.
|
|
12
|
+
* Priority: CLAUDE_CODE_OAUTH_TOKENS > CLAUDE_CODE_OAUTH_TOKEN > (empty)
|
|
13
|
+
*/
|
|
14
|
+
export function loadTokens() {
|
|
15
|
+
const multi = process.env.CLAUDE_CODE_OAUTH_TOKENS;
|
|
16
|
+
if (multi) {
|
|
17
|
+
tokens = multi.split(",").map((t) => t.trim()).filter(Boolean);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const single = process.env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
21
|
+
tokens = single ? [single] : [];
|
|
22
|
+
}
|
|
23
|
+
currentIndex = 0;
|
|
24
|
+
initialized = true;
|
|
25
|
+
return tokens;
|
|
26
|
+
}
|
|
27
|
+
function ensureInitialized() {
|
|
28
|
+
if (!initialized)
|
|
29
|
+
loadTokens();
|
|
30
|
+
}
|
|
31
|
+
/** Returns the current active token, or empty string if none configured. */
|
|
32
|
+
export function getCurrentToken() {
|
|
33
|
+
ensureInitialized();
|
|
34
|
+
return tokens[currentIndex] ?? "";
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Advance to the next token (wraps around).
|
|
38
|
+
* Returns the new current token.
|
|
39
|
+
*/
|
|
40
|
+
export function rotateToken() {
|
|
41
|
+
ensureInitialized();
|
|
42
|
+
if (tokens.length === 0)
|
|
43
|
+
return "";
|
|
44
|
+
currentIndex = (currentIndex + 1) % tokens.length;
|
|
45
|
+
return tokens[currentIndex];
|
|
46
|
+
}
|
|
47
|
+
/** Zero-based index of the current token. */
|
|
48
|
+
export function getTokenIndex() {
|
|
49
|
+
ensureInitialized();
|
|
50
|
+
return currentIndex;
|
|
51
|
+
}
|
|
52
|
+
/** Total number of tokens in the pool. */
|
|
53
|
+
export function getTokenCount() {
|
|
54
|
+
ensureInitialized();
|
|
55
|
+
return tokens.length;
|
|
56
|
+
}
|
package/dist/usage-limit.js
CHANGED
|
@@ -3,8 +3,7 @@ export function detectUsageLimit(text) {
|
|
|
3
3
|
if (lower.includes('extra usage') ||
|
|
4
4
|
lower.includes('usage has been disabled') ||
|
|
5
5
|
lower.includes('billing_error') ||
|
|
6
|
-
lower.includes('usage limit
|
|
7
|
-
lower.includes('your usage limit')) {
|
|
6
|
+
lower.includes('usage limit')) {
|
|
8
7
|
const wake = nextHourBoundary() + 5 * 60 * 1000;
|
|
9
8
|
return {
|
|
10
9
|
detected: true,
|
|
@@ -13,7 +12,7 @@ export function detectUsageLimit(text) {
|
|
|
13
12
|
humanMessage: `⏸ Claude usage limit reached. Will auto-resume at ${new Date(wake).toUTCString()}. I'll message you when it's back.`,
|
|
14
13
|
};
|
|
15
14
|
}
|
|
16
|
-
if (lower.includes('
|
|
15
|
+
if (lower.includes('rate limit') || lower.includes('overloaded')) {
|
|
17
16
|
return {
|
|
18
17
|
detected: true,
|
|
19
18
|
reason: 'rate_limit',
|
package/dist/voice.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { execFile } from "child_process";
|
|
6
6
|
import { promisify } from "util";
|
|
7
7
|
import { existsSync } from "fs";
|
|
8
|
-
import { unlink } from "fs/promises";
|
|
8
|
+
import { unlink, readFile } from "fs/promises";
|
|
9
9
|
import { tmpdir } from "os";
|
|
10
10
|
import { join } from "path";
|
|
11
11
|
import https from "https";
|
|
@@ -92,32 +92,34 @@ export async function transcribeVoice(fileUrl) {
|
|
|
92
92
|
"-c:a", "pcm_s16le",
|
|
93
93
|
wavPath,
|
|
94
94
|
]);
|
|
95
|
-
// 3. Run whisper-cpp
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
95
|
+
// 3. Run whisper-cpp
|
|
96
|
+
// --output-txt writes to ${wavPath}.txt (NOT stdout)
|
|
97
|
+
// -l auto fails with .en models — detect and use -l en instead
|
|
98
|
+
const isEnModel = model.includes(".en.");
|
|
99
|
+
const langArgs = isEnModel ? ["-l", "en"] : ["-l", "auto"];
|
|
100
|
+
try {
|
|
101
|
+
await execFileAsync(whisperBin, [
|
|
102
|
+
"-m", model,
|
|
103
|
+
"-f", wavPath,
|
|
104
|
+
"--no-timestamps",
|
|
105
|
+
...langArgs,
|
|
106
|
+
"--output-txt", // writes to wavPath + ".txt"
|
|
107
|
+
]);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
111
|
+
throw new Error(`whisper-cpp failed: ${msg}`);
|
|
112
|
+
}
|
|
113
|
+
// Read the output file whisper-cpp wrote
|
|
114
|
+
const txtPath = `${wavPath}.txt`;
|
|
115
|
+
let raw = "";
|
|
116
|
+
try {
|
|
117
|
+
raw = await readFile(txtPath, "utf-8");
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
throw new Error("whisper-cpp ran but produced no output file");
|
|
118
121
|
}
|
|
119
|
-
|
|
120
|
-
const text = stdout
|
|
122
|
+
const text = raw
|
|
121
123
|
.replace(/\[BLANK_AUDIO\]/gi, "")
|
|
122
124
|
.replace(/\[.*?\]/g, "") // remove timestamp artifacts
|
|
123
125
|
.trim();
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gonzih/cc-tg",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.17",
|
|
4
4
|
"description": "Claude Code Telegram bot — chat with Claude Code via Telegram",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cc-tg": "./dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "tsc",
|
|
10
|
+
"build": "tsc && chmod +x dist/index.js",
|
|
11
11
|
"start": "node dist/index.js",
|
|
12
12
|
"dev": "node --loader ts-node/esm src/index.ts",
|
|
13
13
|
"test": "vitest run",
|
|
@@ -18,10 +18,11 @@
|
|
|
18
18
|
"dist/"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@gonzih/agent-ops": "^0.1.0",
|
|
21
22
|
"node-telegram-bot-api": "^0.66.0"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
|
-
"@types/node": "^22.
|
|
25
|
+
"@types/node": "^22.0.0",
|
|
25
26
|
"@types/node-telegram-bot-api": "^0.64.0",
|
|
26
27
|
"@vitest/coverage-v8": "^4.1.0",
|
|
27
28
|
"typescript": "^5.5.0",
|