Skip to content

feat: planning step, widget height fix, hide templates#67

Merged
GeneralJerel merged 11 commits intomainfrom
staging
Mar 26, 2026
Merged

feat: planning step, widget height fix, hide templates#67
GeneralJerel merged 11 commits intomainfrom
staging

Conversation

@GeneralJerel
Copy link
Copy Markdown
Collaborator

@GeneralJerel GeneralJerel commented Mar 26, 2026

Summary

Test plan

  • "Visualize how a car axle works" — agent shows PlanCard then generates visualization
  • Widget height stabilizes (no infinite growth) for Canvas/Three.js/SVG visualizations
  • "Visualize a car axle" appears in chat suggestions
  • Templates feature is hidden from UI and agent

Closes #62, closes #64

🤖 Generated with Claude Code

GeneralJerel and others added 10 commits March 26, 2026 07:10
Add a "Visualization Quality Standards" section to steer the model
toward using Three.js (via import map) for 3D content instead of
CSS transform hacks or Canvas 2D projection. Documents available
ES module libraries (three, gsap, d3, chart.js), enforces
type="module" script tags, and sets a polished quality bar for
generated visualizations.
Remove template library drawer, template chips, template tools registration,
and template-related agent state fields. Component files are kept in the
codebase for future re-enablement.

Closes #59
…ance

fix: add visualization quality guidance to agent prompt
- Add Demos button to header and DemoGallery drawer with category filter
- Send demo prompt to CopilotChat via appendMessage on "Try it" click
- Rename SaveTemplateOverlay → ExportOverlay, drop unused description prop
- Remove dead iframe preview code from DemoCard, remove unused html field
- Fix trailing blank line in agent system prompt
- Update chat suggestion from BFS/DFS to 3D Plane Controls
- Add clipboard write error handling in ExportOverlay
Add a plan_visualization tool that the agent must call before any
visualization tool (widgetRenderer, pieChart, barChart). This gives users
transparency into the agent's approach and improves output quality by
forcing structured thinking before code generation.
…mpts

- Break feedback loop in iframe height measurement by collapsing the
  content container before reading scrollHeight, so viewport-relative
  children don't inflate the measurement
- Remove +8 padding from height setter that compounded each cycle
- Replace "binary search" suggestion with "car axle" visualization
Keep planning step additions, adopt staging's quality standards and
removed templates. Combine car axle prompt with staging's 3D plane prompt.
Demo gallery preserved on feat/demo-gallery branch for future work.
feat: add planning step before visualization generation
@GeneralJerel
Copy link
Copy Markdown
Collaborator Author

PR Review: feat: planning step, widget height fix, hide templates

+580 / -88 across 16 files


Issues

1. File not renamed after component rename
save-template-overlay.tsx still has its old name, but the component is now ExportOverlay. Should be renamed to export-overlay.tsx so imports don't confuse future contributors.

2. Demo gallery is dead code on main
Four new files under demo-gallery/ (~418 lines) are added but never imported anywhere. The commit says "preserved on feat/demo-gallery branch for future work" — if there's a separate branch, these files probably shouldn't land on main as unreferenced dead code. Consider removing them from this PR and keeping them on the feature branch only.

3. Potential visual flash in height measurement
widget-renderer.tsx — collapsing the container to height: 0 before reading scrollHeight could cause a brief visual flicker in the iframe. Since ResizeObserver fires on layout changes, this collapse-then-restore could also re-trigger the observer, creating a tight loop. Worth testing with heavy Three.js visualizations to confirm no jank.

content.style.height = '0';
content.style.overflow = 'hidden';
var h = content.scrollHeight;
content.style.height = '';
content.style.overflow = '';

A safer approach might be to clone the node offscreen or use a separate measurement element that doesn't trigger layout shifts on the visible content.

4. Snake_case prop in React component
plan-card.tsxkey_elements uses snake_case because it maps to the Python tool parameter. This works, but if you want to keep React conventions, you could destructure and rename at the call site.


Looks Good

  • Planning tool design — Using a lightweight tool (plan.py) that returns a formatted string while the frontend renders it via useRenderTool is a clean pattern. The mandatory workflow in the system prompt is well-documented.
  • Height fix core logic — Removing the +8 padding accumulation is the right fix for the compounding growth.
  • Template removal — Clean removal from agent state, tools, and UI.
  • ExportOverlay clipboard error handling — Good addition of the rejection handler.
  • Import cleanup in export-utils.ts.

Summary

The substantive changes (planning step, height fix, template hiding) are solid. Main concerns:

  1. Dead demo gallery code shouldn't land on main if it's unused
  2. Rename the file to match ExportOverlay
  3. Validate the height measurement doesn't cause ResizeObserver loops under load

…easurement

- Rename save-template-overlay.tsx to export-overlay.tsx to match component name
- Remove unused demo-gallery components (preserved on feat/demo-gallery branch)
- Fix widget height measurement using offscreen clone instead of collapsing
  visible DOM, preventing potential ResizeObserver infinite loops
- Use camelCase keyElements prop in PlanCard (remap from snake_case at call site)
- Update chat disclaimer to be relevant to visualization demo
@GeneralJerel
Copy link
Copy Markdown
Collaborator Author

Review — ready to merge with one note

+165 / -88 across 12 files. TypeScript compiles clean, no stale imports.

What's in the PR

  1. Planning stepplan_visualization tool + PlanCard UI. Agent must plan before building any visualization.
  2. Widget height fix — Offscreen clone measurement replaces collapse-then-restore. Removes +8 padding accumulation that caused infinite growth.
  3. Template feature removal — Templates removed from agent state, tools, system prompt, and page UI.
  4. ExportOverlay renameSaveTemplateOverlayExportOverlay with file rename + clipboard error handling.
  5. Minor — Updated example suggestions, chat disclaimer, import cleanup.

Note: orphaned template files still on disk

These files are no longer imported but still exist in the tree:

  • apps/agent/src/templates.py
  • apps/app/src/components/template-library/ (4 files)

Not blocking — they'll be addressed when the demo gallery feature lands on this same PR.

Optional improvements (non-blocking)

  • Clone-based height measurement (widget-renderer.tsx:462-469): cloneNode(true) every 200ms for 15s on heavy Three.js content could cause GC pressure. Consider requestAnimationFrame debounce or reusing a single measurement element.
  • postMessage origin (widget-renderer.tsx:575-584): Host-side handler accepts widget-resize from any origin. Pre-existing, low risk (only sets a height number), but could validate e.source.

Looks good

  • Planning tool pattern — clean separation between Python tool and useRenderTool frontend rendering with snake_case → camelCase remapping at the call site.
  • <details> auto-collapse on PlanCard completion is a nice UX touch.
  • Offscreen clone is the right fix for ResizeObserver infinite loop risk.
  • Template removal is thorough in all active code paths.
  • Zero TypeScript errors, no stale imports to removed modules.

@GeneralJerel GeneralJerel merged commit 90adfb6 into main Mar 26, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: widget renderer height grows infinitely for viewport-filling content feat: add planning step before visualization generation

1 participant