@myskyline_ai/ccdebug 0.2.6 → 0.2.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/dist/cli.js CHANGED
@@ -76,13 +76,15 @@ ${exports.colors.yellow}选项:${exports.colors.reset}
76
76
  --serve, --log, -l 启动站点,查看claude code日志
77
77
  --run-with 将后续所有参数传递给 Claude 进程
78
78
  --claude-path 指定 Claude 二进制文件或cli.js的路径
79
+ --trace 启用HTTP请求跟踪(默认不跟踪)
79
80
  --version, -v 显示版本信息
80
81
  --help, -h 显示此帮助信息
81
82
 
82
83
  ${exports.colors.yellow}模式:${exports.colors.reset}
83
84
  ${exports.colors.green}交互式日志:${exports.colors.reset}
84
- ccdebug 启动带流量日志的 Claude
85
- ccdebug --run-with -p "请按要求工作" --verbose 使用特定命令运行 Claude
85
+ ccdebug 启动 Claude(不进行跟踪)
86
+ ccdebug --trace 启动 Claude 并跟踪 HTTP 请求
87
+ ccdebug --trace --run-with -p "请按要求工作" --verbose 使用特定命令运行 Claude 并跟踪请求
86
88
 
87
89
  ${exports.colors.green}Web 服务器:${exports.colors.reset}
88
90
  ccdebug --serve 启动站点,查看claude code日志
@@ -97,7 +99,7 @@ ${exports.colors.yellow}模式:${exports.colors.reset}
97
99
 
98
100
  ${exports.colors.yellow}输出:${exports.colors.reset}
