Skip to content

Conversation

@IovetsNikolay
Copy link
Contributor

@IovetsNikolay IovetsNikolay commented Feb 10, 2026

User description

Rewrote the debug skill to automatically analyze log timeline, locate/export Langfuse traces, and correlate both sources. Added langfuse-export.ts script and npm script shortcut.


CodeAnt-AI Description

Improve Explorbot debug workflow with on-demand Langfuse trace export and clearer log correlation

What Changed

  • Adds a command-line script to fetch and save Langfuse traces and their observations for a specified time range, producing a JSON export usable for session analysis
  • Updates the Explorbot debug guide to describe how to determine the session time range from logs, when to run the Langfuse export, and how to correlate Langfuse traces with browser logs; includes a log-only fallback if Langfuse data is unavailable
  • Exposes a new npm script shortcut to run the Langfuse export easily from the project

Impact

✅ Easier Langfuse exports for specific sessions
✅ Shorter debug sessions by correlating AI traces with browser logs
✅ Clearer root-cause correlation between AI decisions and browser behavior

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Rewrote the debug skill to automatically analyze log timeline,
locate/export Langfuse traces, and correlate both sources.
Added langfuse-export.ts script and npm script shortcut.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codeant-ai
Copy link

codeant-ai bot commented Feb 10, 2026

CodeAnt AI is reviewing your PR.

@codeant-ai codeant-ai bot added the size:L This PR changes 100-499 lines, ignoring generated files label Feb 10, 2026
@codeant-ai
Copy link

codeant-ai bot commented Feb 10, 2026

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Potential runtime error
    The fallback branch in parseTimeRange uses new Date(range).toISOString() without validating the parsed date. If range is not a valid date string this will produce an "Invalid Date" and throw when calling toISOString(). Consider validating the date and failing fast or providing a safe fallback.

  • Partial results / pagination
    fetchTraces and fetchObservations request a single page (limit: 50 / 100) and return data.data. If there are more results than the limit, the script will miss traces/observations. Consider iterating pages or using cursor-based pagination if API supports it.

  • Missing output directory handling
    The script writes to a path like output/langfuse-export-...json but doesn't ensure the directory exists. writeFileSync will fail if the parent directory is missing. Create directories with recursive mkdir before writing.

return { from: from.toISOString(), to: to.toISOString() };
}

return { from: new Date(range).toISOString(), to: to.toISOString() };
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: When a custom time range string is passed that is neither a relative spec (like "1h") nor "today", the code blindly constructs a Date from it and immediately calls toISOString, which will throw a RangeError at runtime if the input is invalid and produces an "Invalid Date". Adding an explicit validity check avoids an unhandled exception and allows you to fail fast with a clear error message. [logic error]

Severity Level: Major ⚠️
- ❌ Langfuse export script crashes on invalid custom date input.
- ⚠️ Debugging workflow interrupted when operator mistypes time range.
Suggested change
return { from: new Date(range).toISOString(), to: to.toISOString() };
const parsed = new Date(range);
if (Number.isNaN(parsed.getTime())) {
throw new Error(`Invalid time range: ${range}`);
}
return { from: parsed.toISOString(), to: to.toISOString() };
Steps of Reproduction ✅
1. From the repo root, run the CLI script with an invalid custom range string, e.g.:

   `bun .claude/skills/explorbot-debug/langfuse-export.ts not-a-date`.

   This executes `.claude/skills/explorbot-debug/langfuse-export.ts`.

2. The script reads `range` from `process.argv[2]` at

   `.claude/skills/explorbot-debug/langfuse-export.ts:68-69`

   (`const range = process.argv[2] || '1h';`), so `range === 'not-a-date'`.

3. `parseTimeRange(range)` is called at

   `.claude/skills/explorbot-debug/langfuse-export.ts:72`, entering

   `parseTimeRange()` defined at lines 29-47.

   The regex match at lines 33-37 fails, and the `if (range === 'today')` branch

   at lines 41-44 is also skipped.

4. Execution reaches the fallback return at line 46:

   `return { from: new Date(range).toISOString(), to: to.toISOString() };`.

   `new Date('not-a-date')` produces an `Invalid Date`; calling `.toISOString()`

   on this throws `RangeError: Invalid time value`, terminating the script before

   any Langfuse data is fetched or written.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** .claude/skills/explorbot-debug/langfuse-export.ts
**Line:** 46:46
**Comment:**
	*Logic Error: When a custom time range string is passed that is neither a relative spec (like "1h") nor "today", the code blindly constructs a Date from it and immediately calls toISOString, which will throw a RangeError at runtime if the input is invalid and produces an "Invalid Date". Adding an explicit validity check avoids an unhandled exception and allows you to fail fast with a clear error message.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

}

const range = process.argv[2] || '1h';
const outPath = process.argv[3] || `output/langfuse-export-${Date.now()}.json`;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The default output path points to "output/..." but the script never creates the "output" directory, so on a fresh checkout running the command with no explicit path will throw an ENOENT error when writeFileSync tries to write into a non-existent directory; using a default filename in the current directory avoids this runtime failure while still allowing callers to pass a custom path if they want. [possible bug]

Severity Level: Major ⚠️
- ❌ Default CLI usage fails without pre-created output directory.
- ⚠️ Debug exports unavailable on fresh checkouts until directory created.
Suggested change
const outPath = process.argv[3] || `output/langfuse-export-${Date.now()}.json`;
const outPath = process.argv[3] || `langfuse-export-${Date.now()}.json`;
Steps of Reproduction ✅
1. Ensure Langfuse environment variables are set so the script passes the

   early check at `.claude/skills/explorbot-debug/langfuse-export.ts:8-15`

   (`LANGFUSE_PUBLIC_KEY` and `LANGFUSE_SECRET_KEY` present).

2. From the repo root, run the script without an explicit output path, e.g.:

   `bun .claude/skills/explorbot-debug/langfuse-export.ts 1h`,

   in a working directory that does not contain an `output/` folder.

3. The script sets `range` and `outPath` at lines 68-69:

   `const range = process.argv[2] || '1h';`

   `const outPath = process.argv[3] || \`output/langfuse-export-\${Date.now()}.json\`;`

   so `outPath` points to `output/langfuse-export-<timestamp>.json`.

4. After fetching traces and observations, the script resolves the path and

   writes the file at lines 96-97:

   `const resolved = resolve(outPath);`

   `writeFileSync(resolved, JSON.stringify(result, null, 2));`.

   Because the `output` directory does not exist and is never created in

   this script or elsewhere in `.claude/skills/explorbot-debug/langfuse-export.ts`,

   `writeFileSync` throws `ENOENT: no such file or directory`, and the export

   fails with no JSON file produced.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** .claude/skills/explorbot-debug/langfuse-export.ts
**Line:** 69:69
**Comment:**
	*Possible Bug: The default output path points to "output/..." but the script never creates the "output" directory, so on a fresh checkout running the command with no explicit path will throw an ENOENT error when writeFileSync tries to write into a non-existent directory; using a default filename in the current directory avoids this runtime failure while still allowing callers to pass a custom path if they want.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

@codeant-ai
Copy link

codeant-ai bot commented Feb 10, 2026

CodeAnt AI finished reviewing your PR.

Copy link
Contributor

@DavertMik DavertMik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THat should simplify so much!
Let's try

@DavertMik DavertMik merged commit 673bf1e into testomatio:main Feb 10, 2026
0 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants