Restore HTML Element Hierarchy in Stack Traces for Better AI Agent Context #38
+116
−41
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem
Between version 0.0.54 and the current version, stack trace output was significantly simplified to reduce noise. While this simplification had good intentions, it removed critical HTML element hierarchy information that AI coding agents need to effectively understand and modify DOM structures.
What Changed Between Versions
Version 0.0.54 output:
Current version output:
Why This Is Problematic for AI Agents
The current version only shows 3 levels and jumps straight to React component names, completely skipping the HTML element hierarchy. This causes several issues:
Lost DOM Context: AI agents can't see that the
spanis inside ath(table header cell), which is in atr(table row), which is in athead(table header), which is in atable. This structural information is critical for understanding how to modify the element correctly.Insufficient Depth: Only 3 levels means the agent might not even see the immediate parent component, let alone the layout structure.
Can't Distinguish Element Types: Without seeing
thvstd, agents can't tell if they're modifying a header cell or data cell. Without seeingbuttonvsa, they can't tell if it's a button or link. This leads to incorrect modifications.Real-World Impact
When an AI agent is asked to "make this bold" or "change the styling" on a table header, it needs to know:
spaninside ath(table header) - style accordinglyWhen asked to "fix this form input":
input→label→div→form→FormComponentSolution
This PR restores the HTML element hierarchy from v0.0.54 while keeping the improvements from recent versions. It provides a middle ground between the overwhelming 20+ level stack traces and the current oversimplified 3-level output.
Changes Made
1. Restored Manual Fiber Traversal (
src/context.ts)Replaced
getOwnerStack()from bippy (which only returns React component owners) with manual fiber tree traversal that includes both HTML elements and React components:Key insight:
isHostFiber()identifies HTML elements (DOM nodes) vsisCompositeFiber()which identifies React components. The oldgetOwnerStack()only returned composite fibers, losing the HTML structure.2. Updated Stack Frame Structure
This preserves both the element/component name AND its source location.
3. Restored Classic Stack Format
Changed from the confusing nested format back to the clearer v0.0.54 style:
The
at X in file.tsxformat is:4. Increased Default Stack Depth
Changed
maxLinesdefault from 3 to 10, because:5. Updated Dependent Code (
src/core.tsx)Fixed references to use new StackFrame structure:
Result
New Output Format (This PR)
Now provides both HTML structure AND React component hierarchy:
Benefits
✅ AI agents see complete HTML structure - Understand element relationships (table header, form input, button, etc.)
✅ React component hierarchy preserved - Still shows component ownership chain
✅ Optimal depth - 10 levels provides enough context without overwhelming (vs 3 too shallow, unlimited too verbose)
✅ Filters noise - Still removes internal React/Next.js components (LoadableComponent, ErrorBoundary, etc.)
✅ Better format - Clearer "at element in file" syntax
✅ Configurable - Users can override
maxLinesif neededComparison Table
at X in filein X (at file)at X in fileTechnical Implementation
Why Manual Traversal?
getOwnerStack()from bippy only returns React component "owners" - components that created other components. It specifically excludes host fibers (HTML elements) because from React's perspective, DOM nodes aren't "owners."Manual
traverseFiber()captures both:isHostFiber(fiber)isCompositeFiber(fiber)Why Filter Internal Components?
Still filters out React/Next.js internal components:
InnerLayoutRouter,RedirectBoundary,LoadingBoundaryLoadableComponent,ErrorBoundarybody,html(Next.js server components)_These add noise without providing useful context for modifications.
Performance
Promise.all()Testing
✅ Built successfully with TypeScript
✅ Tested with
@react-grab/claude-codeintegration✅ Tested with
@react-grab/cursorintegration✅ Tested with complex nested structures (tables, forms, multi-level layouts)
✅ Tested with both Vite and Next.js projects
✅ All package builds pass
Breaking Changes
None. This is fully backward compatible:
maxLinesstill workUsers can still override
maxLinesif they prefer fewer/more levels:Files Changed
packages/react-grab/src/context.ts- Restored fiber traversal, updated stack formattingpackages/react-grab/src/core.tsx- Updated StackFrame property accessMigration Guide
No migration needed - this is a drop-in improvement. If you're using react-grab, you'll automatically get better stack traces after updating.
Related Context
This addresses feedback from users using react-grab with AI coding agents (Claude Code, Cursor, etc.) who found that the simplified stack traces didn't provide enough context for the agents to make accurate code modifications, particularly when working with:
The lack of HTML element visibility meant agents couldn't distinguish between different types of containers, leading to incorrect or suboptimal code changes.
Summary: This PR restores the best aspects of v0.0.54's detailed stack traces while maintaining the improved signal-to-noise ratio of recent versions. It provides the "goldilocks" amount of information - not too much, not too little - specifically optimized for AI agent workflows.