@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 +24 -10
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/interceptor.js +52 -0
- package/package.json +1 -1
- package/web/dist/assets/index-3HemujBj.js +48 -0
- package/web/dist/assets/index-3HemujBj.js.map +1 -0
- package/web/dist/assets/index-DCo5IV1V.css +1 -0
- package/web/dist/index.html +2 -2
- package/web/server/log-file-manager.js +8 -8
- package/web/server/log-file-manager.js.map +1 -1
- package/web/dist/assets/index-0ZGxPLiy.js +0 -48
- package/web/dist/assets/index-0ZGxPLiy.js.map +0 -1
- package/web/dist/assets/index-BoIBQhss.css +0 -1
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
|
|
85
|
-
ccdebug --
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
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"}
|
package/dist/interceptor.js
CHANGED
|
@@ -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`);
|