chatcc-agent 0.3.7 → 0.3.8

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatcc-agent",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "CCLink Agent - bridges Claude Code CLI with instant messaging",
5
5
  "bin": {
6
6
  "chatcc": "src/cli.js"
@@ -101,7 +101,7 @@ class ClaudeBridge {
101
101
  proc.stdin.write(JSON.stringify(msg) + '\n');
102
102
  }
103
103
  } catch (e) {
104
- console.error('[Bridge] stdin write failed:', e.message);
104
+ console.error('[Bridge] stdin write failed:', e.message, e.stack);
105
105
  }
106
106
  }
107
107
 
@@ -267,7 +267,7 @@ class ClaudeBridge {
267
267
  try {
268
268
  await this._queue.enqueue(sessionID, taskFn);
269
269
  } catch (err) {
270
- console.error('[Bridge] Queue error:', err.message);
270
+ console.error('[Bridge] Queue error:', err.message, err.stack);
271
271
  await this.imClient.sendCustomMessage(replyTo, 'stream_end', {
272
272
  msg_id: msgID,
273
273
  exit_code: 1,
@@ -386,7 +386,7 @@ class ClaudeBridge {
386
386
 
387
387
  proc.on('error', async (err) => {
388
388
  clearInterval(timeoutCheck);
389
- console.error('[Bridge] Compact spawn error:', err.message);
389
+ console.error('[Bridge] Compact spawn error:', err.message, err.stack);
390
390
  await sendResponse({ success: false, error: `启动失败: ${err.message}` });
391
391
  if (!settled) { settled = true; reject(err); }
392
392
  });
@@ -478,7 +478,7 @@ class ClaudeBridge {
478
478
  source: { type: 'base64', media_type: mediaType, data: imgData.toString('base64') },
479
479
  });
480
480
  } catch (e) {
481
- console.error('[Bridge] Failed to read image for stdin:', imgPath, e.message);
481
+ console.error('[Bridge] Failed to read image for stdin:', imgPath, e.message, e.stack);
482
482
  }
483
483
  }
484
484
  this._writeToStdin(proc, {
@@ -510,7 +510,7 @@ class ClaudeBridge {
510
510
  let timeoutCheck = null;
511
511
 
512
512
  proc.on('error', async (err) => {
513
- console.error('[Bridge] Claude spawn error:', err.message);
513
+ console.error('[Bridge] Claude spawn error:', err.message, err.stack);
514
514
  clearInterval(timeoutCheck);
515
515
  this._activeProcesses.delete(msgID);
516
516
  this._toolUseBlockQueue.delete(msgID);
@@ -564,7 +564,7 @@ class ClaudeBridge {
564
564
  try {
565
565
  await sendStreamEnd({ exit_code: code });
566
566
  } catch (e) {
567
- console.error('[Bridge] Failed to send stream_end:', e.message);
567
+ console.error('[Bridge] Failed to send stream_end:', e.message, e.stack);
568
568
  }
569
569
  console.log('[Bridge] Claude Code exited:', code);
570
570
 
@@ -636,7 +636,7 @@ class ClaudeBridge {
636
636
  desc: '需要您的选择',
637
637
  ext: JSON.stringify({ session_id: sessionID, push_type: 'agent_reply' }),
638
638
  ignoreBadge: false,
639
- }).catch(e => console.error('[Bridge] user_question:', e.message));
639
+ }).catch(e => console.error('[Bridge] user_question:', e.message, e.stack));
640
640
  } else {
641
641
  this._handleToolUseBlock(block, replyTo, msgID, streamBuffer, sessionID, cwd, workspaceRestricted, permissions, useControl, sendStreamEnd);
642
642
  }
@@ -697,7 +697,7 @@ class ClaudeBridge {
697
697
  const payload = buildPayload();
698
698
  payload.state = 'executing';
699
699
  this.imClient.sendCustomMessage(replyTo, 'agent_tool', payload)
700
- .catch(e => console.error('[Bridge] Failed to send agent_tool:', e.message));
700
+ .catch(e => console.error('[Bridge] Failed to send agent_tool:', e.message, e.stack));
701
701
  } else {
702
702
  const payload = buildPayload();
703
703
  if (sensitive) {
@@ -708,7 +708,7 @@ class ClaudeBridge {
708
708
  payload.workspace_violation = true;
709
709
  }
710
710
  this.imClient.sendCustomMessage(replyTo, 'agent_tool', payload)
711
- .catch(e => console.error('[Bridge] Failed to send agent_tool:', e.message));
711
+ .catch(e => console.error('[Bridge] Failed to send agent_tool:', e.message, e.stack));
712
712
 
713
713
  if (sensitive || workspaceViolation) {
714
714
  this._pendingToolApprovals.set(block.id, {
@@ -791,7 +791,7 @@ class ClaudeBridge {
791
791
  }
792
792
 
793
793
  this.imClient.sendCustomMessage(replyTo, 'agent_tool', payload)
794
- .catch(e => console.error('[Bridge] Failed to send tool_result:', e.message));
794
+ .catch(e => console.error('[Bridge] Failed to send tool_result:', e.message, e.stack));
795
795
  }
796
796
  }
797
797
  }
@@ -12,7 +12,7 @@ async function handleClientList(imClient, from) {
12
12
  await imClient.sendCustomMessage(from, 'client_list_response', {
13
13
  status: 'ok',
14
14
  clients: clients.map(c => ({ client_id: c.client_id, role: c.role, paired_at: c.paired_at })),
15
- }).catch((e) => console.error('[ClientList] Reply failed:', e.message));
15
+ }).catch((e) => console.error('[ClientList] Reply failed:', e.message, e.stack));
16
16
  }
17
17
 
18
18
  async function handleClientRemove(imClient, from, data, pairedClientIDs) {
@@ -42,7 +42,7 @@ async function handleClientRemove(imClient, from, data, pairedClientIDs) {
42
42
  pairedClientIDs.delete(targetID);
43
43
  await imClient.sendCustomMessage(from, 'client_remove_response', {
44
44
  status: 'ok', client_id: targetID,
45
- }).catch((e) => console.error('[ClientRemove] Reply failed:', e.message));
45
+ }).catch((e) => console.error('[ClientRemove] Reply failed:', e.message, e.stack));
46
46
  console.log(`[Client] Removed ${targetID}, remaining: ${updated.length}`);
47
47
  }
48
48
 
@@ -221,7 +221,7 @@ class FileService {
221
221
  });
222
222
  } catch (sendErr) {
223
223
  // Payload too large — retry with minimal info
224
- console.error('[FileService] Tree reply failed (likely too large), sending names only:', sendErr.message);
224
+ console.error('[FileService] Tree reply failed (likely too large), sending names only:', sendErr.message, sendErr.stack);
225
225
  const lightTree = { name: tree.name, type: 'directory', children: tree.children.map(c => ({ name: c.name, type: c.type })) };
226
226
  await this._reply(from, 'file_tree_response', {
227
227
  request_id,
@@ -236,7 +236,7 @@ class FileService {
236
236
  error: e.message,
237
237
  });
238
238
  } catch (replyErr) {
239
- console.error('[FileService] Error reply also failed:', replyErr.message);
239
+ console.error('[FileService] Error reply also failed:', replyErr.message, replyErr.stack);
240
240
  }
241
241
  }
242
242
  }
package/src/im-client.js CHANGED
@@ -62,7 +62,7 @@ class IMClient {
62
62
  this._reconnect();
63
63
  }
64
64
  }).catch(e => {
65
- console.log('[IM] UserSig refresh failed:', e.message);
65
+ console.log('[IM] UserSig refresh failed:', e.message, e.stack);
66
66
  });
67
67
  return;
68
68
  }
@@ -116,7 +116,7 @@ class IMClient {
116
116
  await this.login();
117
117
  console.log('[IM] Reconnected successfully');
118
118
  } catch (e) {
119
- console.log('[IM] Reconnect failed:', e.message);
119
+ console.log('[IM] Reconnect failed:', e.message, e.stack);
120
120
  this._reconnectAttempts++;
121
121
  if (this._reconnectAttempts > this._maxReconnectAttempts) {
122
122
  console.log('[IM] Max reconnect attempts reached. Backing off...');
package/src/index.js CHANGED
@@ -151,7 +151,7 @@ async function checkForUpdates(agentID, pairedClientIDs) {
151
151
  }
152
152
  } catch (e) {
153
153
  // Non-fatal: network issues, npm unavailable, etc.
154
- console.log('[Update] Check failed:', e.message);
154
+ console.log('[Update] Check failed:', e.message, e.stack);
155
155
  }
156
156
  }
157
157
 
@@ -194,7 +194,7 @@ async function main() {
194
194
  console.log('[UserSig] Refreshed successfully');
195
195
  return data.agent_im_user_sig;
196
196
  } catch (e) {
197
- console.error('[UserSig] Refresh failed:', e.message);
197
+ console.error('[UserSig] Refresh failed:', e.message, e.stack);
198
198
  }
199
199
  return null;
200
200
  },
@@ -225,7 +225,7 @@ async function main() {
225
225
  imClient.sendCustomMessage(clientID, 'server_meta', meta).then(() => {
226
226
  console.log('[Online] Notified paired client:', clientID);
227
227
  }).catch((e) => {
228
- console.error('[Online] Failed to notify client:', e.message);
228
+ console.error('[Online] Failed to notify client:', e.message, e.stack);
229
229
  });
230
230
  }
231
231
  }
@@ -335,17 +335,17 @@ async function main() {
335
335
  imClient.sendCustomMessage(from, 'session_update', {
336
336
  session_id: sid,
337
337
  name: title,
338
- }).catch(e => console.error('[Session] Failed to send session_update:', e.message));
338
+ }).catch(e => console.error('[Session] Failed to send session_update:', e.message, e.stack));
339
339
  };
340
340
 
341
341
  const bridgeOpts = { cwd, claudeSessionId: claudeSid, onClaudeSessionId, onResumeFailed, onSessionTitle, workspaceRestricted: isRestricted, permissions: sessionPermissions };
342
342
  if (imageUrls.length > 0) {
343
343
  Promise.all(imageUrls.map(u => downloadImage(u, tempFiles).catch(e => {
344
- console.error('[Image] Download failed:', e.message);
344
+ console.error('[Image] Download failed:', e.message, e.stack);
345
345
  return null;
346
346
  }))).then((paths) => {
347
347
  bridge.handleUserText(from, data.content, sid, { ...bridgeOpts, imagePaths: paths.filter(p => p !== null) });
348
- }).catch(e => console.error('[Image] Processing failed:', e.message));
348
+ }).catch(e => console.error('[Image] Processing failed:', e.message, e.stack));
349
349
  } else {
350
350
  bridge.handleUserText(from, data.content, sid, { ...bridgeOpts, imagePaths: [] });
351
351
  }
@@ -459,7 +459,7 @@ async function main() {
459
459
  console.log(`[Session] Clear context for ${sid}, claudeSessionId reset`);
460
460
  imClient.sendCustomMessage(from, 'clear_response', {
461
461
  request_id: data.request_id, success: true,
462
- }).catch(e => console.error('[Clear] Reply failed:', e.message));
462
+ }).catch(e => console.error('[Clear] Reply failed:', e.message, e.stack));
463
463
  break;
464
464
  }
465
465
 
@@ -487,11 +487,12 @@ async function main() {
487
487
  agent_id: config.agentUserID,
488
488
  timestamp: Date.now(),
489
489
  request_id: data.request_id,
490
- }).catch(e => console.error('[Ping] Reply failed:', e.message));
490
+ }).catch(e => console.error('[Ping] Reply failed:', e.message, e.stack));
491
491
  break;
492
492
  }
493
493
 
494
494
  case 'upgrade_agent': {
495
+ const { spawn } = require('child_process');
495
496
  const oldVersion = getVersion();
496
497
  console.log(`[Upgrade] Request from ${from}, current v${oldVersion}`);
497
498
  (async () => {
@@ -518,7 +519,7 @@ async function main() {
518
519
  });
519
520
  restarter.unref();
520
521
  } catch (e) {
521
- console.error('[Upgrade] Failed:', e.message);
522
+ console.error('[Upgrade] Failed:', e.message, e.stack);
522
523
  await imClient.sendCustomMessage(from, 'upgrade_response', {
523
524
  request_id: data.request_id,
524
525
  success: false,
@@ -558,7 +559,7 @@ if (process.argv.includes('--setup')) {
558
559
  console.log('Setup complete.');
559
560
  process.exit(0);
560
561
  }).catch((err) => {
561
- console.error('Setup failed:', err.message);
562
+ console.error('Setup failed:', err.message, err.stack);
562
563
  process.exit(1);
563
564
  });
564
565
  } else {
@@ -107,7 +107,7 @@ async function handleClaudeSessionList(imClient, from, data) {
107
107
  sessions: sessionList,
108
108
  });
109
109
  } catch (e) {
110
- console.error('[ClaudeSessionList] Error:', e.message);
110
+ console.error('[ClaudeSessionList] Error:', e.message, e.stack);
111
111
  await imClient.sendCustomMessage(from, 'claude_session_list_response', {
112
112
  request_id: requestID,
113
113
  error: e.message,
@@ -128,7 +128,7 @@ async function handlePermissionGrant(imClient, from, data, fileService) {
128
128
  await imClient.sendCustomMessage(from, 'permission_grant_ack', {
129
129
  status: 'ok',
130
130
  path: data.path,
131
- }).catch((e) => console.error('[Grant] Reply failed:', e.message));
131
+ }).catch((e) => console.error('[Grant] Reply failed:', e.message, e.stack));
132
132
  }
133
133
  }
134
134
 
@@ -113,7 +113,7 @@ class SessionStore {
113
113
  fs.closeSync(fd);
114
114
  fs.renameSync(tmp, this.filePath);
115
115
  } catch (e) {
116
- console.warn('[SessionStore] Write failed:', e.message);
116
+ console.warn('[SessionStore] Write failed:', e.message, e.stack);
117
117
  }
118
118
  }
119
119
  }
@@ -34,10 +34,10 @@ class StreamBuffer {
34
34
  try { await this.sendFn(data); }
35
35
  catch (e) {
36
36
  if (this.buffer.length + data.length > MAX_BUFFER_SIZE) {
37
- console.error('[StreamBuffer] Send failed and buffer full, discarding:', e.message);
37
+ console.error('[StreamBuffer] Send failed and buffer full, discarding:', e.message, e.stack);
38
38
  } else {
39
39
  this.buffer = data + this.buffer;
40
- console.error('[StreamBuffer] Send failed, will retry:', e.message);
40
+ console.error('[StreamBuffer] Send failed, will retry:', e.message, e.stack);
41
41
  }
42
42
  }
43
43
  }