Skip to content

Canvas: model-facing geometry + few-shot guidance, inline finding actions, fallback parity - #498

Merged
Milhouszhang merged 4 commits into
masterfrom
feat/canvas-model-guidance-inline-actions
Jul 7, 2026
Merged

Canvas: model-facing geometry + few-shot guidance, inline finding actions, fallback parity#498
Milhouszhang merged 4 commits into
masterfrom
feat/canvas-model-guidance-inline-actions

Conversation

@n-WN

@n-WN n-WN commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Why

An audit of the Canvas implementation against three questions — does the model get few-shot frontend templates, is it told the card/page geometry, and can it perceive canvas interactions — found:

  1. No geometry guidance. The renderer knows its dimensions (chat column ~800px, grid{min} default 190px, code blocks scroll at 260px) but the model was told none of it, so it composes blind.
  2. No few-shot example. The tool description listed the component vocabulary but never showed one complete well-formed spec; the only example lives in the code-review skill. The description had also drifted behind the implemented component set (textarea, editableTable, mediaPicker, dependentSelect were undocumented).
  3. Interaction awareness is solid on paper (typed state + CanvasState pull, Submit push, action round-trip via the daemon bridge) but the desktop inline renderer — the primary surface — silently dropped finding.actions, contradicting the tool description's promise that action buttons continue the conversation. The HTML fallback also rendered five documented components as [unknown component: …].

What

Model-facing guidance (resources/tools/canvas.yaml, resources/canvas/components.md, code-review skill)

  • GEOMETRY contract: usable widths per surface, grid{min} semantics and sane ranges, code-block scroll height, lead-with-summary rule.
  • One complete minimal example spec in the tool description; two few-shot page templates (research dashboard, parameter intake) in the catalog.
  • INTERACTION section: edits auto-save under stable ids; Submit/action clicks message the agent with the canvasId; never ask the user to re-type Canvas values.
  • Complete the component list; retire the stale "not yet wired" note and a runtime-dead repo path reference in the skill.

Desktop inline actions (canvasActions.ts + tests, InlineCanvas*.svelte, stories)

  • finding.actions now render as buttons and route through the existing onSubmitCanvasState channel with the finding's bundled context; actionMessage mirrors the HTML fallback's wording so actions read the same to the agent from either surface.
  • Fix: finding locations rendered as raw JSON ({ "path": "src/pay.rs", "line": 210 }); now src/pay.rs:210.
  • Storybook stories for the two catalog templates double as living documentation.

HTML fallback parity (canvas_template.html)

  • Real textarea input; dependentSelect degrades to a flat single-select with group-suffixed labels; editableTable/mediaPicker/mediaModelSelect degrade read-only with an honest "requires Puffer Desktop" note.
  • Interactive-node list synced with interactive_node_type() in canvas.rs; esc() now escapes " so item URLs can't break out of attribute context.

Verification

  • vitest desktop agent-screen suite: 102 passed (incl. new canvasActions tests) · svelte-check: 0 errors · cargo test -p puffer-core canvas: 16 passed · cargo test -p puffer-resources: all passed.
  • Rendered both surfaces: the updated HTML fallback in Chrome (actions, textarea, degradations, XSS-escape check on table cells and quoted labels) and the desktop inline canvas via the new Storybook stories (actions render, click round-trip fires without console errors, locations formatted).

Generated with Claude Code

n-WN and others added 4 commits July 7, 2026 06:10
The Canvas tool description never told the model how much space a page
gets or what a well-formed spec looks like, and its component list had
drifted behind the implemented set (textarea, editableTable, mediaPicker,
dependentSelect were missing). Add a GEOMETRY contract (chat column
~800px, grid{min} defaults, code-block scroll height), one complete
minimal example spec, and an INTERACTION section that tells the model
edits are saved automatically and it must never ask the user to re-type
Canvas values. Extend the catalog with the same geometry facts plus two
few-shot page templates (research dashboard, parameter intake), and note
which inputs degrade read-only in the HTML fallback.

Also retire the stale 'not yet wired' note in the code-review skill (the
action round-trip exists) and stop pointing at a repo path that does not
exist at runtime.
…urns

The tool description promises that finding action buttons continue the
conversation, and the HTML fallback delivers that via the daemon bridge —
but the desktop inline renderer silently dropped `finding.actions`.
Render them as buttons and route clicks through the existing
onSubmitCanvasState channel with the finding's bundled context
(canvasActions.actionMessage mirrors the fallback's wording so an action
reads the same to the agent from either surface).

Also format finding locations as path:line instead of dumping the raw
location object as JSON, and add InlineCanvas stories covering the two
catalog templates (review-with-actions, parameter intake).
The fallback renderer predates textarea/dependentSelect/editableTable/
mediaPicker/mediaModelSelect, so documented components rendered as
'[unknown component: …]'. Add a real textarea input, degrade
dependentSelect to a flat single-select with group-suffixed labels, and
show editableTable/mediaPicker/mediaModelSelect read-only with an honest
'requires Puffer Desktop' note. Sync the interactive-node list with
interactive_node_type() in canvas.rs and escape double quotes so item
URLs cannot break out of attribute context.
Add a renderer regression test that requires the HTML fallback mediaPicker path to guard URL schemes before creating anchors. The fallback now only links http/https URLs and renders other model-provided values as escaped text.
@Milhouszhang
Milhouszhang merged commit ba1acd8 into master Jul 7, 2026
6 checks passed
@Milhouszhang
Milhouszhang deleted the feat/canvas-model-guidance-inline-actions branch July 7, 2026 09:48
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.

2 participants