diff --git a/apps/claude-trace/README.md b/apps/claude-trace/README.md index c07ac93..9f8e84c 100644 --- a/apps/claude-trace/README.md +++ b/apps/claude-trace/README.md @@ -20,6 +20,12 @@ claude-trace --include-all-requests # Run Claude with specific arguments claude-trace --run-with chat --model sonnet-3.5 +# Use custom output directory (default: .claude-trace) +claude-trace --output-dir /path/to/logs + +# Combine custom output directory with custom log name +claude-trace --output-dir ~/my-traces --log my-session + # Show help claude-trace --help @@ -36,7 +42,7 @@ claude-trace --generate-html logs.jsonl --include-all-requests claude-trace --index ``` -Logs are saved to `.claude-trace/log-YYYY-MM-DD-HH-MM-SS.{jsonl,html}` in your current directory. The HTML file is self-contained and opens in any browser without needing a server. +Logs are saved to `.claude-trace/log-YYYY-MM-DD-HH-MM-SS.{jsonl,html}` in your current directory (or the directory specified by `--output-dir`). The HTML file is self-contained and opens in any browser without needing a server. ## Request Filtering diff --git a/apps/claude-trace/src/cli.ts b/apps/claude-trace/src/cli.ts index ad13e33..59f8069 100644 --- a/apps/claude-trace/src/cli.ts +++ b/apps/claude-trace/src/cli.ts @@ -36,6 +36,7 @@ ${colors.yellow}OPTIONS:${colors.reset} --include-all-requests Include all requests made through fetch, otherwise only requests to v1/messages with more than 2 messages in the context --no-open Don't open generated HTML file in browser --log Specify custom log file base name (without extension) + --output-dir Specify custom output directory (default: .claude-trace) --claude-path Specify custom path to Claude binary --help, -h Show this help message @@ -92,9 +93,16 @@ ${colors.yellow}EXAMPLES:${colors.reset} # Use custom Claude binary path claude-trace --claude-path /usr/local/bin/claude + # Use custom output directory + claude-trace --output-dir /path/to/logs + + # Combine custom output directory with custom log name + claude-trace --output-dir ~/my-traces --log my-session + ${colors.yellow}OUTPUT:${colors.reset} Logs are saved to: ${colors.green}.claude-trace/log-YYYY-MM-DD-HH-MM-SS.{jsonl,html}${colors.reset} With --log NAME: ${colors.green}.claude-trace/NAME.{jsonl,html}${colors.reset} + With --output-dir: ${colors.green}/log-YYYY-MM-DD-HH-MM-SS.{jsonl,html}${colors.reset} ${colors.yellow}MIGRATION:${colors.reset} This tool replaces Python-based claude-logger and claude-token.py scripts @@ -234,6 +242,7 @@ async function runClaudeWithInterception( openInBrowser: boolean = false, customClaudePath?: string, logBaseName?: string, + outputDir?: string, ): Promise { log("Claude Trace", "blue"); log("Starting Claude with traffic logging", "yellow"); @@ -258,6 +267,7 @@ async function runClaudeWithInterception( CLAUDE_TRACE_INCLUDE_ALL_REQUESTS: includeAllRequests ? "true" : "false", CLAUDE_TRACE_OPEN_BROWSER: openInBrowser ? "true" : "false", ...(logBaseName ? { CLAUDE_TRACE_LOG_NAME: logBaseName } : {}), + ...(outputDir ? { CLAUDE_TRACE_OUTPUT_DIR: outputDir } : {}), }, stdio: "inherit", cwd: process.cwd(), @@ -487,6 +497,13 @@ async function main(): Promise { logBaseName = claudeTraceArgs[logIndex + 1]; } + // Check for custom output directory + let outputDir: string | undefined; + const outputDirIndex = claudeTraceArgs.indexOf("--output-dir"); + if (outputDirIndex !== -1 && claudeTraceArgs[outputDirIndex + 1]) { + outputDir = claudeTraceArgs[outputDirIndex + 1]; + } + // Scenario 2: --extract-token if (claudeTraceArgs.includes("--extract-token")) { await extractToken(customClaudePath); @@ -525,7 +542,7 @@ async function main(): Promise { } // Scenario 1: No args (or claude with args) -> launch claude with interception - await runClaudeWithInterception(claudeArgs, includeAllRequests, openInBrowser, customClaudePath, logBaseName); + await runClaudeWithInterception(claudeArgs, includeAllRequests, openInBrowser, customClaudePath, logBaseName, outputDir); } main().catch((error) => { diff --git a/apps/claude-trace/src/interceptor-loader.js b/apps/claude-trace/src/interceptor-loader.js index 7e1f898..019609a 100644 --- a/apps/claude-trace/src/interceptor-loader.js +++ b/apps/claude-trace/src/interceptor-loader.js @@ -7,15 +7,21 @@ try { const jsPath = path.join(__dirname, "interceptor.js"); const tsPath = path.join(__dirname, "interceptor.ts"); + // Build config from environment variables + const config = {}; + if (process.env.CLAUDE_TRACE_OUTPUT_DIR) { + config.logDirectory = process.env.CLAUDE_TRACE_OUTPUT_DIR; + } + if (fs.existsSync(jsPath)) { // Use compiled JavaScript const { initializeInterceptor } = require("./interceptor.js"); - initializeInterceptor(); + initializeInterceptor(config); } else if (fs.existsSync(tsPath)) { // Use TypeScript via tsx require("tsx/cjs/api").register(); const { initializeInterceptor } = require("./interceptor.ts"); - initializeInterceptor(); + initializeInterceptor(config); } else { console.error("Could not find interceptor file"); process.exit(1);