99
101
  cc标准日志: ${exports.colors.green}.claude-trace/cclog/*.jsonl${exports.colors.reset}
100
- cc跟踪日志: ${exports.colors.green}.claude-trace/tracelog/*.jsonl${exports.colors.reset}
102
+ cc跟踪日志: ${exports.colors.green}.claude-trace/tracelog/*.jsonl${exports.colors.reset} ${exports.colors.yellow}(仅在--trace参数下创建)${exports.colors.reset}
101
103
 
102
104
  更多信息请访问: https://github.com/myskyline_ai/ccdebug
103
105
  `);
@@ -319,8 +321,8 @@ function getLoaderPath() {
319
321
  return loaderPath;
320
322
  }
321
323
  // Scenario 1: No args -> launch node with interceptor and absolute path to claude
322
- async function runClaudeWithInterception(claudeArgs = [], includeAllRequests = false, openInBrowser = false, customClaudePath, logBaseName) {
323
- log("启动 Claude 并记录流量日志", "blue");
324
+ async function runClaudeWithInterception(claudeArgs = [], includeAllRequests = false, openInBrowser = false, customClaudePath, logBaseName, enableTrace = false) {
325
+ log("启动 Claude", "blue");
324
326
  if (claudeArgs.length > 0) {
325
327
  log(`Claude 参数: ${claudeArgs.join(" ")}`, "blue");
326
328
  }
@@ -329,7 +331,12 @@ async function runClaudeWithInterception(claudeArgs = [], includeAllRequests = f
329
331
  let child;
330
332
  if (isNodeScript(claudePath)) {
331
333
  // Node.js 脚本方式:使用原有的 --require 方式
332
- log("使用 Node.js 拦截方法", "blue");
334
+ if (enableTrace) {
335
+ log("使用 Node.js 拦截方法(已启用跟踪)", "blue");
336
+ }
337
+ else {
338
+ log("使用 Node.js 启动 Claude(未启用跟踪)", "blue");
339
+ }
333
340
  const loaderPath = getLoaderPath();
334
341
  const spawnArgs = ["--require", loaderPath, claudePath, ...claudeArgs];
335
342
  child = (0, child_process_1.spawn)("node", spawnArgs, {
@@ -338,6 +345,7 @@ async function runClaudeWithInterception(claudeArgs = [], includeAllRequests = f
338
345
  NODE_OPTIONS: "--no-deprecation",
339
346
  CLAUDE_TRACE_INCLUDE_ALL_REQUESTS: includeAllRequests ? "true" : "false",
340
347
  CLAUDE_TRACE_OPEN_BROWSER: openInBrowser ? "true" : "false",
348
+ CLAUDE_TRACE_ENABLED: enableTrace ? "true" : "false",
341
349
  ...(logBaseName ? { CLAUDE_TRACE_LOG_NAME: logBaseName } : {}),
342
350
  },
343
351
  stdio: "inherit",
@@ -350,8 +358,7 @@ async function runClaudeWithInterception(claudeArgs = [], includeAllRequests = f
350
358
  log("⚠️ 警告: 检测到原生二进制文件", "yellow");
351
359
  log("CCDebug 无法拦截来自 Claude Code 原生二进制版本的 API 请求,调试功能将无法工作", "yellow");
352
360
  log("要使用 CCDebug 的完整调试功能,请改用 NPM 版本的 Claude Code。", "yellow");
353
- console.log("");
354
- log("正在启动 Claude(不进行 API 拦截)...", "blue");
361
+ log("启动 Claude(不进行 API 拦截)...", "blue");
355
362
  console.log("");
356
363
  // 给用户一点时间阅读提示信息
357
364
  await new Promise(resolve => setTimeout(resolve, 500));
@@ -366,7 +373,12 @@ async function runClaudeWithInterception(claudeArgs = [], includeAllRequests = f
366
373
  }
367
374
  // Node.js 模式显示成功消息
368
375
  if (isNodeScript(claudePath)) {
369
- log("流量日志记录器启动成功", "green");
376
+ if (enableTrace) {
377
+ log("流量日志记录器启动成功", "green");
378
+ }
379
+ else {
380
+ log("Claude 启动成功(未启用跟踪)", "green");
381
+ }
370
382
  console.log("");
371
383
  }
372
384
  // Handle child process events
@@ -588,6 +600,8 @@ async function main() {
588
600
  showHelp();
589
601
  process.exit(0);
590
602
  }
603
+ // Check for trace flag
604
+ const enableTrace = claudeTraceArgs.includes("--trace");
591
605
  // Check for include all requests flag
592
606
  const includeAllRequests = claudeTraceArgs.includes("--include-all-requests");
593
607
  // Check for no-open flag (inverted logic - open by default)
@@ -665,7 +679,7 @@ async function main() {
665
679
  return;
666
680
  }
667
681
  // Scenario 1: No args (or claude with args) -> launch claude with interception
668
- await runClaudeWithInterception(claudeArgs, includeAllRequests, openInBrowser, customClaudePath, logBaseName);
682
+ await runClaudeWithInterception(claudeArgs, includeAllRequests, openInBrowser, customClaudePath, logBaseName, enableTrace);
669
683
  }
670
684
  main().catch((error) => {
671
685
  const err = error;
@@ -1 +1 @@
1
- {"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../src/interceptor.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAC/C;AAED,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,MAAM,GAAE,iBAAsB;IA6C1C,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,sBAAsB;YAgChB,aAAa;YAKb,gBAAgB;YAsBhB,iBAAiB;IAwBxB,aAAa,IAAI,IAAI;IAKrB,eAAe,IAAI,IAAI;IA0FvB,kBAAkB,IAAI,IAAI;IA8CjC,OAAO,CAAC,oBAAoB;IAuE5B,OAAO,CAAC,mBAAmB;YAab,2BAA2B;YAiB3B,cAAc;YASd,YAAY;IAcnB,OAAO,IAAI,IAAI;IA4CtB,OAAO,CAAC,mBAAmB;IA0C3B,OAAO,CAAC,aAAa;IA4DrB,OAAO,CAAC,6BAA6B;IAkB9B,QAAQ;;;;;;CAQf;AAQD,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,mBAAmB,CA8BrF;AAED,wBAAgB,SAAS,IAAI,mBAAmB,GAAG,IAAI,CAEtD"}
1
+ {"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../src/interceptor.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;CAC/C;AAED,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAA+B;IACtD,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,MAAM,GAAE,iBAAsB;IAmE1C,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,sBAAsB;YAgChB,aAAa;YAKb,gBAAgB;YAsBhB,iBAAiB;IAwBxB,aAAa,IAAI,IAAI;IAKrB,eAAe,IAAI,IAAI;IA+FvB,kBAAkB,IAAI,IAAI;IAmDjC,OAAO,CAAC,oBAAoB;IAuE5B,OAAO,CAAC,mBAAmB;YAab,2BAA2B;YAiB3B,cAAc;YAcd,YAAY;IAmBnB,OAAO,IAAI,IAAI;IAiDtB,OAAO,CAAC,mBAAmB;IA+C3B,OAAO,CAAC,aAAa;IAiErB,OAAO,CAAC,6BAA6B;IAuB9B,QAAQ;;;;;;CAQf;AAQD,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,mBAAmB,CA8BrF;AAED,wBAAgB,SAAS,IAAI,mBAAmB,GAAG,IAAI,CAEtD"}
@@ -14,6 +14,26 @@ class ClaudeTrafficLogger {
14
14
  constructor(config = {}) {
15
15
  this.pendingRequests = new Map();
16
16
  this.pairs = [];
17
+ // 检查是否启用了跟踪
18
+ const traceEnabled = process.env.CLAUDE_TRACE_ENABLED === "true";
19
+ if (!traceEnabled) {
20
+ // 如果未启用跟踪,则不初始化日志记录器
21
+ this.config = {
22
+ logDirectory: ".claude-trace",
23
+ enableRealTimeHTML: false,
24
+ logLevel: "info",
25
+ ...config,
26
+ };
27
+ // 不创建目录和文件
28
+ this.traceHomeDir = "";
29
+ this.traceLogDir = "";
30
+ this.traceLogFile = "";
31
+ this.ccLogDir = "";
32
+ this.ccLogFile = "";
33
+ this.htmlFile = "";
34
+ this.htmlGenerator = new html_generator_1.HTMLGenerator();
35
+ return;
36
+ }
17
37
  this.config = {
18
38
  logDirectory: ".claude-trace",
19
39
  enableRealTimeHTML: false,
@@ -154,6 +174,10 @@ class ClaudeTrafficLogger {
154
174
  this.instrumentNodeHTTP();
155
175
  }
156
176
  instrumentFetch() {
177
+ // 检查是否启用了跟踪
178
+ if (!this.traceLogFile) {
179
+ return;
180
+ }
157
181
  if (!global.fetch) {
158
182
  // Silent - fetch not available
159
183
  return;
@@ -226,6 +250,10 @@ class ClaudeTrafficLogger {
226
250
  // Silent initialization
227
251
  }
228
252
  instrumentNodeHTTP() {
253
+ // 检查是否启用了跟踪
254
+ if (!this.traceLogFile) {
255
+ return;
256
+ }
229
257
  try {
230
258
  const http = require("http");
231
259
  const https = require("https");
@@ -352,6 +380,10 @@ class ClaudeTrafficLogger {
352
380
  }
353
381
  }
354
382
  async writePairToLog(pair) {
383
+ // 检查是否启用了跟踪
384
+ if (!this.traceLogFile) {
385
+ return;
386
+ }
355
387
  try {
356
388
  const jsonLine = JSON.stringify(pair) + "\n";
357
389
  fs_1.default.appendFileSync(this.traceLogFile, jsonLine);
@@ -361,6 +393,10 @@ class ClaudeTrafficLogger {
361
393
  }
362
394
  }
363
395
  async generateHTML() {
396
+ // 检查是否启用了跟踪
397
+ if (!this.htmlFile) {
398
+ return;
399
+ }
364
400
  try {
365
401
  const includeAllRequests = process.env.CLAUDE_TRACE_INCLUDE_ALL_REQUESTS === "true";
366
402
  await this.htmlGenerator.generateHTML(this.pairs, this.htmlFile, {
@@ -375,6 +411,10 @@ class ClaudeTrafficLogger {
375
411
  }
376
412
  }
377
413
  cleanup() {
414
+ // 检查是否启用了跟踪
415
+ if (!this.traceLogFile) {
416
+ return;
417
+ }
378
418
  console.log("Cleaning up orphaned requests...");
379
419
  for (const [, requestData] of this.pendingRequests.entries()) {
380
420
  const orphanedPair = {
@@ -413,6 +453,10 @@ class ClaudeTrafficLogger {
413
453
  // }
414
454
  }
415
455
  getSessionIdFromLog() {
456
+ // 检查是否启用了跟踪
457
+ if (!this.traceLogFile) {
458
+ return '';
459
+ }
416
460
  // Check if log file exists
417
461
  if (!fs_1.default.existsSync(this.traceLogFile)) {
418
462
  console.log("获取sessionId错误:Log file does not exist");
@@ -447,6 +491,10 @@ class ClaudeTrafficLogger {
447
491
  return sessionMatch[1];
448
492
  }
449
493
  copyCClogFile(sessionId) {
494
+ // 检查是否启用了跟踪
495
+ if (!this.ccLogDir) {
496
+ return;
497
+ }
450
498
  //将当前会话对应的cc日志文件,拷贝到.claude-trace/cclog目录
451
499
  try {
452
500
  // 创建LogFileManager实例
@@ -497,6 +545,10 @@ class ClaudeTrafficLogger {
497
545
  }
498
546
  }
499
547
  renameTraceLogFileBySessionId(sessionId) {
548
+ // 检查是否启用了跟踪
549
+ if (!this.traceLogFile) {
550
+ return;
551
+ }
500
552
  try {
501
553
  const logDir = path_1.default.dirname(this.traceLogFile);
502
554
  const newLogFile = path_1.default.join(logDir, `${sessionId}.jsonl`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myskyline_ai/ccdebug",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "跟踪记录CC请求,可针对特定请求反复调试验证,以更直观的时间线形式展示CC日志",
5
5
  "publishConfig": {
6
6
  "access": "public"