@gonzih/cc-tg 0.2.19 → 0.2.21
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 -5
- package/dist/claude.js +29 -27
- package/package.json +1 -1
package/dist/bot.d.ts
CHANGED
|
@@ -38,6 +38,7 @@ export declare class CcTgBot {
|
|
|
38
38
|
/** Kill cc-agent PIDs with SIGTERM. Returns the list of killed PIDs. */
|
|
39
39
|
private killCcAgent;
|
|
40
40
|
private handleReloadMcp;
|
|
41
|
+
private handleMcpStatus;
|
|
41
42
|
private handleMcpVersion;
|
|
42
43
|
private handleClearNpxCache;
|
|
43
44
|
private handleRestart;
|
package/dist/bot.js
CHANGED
|
@@ -20,6 +20,7 @@ const BOT_COMMANDS = [
|
|
|
20
20
|
{ command: "help", description: "Show all available commands" },
|
|
21
21
|
{ command: "cron", description: "Manage cron jobs — add/list/edit/remove/clear" },
|
|
22
22
|
{ command: "reload_mcp", description: "Restart the cc-agent MCP server process" },
|
|
23
|
+
{ command: "mcp_status", description: "Check MCP server connection status" },
|
|
23
24
|
{ command: "mcp_version", description: "Show cc-agent npm version and npx cache info" },
|
|
24
25
|
{ command: "clear_npx_cache", description: "Clear npx cache and restart MCP to pick up latest version" },
|
|
25
26
|
{ command: "restart", description: "Restart the bot process in-place" },
|
|
@@ -236,6 +237,11 @@ export class CcTgBot {
|
|
|
236
237
|
await this.handleReloadMcp(chatId);
|
|
237
238
|
return;
|
|
238
239
|
}
|
|
240
|
+
// /mcp_status — run `claude mcp list` and show connection status
|
|
241
|
+
if (text === "/mcp_status") {
|
|
242
|
+
await this.handleMcpStatus(chatId);
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
239
245
|
// /mcp_version — show published npm version and cached npx entries
|
|
240
246
|
if (text === "/mcp_version") {
|
|
241
247
|
await this.handleMcpVersion(chatId);
|
|
@@ -454,7 +460,12 @@ export class CcTgBot {
|
|
|
454
460
|
});
|
|
455
461
|
}
|
|
456
462
|
// Hybrid file upload: find files mentioned in result text that Claude actually wrote
|
|
457
|
-
|
|
463
|
+
try {
|
|
464
|
+
this.uploadMentionedFiles(chatId, text, session);
|
|
465
|
+
}
|
|
466
|
+
catch (err) {
|
|
467
|
+
console.error(`[tg:${chatId}] uploadMentionedFiles error:`, err.message);
|
|
468
|
+
}
|
|
458
469
|
}
|
|
459
470
|
trackWrittenFiles(msg, session, cwd) {
|
|
460
471
|
// Only look at assistant messages with tool_use blocks
|
|
@@ -608,7 +619,13 @@ export class CcTgBot {
|
|
|
608
619
|
console.log(`[claude:files] skipping sensitive file: ${filePath}`);
|
|
609
620
|
continue;
|
|
610
621
|
}
|
|
611
|
-
|
|
622
|
+
let fileSize;
|
|
623
|
+
try {
|
|
624
|
+
fileSize = statSync(filePath).size;
|
|
625
|
+
}
|
|
626
|
+
catch {
|
|
627
|
+
continue; // file disappeared between existsSync and statSync
|
|
628
|
+
}
|
|
612
629
|
const MAX_TG_FILE_BYTES = 50 * 1024 * 1024;
|
|
613
630
|
if (fileSize > MAX_TG_FILE_BYTES) {
|
|
614
631
|
const mb = (fileSize / (1024 * 1024)).toFixed(1);
|
|
@@ -660,7 +677,13 @@ export class CcTgBot {
|
|
|
660
677
|
output += text;
|
|
661
678
|
const result = output.trim();
|
|
662
679
|
if (result) {
|
|
663
|
-
|
|
680
|
+
let footer = "";
|
|
681
|
+
try {
|
|
682
|
+
footer = formatCronCostFooter(cronUsage);
|
|
683
|
+
}
|
|
684
|
+
catch (err) {
|
|
685
|
+
console.error(`[cron] cost footer error:`, err.message);
|
|
686
|
+
}
|
|
664
687
|
const chunks = splitMessage(`🕐 ${result}${footer}`);
|
|
665
688
|
(async () => {
|
|
666
689
|
for (const chunk of chunks) {
|
|
@@ -841,12 +864,30 @@ export class CcTgBot {
|
|
|
841
864
|
return pids;
|
|
842
865
|
}
|
|
843
866
|
async handleReloadMcp(chatId) {
|
|
867
|
+
await this.bot.sendMessage(chatId, "Clearing npx cache and reloading MCP...");
|
|
868
|
+
try {
|
|
869
|
+
const home = process.env.HOME ?? "~";
|
|
870
|
+
execSync(`rm -rf "${home}/.npm/_npx/"`, { encoding: "utf8", shell: "/bin/sh" });
|
|
871
|
+
console.log("[mcp] cleared ~/.npm/_npx/");
|
|
872
|
+
}
|
|
873
|
+
catch (err) {
|
|
874
|
+
await this.bot.sendMessage(chatId, `Warning: failed to clear npx cache: ${err.message}`);
|
|
875
|
+
}
|
|
844
876
|
const pids = this.killCcAgent();
|
|
845
877
|
if (pids.length === 0) {
|
|
846
|
-
await this.bot.sendMessage(chatId, "No cc-agent process found
|
|
878
|
+
await this.bot.sendMessage(chatId, "NPX cache cleared. No cc-agent process found — MCP will start fresh on the next agent call.");
|
|
847
879
|
return;
|
|
848
880
|
}
|
|
849
|
-
await this.bot.sendMessage(chatId, `Sent SIGTERM to cc-agent (pid${pids.length > 1 ? "s" : ""}: ${pids.join(", ")}).\nMCP restarted. New process will load on next agent call.`);
|
|
881
|
+
await this.bot.sendMessage(chatId, `NPX cache cleared. Sent SIGTERM to cc-agent (pid${pids.length > 1 ? "s" : ""}: ${pids.join(", ")}).\nMCP restarted. New process will load on next agent call.`);
|
|
882
|
+
}
|
|
883
|
+
async handleMcpStatus(chatId) {
|
|
884
|
+
try {
|
|
885
|
+
const output = execSync("claude mcp list", { encoding: "utf8", shell: "/bin/sh" }).trim();
|
|
886
|
+
await this.bot.sendMessage(chatId, `MCP server status:\n\n${output || "(no output)"}`);
|
|
887
|
+
}
|
|
888
|
+
catch (err) {
|
|
889
|
+
await this.bot.sendMessage(chatId, `Failed to run claude mcp list: ${err.message}`);
|
|
890
|
+
}
|
|
850
891
|
}
|
|
851
892
|
async handleMcpVersion(chatId) {
|
|
852
893
|
let npmVersion = "unknown";
|
package/dist/claude.js
CHANGED
|
@@ -107,38 +107,40 @@ export class ClaudeProcess extends EventEmitter {
|
|
|
107
107
|
for (const line of lines) {
|
|
108
108
|
if (!line.trim())
|
|
109
109
|
continue;
|
|
110
|
+
let raw;
|
|
110
111
|
try {
|
|
111
|
-
|
|
112
|
-
// Emit usage events from Anthropic API stream events passed through by Claude CLI
|
|
113
|
-
if (raw.type === "message_start") {
|
|
114
|
-
const usage = (raw.message?.usage);
|
|
115
|
-
if (usage) {
|
|
116
|
-
this.emit("usage", {
|
|
117
|
-
inputTokens: usage.input_tokens ?? 0,
|
|
118
|
-
outputTokens: 0, // output_tokens at message_start is always 0
|
|
119
|
-
cacheReadTokens: usage.cache_read_input_tokens ?? 0,
|
|
120
|
-
cacheWriteTokens: usage.cache_creation_input_tokens ?? 0,
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
else if (raw.type === "message_delta") {
|
|
125
|
-
const usage = raw.usage;
|
|
126
|
-
if (usage?.output_tokens) {
|
|
127
|
-
this.emit("usage", {
|
|
128
|
-
inputTokens: 0,
|
|
129
|
-
outputTokens: usage.output_tokens,
|
|
130
|
-
cacheReadTokens: 0,
|
|
131
|
-
cacheWriteTokens: 0,
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
const msg = this.parseMessage(raw);
|
|
136
|
-
if (msg)
|
|
137
|
-
this.emit("message", msg);
|
|
112
|
+
raw = JSON.parse(line);
|
|
138
113
|
}
|
|
139
114
|
catch {
|
|
140
115
|
// Non-JSON line (startup noise etc.) — ignore
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
// Emit usage events from Anthropic API stream events passed through by Claude CLI
|
|
119
|
+
if (raw.type === "message_start") {
|
|
120
|
+
const usage = (raw.message?.usage);
|
|
121
|
+
if (usage) {
|
|
122
|
+
this.emit("usage", {
|
|
123
|
+
inputTokens: usage.input_tokens ?? 0,
|
|
124
|
+
outputTokens: 0, // output_tokens at message_start is always 0
|
|
125
|
+
cacheReadTokens: usage.cache_read_input_tokens ?? 0,
|
|
126
|
+
cacheWriteTokens: usage.cache_creation_input_tokens ?? 0,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else if (raw.type === "message_delta") {
|
|
131
|
+
const usage = raw.usage;
|
|
132
|
+
if (usage?.output_tokens) {
|
|
133
|
+
this.emit("usage", {
|
|
134
|
+
inputTokens: 0,
|
|
135
|
+
outputTokens: usage.output_tokens,
|
|
136
|
+
cacheReadTokens: 0,
|
|
137
|
+
cacheWriteTokens: 0,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
141
140
|
}
|
|
141
|
+
const msg = this.parseMessage(raw);
|
|
142
|
+
if (msg)
|
|
143
|
+
this.emit("message", msg);
|
|
142
144
|
}
|
|
143
145
|
}
|
|
144
146
|
parseMessage(raw) {
|