chatcc-agent 0.3.5 → 0.3.6
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/package.json +1 -1
- package/src/claude-bridge.js +5 -0
- package/src/constants.js +6 -1
- package/src/im-client.js +20 -4
- package/src/index.js +58 -0
- package/src/server-info.js +3 -1
package/package.json
CHANGED
package/src/claude-bridge.js
CHANGED
|
@@ -614,6 +614,11 @@ class ClaudeBridge {
|
|
|
614
614
|
session_id: sessionID,
|
|
615
615
|
tool_use_id: block.id,
|
|
616
616
|
questions: block.input?.questions || [],
|
|
617
|
+
}, {
|
|
618
|
+
title: 'Claude 有问题',
|
|
619
|
+
desc: '需要您的选择',
|
|
620
|
+
ext: JSON.stringify({ session_id: sessionID, push_type: 'agent_reply' }),
|
|
621
|
+
ignoreBadge: false,
|
|
617
622
|
}).catch(e => console.error('[Bridge] user_question:', e.message));
|
|
618
623
|
} else {
|
|
619
624
|
this._handleToolUseBlock(block, replyTo, msgID, streamBuffer, sessionID, cwd, workspaceRestricted, permissions, useControl, sendStreamEnd);
|
package/src/constants.js
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
* Chinese display labels live on the iOS side only.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
// Protocol versioning — bump CURRENT when introducing breaking changes.
|
|
7
|
+
// MIN is the oldest client/agent version we still support.
|
|
8
|
+
const CURRENT_PROTOCOL_VERSION = 1;
|
|
9
|
+
const MIN_PROTOCOL_VERSION = 1;
|
|
10
|
+
|
|
6
11
|
// Default permission modes (sent as default_mode in session settings)
|
|
7
12
|
const PERMISSION_MODES = {
|
|
8
13
|
CONFIRM_EVERY: 'confirm_every', // 每次确认
|
|
@@ -34,4 +39,4 @@ function normalizePermission(value) {
|
|
|
34
39
|
return LEGACY_MODE_MAP[value] || value;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
|
-
module.exports = { PERMISSION_MODES, PERMISSION_ACTIONS, LEGACY_MODE_MAP, normalizePermission };
|
|
42
|
+
module.exports = { CURRENT_PROTOCOL_VERSION, MIN_PROTOCOL_VERSION, PERMISSION_MODES, PERMISSION_ACTIONS, LEGACY_MODE_MAP, normalizePermission };
|
package/src/im-client.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const WebSocket = require('ws');
|
|
2
2
|
global.WebSocket = WebSocket;
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const { CURRENT_PROTOCOL_VERSION, MIN_PROTOCOL_VERSION } = require('./constants');
|
|
5
|
+
const PROTOCOL_VERSION = CURRENT_PROTOCOL_VERSION;
|
|
5
6
|
|
|
6
7
|
class IMClient {
|
|
7
8
|
constructor(sdkAppID, userID, userSig, options = {}) {
|
|
@@ -134,16 +135,31 @@ class IMClient {
|
|
|
134
135
|
this._messageHandlers.push(handler);
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
async sendCustomMessage(to, ccType, payload = {}) {
|
|
138
|
+
async sendCustomMessage(to, ccType, payload = {}, pushOptions = null) {
|
|
138
139
|
const message = this.tim.createCustomMessage({
|
|
139
140
|
to,
|
|
140
141
|
conversationType: this.TIM.TYPES.CONV_C2C,
|
|
141
142
|
payload: {
|
|
142
|
-
data: JSON.stringify({ cc_type: ccType, v: PROTOCOL_VERSION, ...payload }),
|
|
143
|
+
data: JSON.stringify({ cc_type: ccType, v: PROTOCOL_VERSION, min_v: MIN_PROTOCOL_VERSION, ...payload }),
|
|
143
144
|
description: 'CCLink',
|
|
144
145
|
},
|
|
145
146
|
});
|
|
146
|
-
|
|
147
|
+
|
|
148
|
+
// Default: silent (disablePush). Only messages with explicit pushOptions trigger notifications.
|
|
149
|
+
const sendOpts = {};
|
|
150
|
+
if (pushOptions) {
|
|
151
|
+
sendOpts.offlinePushInfo = {
|
|
152
|
+
title: pushOptions.title || 'CCLink',
|
|
153
|
+
description: pushOptions.desc || '',
|
|
154
|
+
extension: pushOptions.ext || '',
|
|
155
|
+
disablePush: false,
|
|
156
|
+
apnsInfo: { ignoreIOSBadge: pushOptions.ignoreBadge ?? false },
|
|
157
|
+
};
|
|
158
|
+
} else {
|
|
159
|
+
sendOpts.offlinePushInfo = { disablePush: true };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
await this.tim.sendMessage(message, sendOpts);
|
|
147
163
|
return message.ID;
|
|
148
164
|
}
|
|
149
165
|
}
|
package/src/index.js
CHANGED
|
@@ -133,6 +133,28 @@ async function shutdown(signal) {
|
|
|
133
133
|
|
|
134
134
|
process.on('exit', cleanupTempFiles);
|
|
135
135
|
|
|
136
|
+
async function checkForUpdates(agentID, pairedClientIDs) {
|
|
137
|
+
try {
|
|
138
|
+
const { execSync } = require('child_process');
|
|
139
|
+
const currentVersion = getVersion();
|
|
140
|
+
const latestVersion = execSync('npm view chatcc-agent version', {
|
|
141
|
+
encoding: 'utf-8', timeout: 15000,
|
|
142
|
+
}).trim();
|
|
143
|
+
if (latestVersion && latestVersion !== currentVersion) {
|
|
144
|
+
console.log(`[Update] New version available: ${currentVersion} -> ${latestVersion}`);
|
|
145
|
+
for (const clientID of pairedClientIDs) {
|
|
146
|
+
imClient.sendCustomMessage(clientID, 'update_available', {
|
|
147
|
+
current_version: currentVersion,
|
|
148
|
+
latest_version: latestVersion,
|
|
149
|
+
}).catch(() => {});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
} catch (e) {
|
|
153
|
+
// Non-fatal: network issues, npm unavailable, etc.
|
|
154
|
+
console.log('[Update] Check failed:', e.message);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
136
158
|
async function main() {
|
|
137
159
|
// Pre-flight: check Claude CLI is available
|
|
138
160
|
const { execFileSync } = require('child_process');
|
|
@@ -208,6 +230,13 @@ async function main() {
|
|
|
208
230
|
}
|
|
209
231
|
}
|
|
210
232
|
|
|
233
|
+
// Auto-update check: on startup and every 24h
|
|
234
|
+
checkForUpdates(config.agentUserID, pairedClientIDs);
|
|
235
|
+
const updateInterval = setInterval(() => {
|
|
236
|
+
checkForUpdates(config.agentUserID, pairedClientIDs);
|
|
237
|
+
}, 24 * 60 * 60 * 1000);
|
|
238
|
+
updateInterval.unref();
|
|
239
|
+
|
|
211
240
|
// Setup services
|
|
212
241
|
sessions = new SessionStore(path.join(CHATCC_DIR, 'sessions.json'), {
|
|
213
242
|
maxSessions: MAX_SESSIONS,
|
|
@@ -232,6 +261,11 @@ async function main() {
|
|
|
232
261
|
request_id: reqId,
|
|
233
262
|
path: filePath,
|
|
234
263
|
operation,
|
|
264
|
+
}, {
|
|
265
|
+
title: '权限请求',
|
|
266
|
+
desc: `${operation}: ${filePath.length > 40 ? '...' + filePath.slice(-37) : filePath}`,
|
|
267
|
+
ext: JSON.stringify({ push_type: 'tool_confirm' }),
|
|
268
|
+
ignoreBadge: false,
|
|
235
269
|
}).catch(() => {});
|
|
236
270
|
const timer = setTimeout(() => {
|
|
237
271
|
fileService._pendingPermissions.delete(reqId);
|
|
@@ -409,6 +443,26 @@ async function main() {
|
|
|
409
443
|
break;
|
|
410
444
|
}
|
|
411
445
|
|
|
446
|
+
case 'clear_request': {
|
|
447
|
+
const sid = data.session_id;
|
|
448
|
+
const sess = sessions.get(sid) || null;
|
|
449
|
+
if (!sess || sess.clientID !== from) {
|
|
450
|
+
imClient.sendCustomMessage(from, 'clear_response', {
|
|
451
|
+
request_id: data.request_id, success: false, error: '会话不存在或无权限',
|
|
452
|
+
}).catch(() => {});
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
// Clear Claude session so next message starts fresh
|
|
456
|
+
sess.claudeSessionId = null;
|
|
457
|
+
sess.lastActiveAt = Date.now();
|
|
458
|
+
sessions.set(sid, sess);
|
|
459
|
+
console.log(`[Session] Clear context for ${sid}, claudeSessionId reset`);
|
|
460
|
+
imClient.sendCustomMessage(from, 'clear_response', {
|
|
461
|
+
request_id: data.request_id, success: true,
|
|
462
|
+
}).catch(e => console.error('[Clear] Reply failed:', e.message));
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
|
|
412
466
|
case 'compact_request': {
|
|
413
467
|
const sid = data.session_id;
|
|
414
468
|
const sess = sessions.get(sid) || null;
|
|
@@ -478,6 +532,10 @@ async function main() {
|
|
|
478
532
|
|
|
479
533
|
default:
|
|
480
534
|
console.log('[Message] Unknown cc_type:', data.cc_type, 'v=', data.v || 0);
|
|
535
|
+
imClient.sendCustomMessage(from, 'unknown_type_error', {
|
|
536
|
+
original_type: data.cc_type,
|
|
537
|
+
message: `Unknown cc_type: ${data.cc_type}`,
|
|
538
|
+
}).catch(() => {});
|
|
481
539
|
}
|
|
482
540
|
});
|
|
483
541
|
|
package/src/server-info.js
CHANGED
|
@@ -2,6 +2,7 @@ const os = require('os');
|
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const { getVersion } = require('./version');
|
|
5
|
+
const { CURRENT_PROTOCOL_VERSION, MIN_PROTOCOL_VERSION } = require('./constants');
|
|
5
6
|
|
|
6
7
|
function collectServerMeta() {
|
|
7
8
|
const suggestedWorkspaces = [];
|
|
@@ -23,7 +24,8 @@ function collectServerMeta() {
|
|
|
23
24
|
cpuCount: os.cpus().length,
|
|
24
25
|
memoryGB: Math.round(os.totalmem() / 1024 / 1024 / 1024),
|
|
25
26
|
agentVersion: getVersion(),
|
|
26
|
-
protocol_version:
|
|
27
|
+
protocol_version: CURRENT_PROTOCOL_VERSION,
|
|
28
|
+
min_protocol_version: MIN_PROTOCOL_VERSION,
|
|
27
29
|
suggestedWorkspaces: suggestedWorkspaces,
|
|
28
30
|
};
|
|
29
31
|
}
|