Skip to content

Conversation

@koriym
Copy link
Owner

@koriym koriym commented Nov 1, 2025

Summary

Resolves Issue #28 (Issue 1) by making --json output clean and parseable with jq and other JSON tools.

Problem

When using --json mode, script stdout/stderr mixed with JSON output:

./bin/xdebug-profile --json -- php script.php | jq '.'
# parse error: Invalid numeric literal at line 1, column 8

Root Cause:

  • Script output (echo, var_dump, errors) interleaved with JSON
  • Broke jq parsing and piping to other tools
  • Made JSON mode unusable for automation and MCP integration

Solution

Automatically suppress script output when --json is used:

if ($jsonOutput) {
    // Suppress script output for clean JSON
    $cmd .= ' > /dev/null 2>&1';
    exec($cmd, $output, $exitCode);
} else {
    // Show script output in human mode
    passthru($cmd, $exitCode);
}

Benefits

Clean JSON output - No more mixed output:

./bin/xdebug-profile --json -- php script.php | jq '.["🎯 bottleneck_functions"]'
# Works perfectly!

jq compatible - Pipe directly to jq for filtering
MCP compatible - Pure JSON response for AI integration
Tool-friendly - Easy integration with other JSON processors
Backward compatible - Human-readable mode unchanged

Changes

Code:

  • bin/xdebug-profile: Conditional output suppression based on $jsonOutput flag
  • Exit code preserved for error detection

Documentation:

  • bin/xdebug-profile --help: Updated option descriptions and added jq example
  • docs/TROUBLESHOOTING.md: Added section on JSON output issues with before/after examples

Usage Examples

Before (broken):

./bin/xdebug-profile --json -- php script.php
# Mixed output breaks parsing

After (clean):

# Pure JSON output
./bin/xdebug-profile --json -- php script.php | jq '.["⏱️ execution_time_ms"]'

# Human-readable with script output
./bin/xdebug-profile -- php script.php

Testing

Verified that:

  • JSON mode produces clean, parseable output
  • jq filtering works correctly
  • Human mode still shows script output
  • Exit codes preserved for error handling

Related

This addresses Issue 1 from #28. Other enhancements (--top, --filter) will be addressed in separate PRs.

🤖 Generated with Claude Code

Sourceryによる要約

JSONモードでのスクリプト出力を抑制し、クリーンでパース可能なJSONを生成し、jqフィルタリングの使用例を含むドキュメントを更新

バグ修正:

  • --json使用時にスクリプトの標準出力および標準エラー出力を抑制し、出力の混在を防ぎ、クリーンなJSONパースを可能にする

機能改善:

  • スクリプト出力抑制時に元のコマンドの終了コードを保持する

ドキュメント:

  • JSONモードおよびjqフィルタリングの使用例(Before/After)を含むトラブルシューティングセクションを追加
Original summary in English

Summary by Sourcery

Suppress script output in JSON mode to produce clean, parseable JSON and update documentation with usage examples for jq filtering

Bug Fixes:

  • Suppress script stdout and stderr when --json is used to prevent interleaved output and enable clean JSON parsing

Enhancements:

  • Preserve the original command’s exit code when suppressing script output

Documentation:

  • Add troubleshooting section with before/after examples for JSON mode and jq filtering usage

Summary by CodeRabbit

  • New Features

    • JSON output now suppresses profiled script stdout/stderr for clean, machine-parseable output; human-readable mode remains unchanged.
  • Documentation

    • Help text and changelog updated with JSON workflow examples and usage.
    • Troubleshooting guide enhanced with examples for piping JSON to tools (e.g., jq) and avoiding mixed output.
Resolves Issue #28 (Issue 1) by making --json output parseable with jq
and other JSON tools.

Problem:
- Script stdout/stderr mixed with JSON output
- Broke jq parsing: `./bin/xdebug-profile --json -- php script.php | jq`
- Prevented piping to other JSON processing tools
- Common error: "parse error: Invalid numeric literal"

Solution:
- In JSON mode, redirect script output to /dev/null
- Keep exit code for error detection
- Use passthru() for human mode (show script output)
- Use exec() for JSON mode (suppress script output)

Benefits:
- ✅ Clean JSON output for jq: `... | jq '.["🎯 bottleneck_functions"]'`
- ✅ MCP-compatible: pure JSON response
- ✅ Tool-friendly: easy to integrate with other tools
- ✅ Backward compatible: human mode unchanged

Changes:
- bin/xdebug-profile: Conditional output suppression in JSON mode
- docs/TROUBLESHOOTING.md: Added JSON parsing issue and solution
- Updated --help text with clear behavior explanation
- Added jq usage example to help text

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 1, 2025

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "Fix #28 (Issue 1): Suppress script output in JSON mode for clean parsing" directly and clearly describes the main change in the changeset. The title accurately captures the core modification in bin/xdebug-profile, which redirects stdout/stderr to /dev/null when --json is active to prevent script output from interleaving with JSON output. The title is specific and descriptive—it explains what is being changed (suppressing script output), in what context (JSON mode), and the reason (for clean parsing)—without being verbose or vague. The inclusion of the issue reference (#28) provides proper context, and the title is concise enough to be quickly understood when scanning commit history.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/issue-28-json-clean-output

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai
Copy link

sourcery-ai bot commented Nov 1, 2025

レビュー担当者向けガイド(小規模PRでは折りたたみ表示)

レビュー担当者向けガイド

このPRは、--jsonフラグが使用された際に、純粋でパース可能なJSON出力を保証するためにスクリプトの標準出力/標準エラーの条件付き抑制を導入し、CLIヘルプテキストとトラブルシューティングドキュメントをjq統合の例で更新します。

JSONモードでの条件付き出力抑制のシーケンス図

sequenceDiagram
    participant User as actor User
    participant CLI as "xdebug-profile CLI"
    participant Script as "Target PHP Script"
    User->>CLI: Run xdebug-profile with --json flag
    CLI->>Script: Execute script (output suppressed)
    Script-->>CLI: Script runs (stdout/stderr redirected)
    CLI-->>User: Return pure JSON output
    User->>CLI: Run xdebug-profile without --json
    CLI->>Script: Execute script (output visible)
    Script-->>CLI: Script runs (stdout/stderr shown)
    CLI-->>User: Return human-readable output with script output
Loading

更新された出力処理ロジックのクラス図

classDiagram
    class XdebugProfileCLI {
      +bool jsonOutput
      +int exitCode
      +runScript(cmd)
    }
    XdebugProfileCLI : +runScript(cmd)
    XdebugProfileCLI : if jsonOutput
    XdebugProfileCLI :   cmd += ' > /dev/null 2>&1'
    XdebugProfileCLI :   exec(cmd, output, exitCode)
    XdebugProfileCLI : else
    XdebugProfileCLI :   passthru(cmd, exitCode)
    XdebugProfileCLI : # Output handling logic updated
Loading

ファイルレベルの変更点

変更点 詳細 ファイル
JSONモードでのスクリプト出力抑制
  • --jsonフラグが有効な場合、スクリプトの標準出力/標準エラーを/dev/nullにリダイレクト
  • JSONモードではexecを使用し、人間が読めるモードではpassthruを使用
  • 両方の実行パスでスクリプトの終了コードを保持
bin/xdebug-profile
ヘルプテキストとCLI使用例の更新
  • --help出力にJSONモードの説明を追加
  • CLIヘルプにjqフィルタリングの例を追加
bin/xdebug-profile
JSON出力のトラブルシューティングセクションの追加
  • スクリプト出力とJSON出力が混在する一般的な問題のエントリを導入
  • jq互換性を示すbashのビフォー/アフター例を提供
docs/TROUBLESHOOTING.md

関連する可能性のある課題


ヒントとコマンド

Sourceryとの連携

  • 新しいレビューをトリガーする: プルリクエストに@sourcery-ai reviewとコメントします。
  • 議論を続ける: Sourceryのレビューコメントに直接返信します。
  • レビューコメントからGitHub issueを生成する: Sourceryにレビューコメントからissueを作成するよう、それに返信して依頼します。また、レビューコメントに@sourcery-ai issueと返信することで、issueを作成することもできます。
  • プルリクエストのタイトルを生成する: プルリクエストのタイトル内のどこかに@sourcery-aiと記述すると、いつでもタイトルを生成できます。また、プルリクエストに@sourcery-ai titleとコメントすることで、いつでもタイトルを(再)生成できます。
  • プルリクエストの要約を生成する: プルリクエストの本文内のどこかに@sourcery-ai summaryと記述すると、いつでも好きな場所にPRの要約を生成できます。また、プルリクエストに@sourcery-ai summaryとコメントすることで、いつでも要約を(再)生成できます。
  • レビュー担当者向けガイドを生成する: プルリクエストに@sourcery-ai guideとコメントすることで、いつでもレビュー担当者向けガイドを(再)生成できます。
  • すべてのSourcery���メントを解決する: プルリクエストに@sourcery-ai resolveとコメントすると、すべてのSourceryコメントを解決できます。すでにすべてのコメントに対応し、もう表示したくない場合に便利です。
  • すべてのSourceryレビューを却下する: プルリクエストに@sourcery-ai dismissとコメントすると、既存のすべてのSourceryレビューを却下できます。新しいレビューで一から始めたい場合に特に便利です。新しいレビューをトリガーするには、@sourcery-ai reviewとコメントするのを忘れないでください!

エクスペリエンスのカスタマイズ

ダッシュボードにアクセスして、以下を行うことができます:

  • Sourceryが生成するプルリクエストの要約、レビュー担当者向けガイドなどのレビュー機能を有効または無効にします。
  • レビュー言語を変更します。
  • カスタムレビュー指示を追加、削除、または編集します。
  • その他のレビュー設定を調整します。

ヘルプ

Original review guide in English
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

The PR introduces conditional suppression of script stdout/stderr when the --json flag is used to ensure pure, parseable JSON output, and updates the CLI help text and troubleshooting documentation with examples for jq integration.

Sequence diagram for conditional output suppression in JSON mode

sequenceDiagram
    participant User as actor User
    participant CLI as "xdebug-profile CLI"
    participant Script as "Target PHP Script"
    User->>CLI: Run xdebug-profile with --json flag
    CLI->>Script: Execute script (output suppressed)
    Script-->>CLI: Script runs (stdout/stderr redirected)
    CLI-->>User: Return pure JSON output
    User->>CLI: Run xdebug-profile without --json
    CLI->>Script: Execute script (output visible)
    Script-->>CLI: Script runs (stdout/stderr shown)
    CLI-->>User: Return human-readable output with script output
Loading

Class diagram for updated output handling logic

classDiagram
    class XdebugProfileCLI {
      +bool jsonOutput
      +int exitCode
      +runScript(cmd)
    }
    XdebugProfileCLI : +runScript(cmd)
    XdebugProfileCLI : if jsonOutput
    XdebugProfileCLI :   cmd += ' > /dev/null 2>&1'
    XdebugProfileCLI :   exec(cmd, output, exitCode)
    XdebugProfileCLI : else
    XdebugProfileCLI :   passthru(cmd, exitCode)
    XdebugProfileCLI : # Output handling logic updated
Loading

File-Level Changes

Change Details Files
Suppress script output in JSON mode
  • Redirect script stdout/stderr to /dev/null when --json flag is active
  • Use exec for JSON mode and passthru for human-readable mode
  • Preserve script exit code across both execution paths
bin/xdebug-profile
Update help text and CLI usage examples
  • Enhance --help output with JSON mode description
  • Add jq filtering examples to CLI help
bin/xdebug-profile
Add troubleshooting section for JSON output
  • Introduce common problem entry for mixed script/JSON output
  • Provide before/after bash examples demonstrating jq compatibility
docs/TROUBLESHOOTING.md

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

こんにちは - あなたの変更を確認しました - いくつかフィードバックがあります:

  • 出力抑制のために /dev/null をハードコーディングすると、Windows で動作しない可能性があります。PHP の出力バッファリングのようなクロスプラットフォームなアプローチを使用するか、適切なヌルデバイスを検出することを検討してください。
  • JSON モードですべてのスクリプト出力をサイレントに破棄すると、デバッグが難しくなる可能性があります。オプションで標準エラー出力をキャプチャし、JSON フィールドに含めるか、ログファイルにリダイレクトすることを検討してください。
Prompt for AI Agents
このコードレビューのコメントに対処してください:

## 全体的なコメント
- 出力抑制のために `/dev/null` をハードコーディングすると、Windows で動作しない可能性があります。PHP の出力バッファリングのようなクロスプラットフォームなアプローチを使用するか、適切なヌルデバイスを検出することを検討してください。
- JSON モードですべてのスクリプト出力をサイレントに破棄すると、デバッグが難しくなる可能性があります。オプションで標準エラー出力をキャプチャし、JSON フィールドに含めるか、ログファイルにリダイレクトすることを検討してください。

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
もっと役立つようにするには!各コメントの👍または👎をクリックしてください。そのフィードバックをレビュー改善に役立てます。
Original comment in English

Hey there - I've reviewed your changes - here's some feedback:

  • Hardcoding /dev/null for output suppression may break on Windows; consider using a cross-platform approach like PHP’s output buffering or detecting the appropriate null device.
  • Silently discarding all script output in JSON mode can make debugging harder; consider optionally capturing stderr and including it in a JSON field or redirecting it to a log file.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Hardcoding /dev/null for output suppression may break on Windows; consider using a cross-platform approach like PHP’s output buffering or detecting the appropriate null device.
- Silently discarding all script output in JSON mode can make debugging harder; consider optionally capturing stderr and including it in a JSON field or redirecting it to a log file.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Add entry for Issue #28 (Issue 1) in Unreleased section.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
docs/TROUBLESHOOTING.md (1)

220-220: Replace version placeholder with actual version.

The comment references "v0.x.x" which appears to be a placeholder. Consider replacing this with the actual version where this fix was introduced or removing the version reference entirely if it's not critical.

Apply this diff if you want to remove the version reference:

-# ❌ Before v0.x.x: Script output breaks jq parsing
+# ❌ Before: Script output breaks jq parsing
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef01bf0 and d8f6f7f.

📒 Files selected for processing (2)
  • bin/xdebug-profile (4 hunks)
  • docs/TROUBLESHOOTING.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-02T16:54:01.944Z
Learnt from: CR
Repo: koriym/xdebug-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-02T16:54:01.944Z
Learning: Default tool selection: use ./bin/xdebug-profile for general analysis, ./bin/xdebug-trace for execution flow, ./bin/xdebug-coverage for coverage, ./bin/xdebug-debug for interactive debugging

Applied to files:

  • bin/xdebug-profile
  • docs/TROUBLESHOOTING.md
📚 Learning: 2025-09-02T16:54:01.944Z
Learnt from: CR
Repo: koriym/xdebug-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-02T16:54:01.944Z
Learning: Prioritize runtime execution data (trace/profile/coverage) over static code analysis when assisting with PHP debugging

Applied to files:

  • bin/xdebug-profile
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review
🔇 Additional comments (4)
docs/TROUBLESHOOTING.md (1)

233-234: LGTM!

The jq filtering examples clearly demonstrate the clean JSON output functionality. These examples will help users understand how to leverage the fixed JSON output with standard tooling.

bin/xdebug-profile (3)

31-31: LGTM!

The help text updates clearly communicate the JSON mode behavior and provide a practical jq filtering example. The documentation accurately reflects the implementation changes.

Also applies to: 54-56, 66-67


167-174: Consider documenting error debugging workflow for JSON mode.

In JSON mode, all script output (including errors, warnings, and exceptions) is suppressed for clean JSON parsing. While this achieves the PR objective, it may hinder debugging when the profiled script fails. Users will see a non-zero exit code but no error messages.

Consider adding a note in the help text or troubleshooting guide suggesting that users should:

  1. Run without --json first to verify the script works
  2. Check exit codes in JSON mode to detect failures
  3. Re-run without --json if debugging is needed

Example addition to help text:

 CORE OPTIONS:
-  --json                      AI-optimized JSON output (suppresses script output for clean parsing)
+  --json                      AI-optimized JSON output (suppresses script output for clean parsing)
+                              Note: Errors are suppressed; check exit code or run without --json to debug

Is this trade-off acceptable, or should critical errors (e.g., PHP fatal errors) remain visible even in JSON mode?


166-166: LGTM!

Exit code handling is correct. The script properly captures the exit code from both exec() and passthru() calls and propagates it at the end, ensuring that failures in the profiled script are detectable even when output is suppressed.

Also applies to: 520-520

Comment on lines +167 to +174
if ($jsonOutput) {
// JSON mode: suppress script output for clean JSON parsing
$cmd .= ' > /dev/null 2>&1';
exec($cmd, $output, $exitCode);
} else {
// Human-readable mode: show script output
passthru($cmd, $exitCode);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Windows compatibility issue with /dev/null redirection.

The redirection > /dev/null 2>&1 is Unix/Linux specific and will fail on Windows systems. Windows uses NUL instead of /dev/null.

Apply this diff to add cross-platform support:

+// Determine null device based on OS
+$nullDevice = PHP_OS_FAMILY === 'Windows' ? 'NUL' : '/dev/null';
+
 // Execute command
 $exitCode = 0;
 if ($jsonOutput) {
     // JSON mode: suppress script output for clean JSON parsing
-    $cmd .= ' > /dev/null 2>&1';
+    $cmd .= " > {$nullDevice} 2>&1";
     exec($cmd, $output, $exitCode);
 } else {
     // Human-readable mode: show script output
     passthru($cmd, $exitCode);
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In bin/xdebug-profile around lines 167 to 174, the current redirection uses the
Unix-specific '/dev/null' which breaks on Windows; detect the platform (for
example via PHP_OS_FAMILY or checking PHP_OS for 'WIN') and set a $nullDevice
variable to 'NUL' on Windows and '/dev/null' otherwise, then append the
redirection using that variable (e.g., " > {nullDevice} 2>&1") when building
$cmd for JSON mode so exec() works cross-platform; leave the passthru path
unchanged.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
CHANGELOG.md (1)

57-61: Well-written changelog entry; consider clarifying the issue scope.

The entry accurately captures the fix and includes a practical jq example. However, since Issue #28 has multiple parts (as noted in the PR objectives), consider clarifying that this entry addresses "Issue 1 from #28" to distinguish it from the earlier %p placeholder fix on lines 53–56, which also references #28.

Suggested revision:

- **JSON Output Parsing**: Fixed `xdebug-profile --json` to suppress script output for clean JSON ([#28](https://github.com/koriym/xdebug-mcp/issues/28))
+ **JSON Output Parsing**: Fixed `xdebug-profile --json` to suppress script output for clean JSON ([#28](https://github.com/koriym/xdebug-mcp/issues/28) - Part 1)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d8f6f7f and e342590.

📒 Files selected for processing (1)
  • CHANGELOG.md (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-02T16:54:01.944Z
Learnt from: CR
Repo: koriym/xdebug-mcp PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-02T16:54:01.944Z
Learning: Default tool selection: use ./bin/xdebug-profile for general analysis, ./bin/xdebug-trace for execution flow, ./bin/xdebug-coverage for coverage, ./bin/xdebug-debug for interactive debugging

Applied to files:

  • CHANGELOG.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Sourcery review
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants