chatccc 0.2.152 → 0.2.154

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.
@@ -1,67 +1,64 @@
1
- # Sending & Downloading Files/Videos
2
-
3
- ## Send Files or Videos
4
-
5
- Videos are sent as regular files (not media), which looks cleaner in Feishu.
6
-
7
- ### Script (recommended)
8
- ```bash
9
- node "{{send_file_script}}" --url "{{send_file_url}}" --session-id "{{session_id}}" --path "<absolute file path>" --caption "<optional caption>"
10
- ```
11
-
12
- ### Direct HTTP
13
- ```http
14
- POST {{send_file_url}}
15
- Content-Type: application/json; charset=utf-8
16
-
17
- {"session_id":"{{session_id}}","path":"<absolute file path>","caption":"<optional caption>"}
18
- ```
19
-
20
- ### Rules
21
-
22
- - Save or choose a local file first.
23
- - Use an absolute local path.
24
- - Max file size: 30MB.
25
- - Supported formats: .mp4 .mov .avi .mkv .webm .flv .mp3 .wav .ogg .aac .m4a .pdf .doc .docx .xls .xlsx .csv .ppt .pptx .txt .zip .tar .gz.
26
- - Only send a file/video when the user asked for one or when it materially helps the answer.
27
-
28
- ### Video Compression (when file > 30MB)
29
-
30
- If the video exceeds 30MB, compress it with ffmpeg before sending.
31
-
32
- **Ensure ffmpeg is available** (install if missing):
33
-
34
- | OS | Install command |
35
- |----|----------------|
36
- | macOS | `brew install ffmpeg` |
37
- | Linux (Debian/Ubuntu) | `sudo apt install ffmpeg` |
38
- | Linux (RHEL/Fedora) | `sudo dnf install ffmpeg` |
39
- | Windows | `winget install Gyan.FFmpeg` |
40
-
41
- **Two-pass compression** (target ~28MB for 30s video, adjust `b:v` for other durations):
42
-
43
- ```bash
44
- ffmpeg -y -i "<input>" -c:v libx264 -b:v <bitrate>k -pass 1 -f mp4 NUL
45
- ffmpeg -y -i "<input>" -c:v libx264 -b:v <bitrate>k -pass 2 -c:a aac -b:a 128k "<output>"
46
- ```
47
-
48
- Bitrate formula: `bitrate = 28 × 8 × 1000 ÷ duration_seconds - 128` (target ~28MB, safe under 30MB).
49
- On Windows replace `NUL` with `NUL` (same); on Linux/macOS use `/dev/null`.
50
-
51
- If the compressed file still exceeds 30MB, explain to the user that automatic compression wasn't enough and suggest they manually trim or re-encode the source.
52
-
53
- ## Download Files or Videos
54
-
55
- When the user sends a file or video to the bot, the message contains `message_id` and `file_key`. Download it with:
56
-
57
- ```bash
58
- node "{{download_video_script}}" --message-id <message_id> --file-key <file_key> --name <file_name>
59
- ```
60
-
61
- If only `chat_id` and `file_key` are available:
62
-
63
- ```bash
64
- node "{{download_video_script}}" --chat-id <chat_id> --file-key <file_key> --name <file_name>
65
- ```
66
-
1
+ # Sending & Downloading Files/Videos
2
+
3
+ ## Send Files or Videos
4
+
5
+ Videos are sent as regular files (not media), which looks cleaner in Feishu.
6
+
7
+ **Use the node script below. Do NOT use curl or raw HTTP — the script correctly handles errors and exits non-zero on failure.**
8
+
9
+ ### Script
10
+
11
+ ```bash
12
+ node "{{send_file_script}}" --url "{{send_file_url}}" --session-id "{{session_id}}" --path "<absolute file path>" --caption "<optional caption>"
13
+ ```
14
+
15
+ ### Rules
16
+
17
+ - Use the node script above — never curl or raw HTTP.
18
+ - Save or choose a local file first.
19
+ - Use an absolute local path.
20
+ - Max file size: 30MB.
21
+ - Supported formats: .mp4 .mov .avi .mkv .webm .flv .mp3 .wav .ogg .aac .m4a .pdf .doc .docx .xls .xlsx .csv .ppt .pptx .txt .zip .tar .gz.
22
+ - Only send a file/video when the user asked for one or when it materially helps the answer.
23
+ - **If the script fails (non-zero exit), read stderr for the error. Do NOT retry with the same path. Either fix the problem (wrong extension, missing file, etc.) or tell the user what the error was. Never retry more than once.**
24
+
25
+ ### Video Compression (when file > 30MB)
26
+
27
+ If the video exceeds 30MB, compress it with ffmpeg before sending.
28
+
29
+ **Ensure ffmpeg is available** (install if missing):
30
+
31
+ | OS | Install command |
32
+ |----|----------------|
33
+ | macOS | `brew install ffmpeg` |
34
+ | Linux (Debian/Ubuntu) | `sudo apt install ffmpeg` |
35
+ | Linux (RHEL/Fedora) | `sudo dnf install ffmpeg` |
36
+ | Windows | `winget install Gyan.FFmpeg` |
37
+
38
+ **Two-pass compression** (target ~28MB for 30s video, adjust `b:v` for other durations):
39
+
40
+ ```bash
41
+ ffmpeg -y -i "<input>" -c:v libx264 -b:v <bitrate>k -pass 1 -f mp4 NUL
42
+ ffmpeg -y -i "<input>" -c:v libx264 -b:v <bitrate>k -pass 2 -c:a aac -b:a 128k "<output>"
43
+ ```
44
+
45
+ Bitrate formula: `bitrate = 28 × 8 × 1000 ÷ duration_seconds - 128` (target ~28MB, safe under 30MB).
46
+ On Windows replace `NUL` with `NUL` (same); on Linux/macOS use `/dev/null`.
47
+
48
+ If the compressed file still exceeds 30MB, explain to the user that automatic compression wasn't enough and suggest they manually trim or re-encode the source.
49
+
50
+ ## Download Files or Videos
51
+
52
+ When the user sends a file or video to the bot, the message contains `message_id` and `file_key`. Download it with:
53
+
54
+ ```bash
55
+ node "{{download_video_script}}" --message-id <message_id> --file-key <file_key> --name <file_name>
56
+ ```
57
+
58
+ If only `chat_id` and `file_key` are available:
59
+
60
+ ```bash
61
+ node "{{download_video_script}}" --chat-id <chat_id> --file-key <file_key> --name <file_name>
62
+ ```
63
+
67
64
  Downloads are saved under `~/.chatccc/videos/downloads/`.
@@ -1,28 +1,25 @@
1
- # Sending & Receiving Images
2
-
3
- ## Send Images
4
-
5
- ### Script (recommended)
6
- ```bash
7
- node "{{send_image_script}}" --url "{{send_image_url}}" --session-id "{{session_id}}" --path "<absolute image path>" --caption "<optional caption>"
8
- ```
9
-
10
- ### Direct HTTP
11
- ```http
12
- POST {{send_image_url}}
13
- Content-Type: application/json; charset=utf-8
14
-
15
- {"session_id":"{{session_id}}","path":"<absolute image path>","caption":"<optional caption>"}
16
- ```
17
-
18
- ### Rules
19
-
20
- - Save or choose a local image file first.
21
- - Use an absolute local path.
22
- - Supported formats: .png, .jpg, .jpeg, .webp, .gif, .bmp.
23
- - Max image size: 10MB.
24
- - Only send an image when the user asked for one or when it materially helps the answer.
25
-
26
- ## Receive Images
27
-
1
+ # Sending & Receiving Images
2
+
3
+ ## Send Images
4
+
5
+ **Use the node script below. Do NOT use curl or raw HTTP — the script correctly handles errors and exits non-zero on failure.**
6
+
7
+ ### Script
8
+
9
+ ```bash
10
+ node "{{send_image_script}}" --url "{{send_image_url}}" --session-id "{{session_id}}" --path "<absolute image path>" --caption "<optional caption>"
11
+ ```
12
+
13
+ ### Rules
14
+
15
+ - Use the node script above — never curl or raw HTTP.
16
+ - Save or choose a local image file first.
17
+ - Use an absolute local path.
18
+ - Supported formats: .png, .jpg, .jpeg, .webp, .gif, .bmp.
19
+ - Max image size: 10MB.
20
+ - Only send an image when the user asked for one or when it materially helps the answer.
21
+ - **If the script fails (non-zero exit), read stderr for the error. Do NOT retry with the same path. Either fix the problem (wrong extension, missing file, etc.) or tell the user what the error was. Never retry more than once.**
22
+
23
+ ## Receive Images
24
+
28
25
  Images sent to the bot are automatically downloaded to `~/.chatccc/images/downloads/`. The message contains an `image_key` that maps to the cached file.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatccc",
3
- "version": "0.2.152",
3
+ "version": "0.2.154",
4
4
  "description": "Feishu bot bridge for Claude Code",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -10,9 +10,6 @@ export const AGENT_STOP_STUCK_PATH = "/api/agent/stop-stuck-loop";
10
10
 
11
11
  const MAX_REQUEST_BYTES = 8 * 1024;
12
12
 
13
- /** 已处理过 stop-stuck-loop 的 session,防止 agent 循环中反复调用 */
14
- const processedSessions = new Set<string>();
15
-
16
13
  function jsonReply(res: ServerResponse, status: number, data: unknown): void {
17
14
  res.writeHead(status, { "Content-Type": "application/json; charset=utf-8" });
18
15
  res.end(JSON.stringify(data));
@@ -68,19 +65,10 @@ export async function handleAgentStopStuckRequest(
68
65
 
69
66
  const prompt = activePrompts.get(sessionId);
70
67
  if (!prompt) {
71
- // session 可能已被清理,清理去重记录
72
- processedSessions.delete(sessionId);
73
68
  jsonReply(res, 404, { error: "Session not found or not running" });
74
69
  return true;
75
70
  }
76
71
 
77
- // 去重:同一 session 只处理一次,防止 agent 循环中反复调用
78
- if (processedSessions.has(sessionId)) {
79
- jsonReply(res, 200, { ok: true, deduplicated: true });
80
- return true;
81
- }
82
- processedSessions.add(sessionId);
83
-
84
72
  // 先发"卡住"提示消息给所有绑定的群聊
85
73
  const chats = getChatsForSession(sessionId);
86
74
  for (const chatId of chats) {