Conversation
When debugging loops, most steps produce identical state. The --watch option evaluates PHP expressions at each step and only records steps where watched values change, dramatically reducing output tokens. Supports multiple --watch flags, tracks initial/changed/out_of_scope transitions, and includes previous values for comparison.
📝 WalkthroughWalkthroughAdds a global --watch=EXPR flag to xstep; collects multiple watches, propagates them to DebugServer, evaluates watch expressions each step, attaches per-step watch metadata (expression, value, previous, reason), and when watches are present only records steps where at least one watched value changed. Changes
Sequence DiagramsequenceDiagram
participant User as User/CLI
participant Parser as bin/xstep Parser
participant Server as DebugServer
participant DBGp as DBGp Evaluator
participant Recorder as Step Recorder
User->>Parser: Run xstep with --watch=EXPR...
Parser->>Parser: Collect watches[] and other options
Parser->>Server: Start DebugServer with watches config
loop for each program step
Server->>DBGp: Evaluate each watch expression
DBGp-->>Server: Return value or <unavailable>
Server->>Server: Compute current watch data (expression,value,previous,reason)
Server->>Server: Compare with previous values
alt any watched value changed
Server->>Recorder: Record step + watches metadata
Recorder-->>Server: Acknowledge recording
else no watched changes
Server->>Server: Skip recording this step
end
Server->>Server: Update previous watch values
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
outputStepRecordingResults() was called both from within performStepTrace() and again from cleanup, causing duplicate JSON output. Add a guard flag to ensure single output.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/DebugServer.php`:
- Around line 1035-1089: evaluateWatchExpression currently summarizes
arrays/objects as "array(n)" or "object: Class", which prevents watches from
detecting internal mutations; update evaluateWatchExpression to, when $type is
'array' or 'object', attempt to include a content-derived signature (e.g., hash
of serialize() or json_encode() of child properties) instead of only
count/class: inspect $prop children (or use $this->propertyGet/children data
returned by parseXmlResponse), build a stable string representation of child
values (falling back to the existing summary if children are unavailable), then
return a short hash or encoded snippet so watches change when internal contents
change; keep the existing fallback behavior for missing data.
🧹 Nitpick comments (1)
src/DebugServer.php (1)
637-667: Consider separating executed-step cap from recorded-step cap when watch filtering is enabled.
$stepCountincrements on skipped steps, so long loops with no watch changes can hitmaxStepsbefore any recorded change. A separateexecutedStepssafety cap plusrecordedStepsformaxStepswould preserve safety while keeping the watch feature useful.
- Add content-based hashing for array/object watch expressions using property_get child element inspection (detects internal mutations) - Separate recorded step count from executed step count so watch-filtered loops don't hit maxSteps prematurely (safety cap = maxSteps * 10)
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/DebugServer.php (1)
615-673:⚠️ Potential issue | 🟠 MajorKeep diff baselines aligned to recorded steps when watch filtering skips execution.
previousVariablesis updated before you decide to skip a step, so the next recorded diff is relative to an unrecorded step; downstream can’t reconstruct state across recorded steps. Consider updating the baseline only when a step is actually recorded (or switch to full recording whenwatchChanged).🛠️ Suggested fix (update baseline only on recorded steps)
- $previousVariables = $currentVariables; + // defer baseline update until we actually record- $previousVariables = $currentVariables; + // defer baseline update until we actually record$steps[] = $step; + $previousVariables = $currentVariables; $recordedCount++;
|
@coderabbitai Both issues addressed in b8e5b8f:
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 3297 🏁 Script executed: Length of output: 1994 🏁 Script executed: Length of output: 1472
✅ Content-based hashing (lines 1124-1160):
✅ maxSteps separation (lines 501, 514, 688, 691):
Both implementations look solid. The content hashing will now detect internal array/object mutations, and the watch filtering won't prematurely hit the step limit! 🎯 🧠 Learnings usedIf you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! |
Summary
--watch=EXPRoption toxstepthat evaluates PHP expressions at each step and only records steps where the watched value changes--watchflags, tracksinitial/changed/out_of_scopetransitions with previous valuesChanges
bin/xstep: Parse--watch=EXPRarguments (multiple allowed)src/DebugServer.php: AddevaluateWatchExpression()method and watch-based filtering inperformStepTrace()docs/schemas/xstep.json: Addwatchesfield to breakpoint schema definitiontests/Unit/DebugServerTest.php: Add tests for watches option and method existenceTest plan
composer testspasses (PHPCS, PHPStan, PHPUnit)composer pcovcoverage 98.80%xcoverage100% (416/416 lines)Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.