Skip to content

Feat/renderer vue#59

Merged
gitsad merged 41 commits into
mainfrom
feat/renderer-vue
Jul 24, 2026
Merged

Feat/renderer vue#59
gitsad merged 41 commits into
mainfrom
feat/renderer-vue

Conversation

@gitsad

@gitsad gitsad commented Jul 24, 2026

Copy link
Copy Markdown
Member

What does this PR do?

Adds @mobile-reality/mdma-renderer-vue (v0.1.0), a Vue 3 renderer for MDMA documents, plus
its docs and a runnable example. It turns a parsed MDMA document into interactive Vue components —
all 10 component types plus inline Markdown — with full state, bindings, actions, policy, audit,
and PII redaction, consuming the headless spec + runtime stack unchanged. The view layer is
new; the store logic is shared and framework-agnostic.

Highlights:

  • New package packages/renderer-vueMdmaDocument, MdmaBlock, the theme module,
    provide/inject contexts (store, element overrides, custom variants), store composables that
    return ComputedRefs, the renderer registry, and built-in renderers for every component type.
    Ships styles.css (--mdma-* variables). Authored as defineComponent + h() in plain .ts
    (no .vue SFCs), so it builds with tsc and needs no bundler. 19 test files / 121 tests.
  • Example examples/renderers/mdma-vue — a frontend-only OpenRouter agent chat that renders
    streamed MDMA replies with the Vue renderer (streamed re-parse via updateAst, per-turn store,
    aggregated action log, a 2D-chart override, and a three.js graph-3d custom component). Private,
    not published.
  • Docs — a "Renderers → Vue" page in the demo app, a Vue note on the Theming page, and Vue
    mentions across the repo README / docs/. Fixes lang="vue" syntax highlighting in the demo.

Closes #

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing behavior to change)
  • Refactor (no functional change)
  • Documentation
  • CI / tooling

Packages Affected

  • @mobile-reality/mdma-renderer-vue
  • @mobile-reality/mdma-spec
  • @mobile-reality/mdma-parser
  • @mobile-reality/mdma-runtime
  • @mobile-reality/mdma-attachables-core
  • @mobile-reality/mdma-renderer-react
  • @mobile-reality/mdma-prompt-pack

Checklist

  • I have read the CONTRIBUTING guide.
  • My code follows the existing code style (pnpm format and pnpm lint pass).
  • I have added or updated tests that cover my changes. (19 files, 121 tests in renderer-vue)
  • All tests pass (pnpm test).
  • Type-checking passes (pnpm typecheck). (24 tasks green)
  • I have added a changeset (pnpm changeset) if this change affects published packages.
    (.changeset/vue-renderer.md, minor)
  • New or changed MDMA schemas are backwards-compatible (or marked as breaking).
    (N/A — no schema changes; the Vue renderer consumes spec unchanged.)
  • Sensitive fields are marked with sensitive: true where appropriate.
    (N/A — no spec/schema changes; the renderer honors existing sensitive flags and redaction.)

How to Test

  1. pnpm install && pnpm build
  2. Package gate: pnpm --filter @mobile-reality/mdma-renderer-vue test (121 tests),
    ... typecheck, ... lint — all green.
  3. Export-parity guard: tests/public-api.test.ts asserts every value export of
    renderer-react exists in renderer-vue.
  4. Docs: pnpm --filter @mobile-reality/mdma-demo devDocs → Renderers → Vue (and the Vue
    note on the Theming page); confirm the vue code blocks are syntax-highlighted.
  5. Example (optional, needs a key): in examples/renderers/mdma-vue, copy .env.example to
    .env, set VITE_OPENROUTER_API_KEY, then pnpm --filter mdma-example-vue dev. Ask "collect
    my shipping details", "chart our quarterly revenue", "show sales by region and quarter as a 3D
    graph"; components render live as the reply streams, and interactions appear in the action log.

gitsad added 30 commits July 23, 2026 18:40
Frontend-only Vite + Vue 3 app that parses one MDMA document and renders it
with @mobile-reality/mdma-renderer-vue: a form (with a sensitive field and a
data-source select), a masked-column table, a callout, an approval gate, and a
submit button, plus a live audit-log panel and a light/dark theme toggle.
Streams a model through OpenRouter (key from VITE_OPENROUTER_API_KEY) prompted
with the MDMA author prompt; each assistant reply is re-parsed per chunk into
its own DocumentStore and rendered with @mobile-reality/mdma-renderer-vue, so
embedded components appear live as the response streams. Frontend-only, no
backend or AG-UI — the Vue counterpart of the React demo's agent chat.
…dma-vue

Renderer demos live under examples/renderers/ rather than alongside the
protocol integrations; adds the examples/renderers/* workspace glob.
gitsad added 11 commits July 24, 2026 12:58
Mutating a turn in place left its keyed <ChatMessage> with an unchanged prop
reference, so Vue skipped the patch and the bubble stayed on the placeholder
while content streamed in. Replace the turn object per update, and markRaw the
store/AST so Vue never proxies them.
The flex body now sets min-height:0 so the message thread scrolls internally
instead of the window. Adds a right-hand action-log panel that merges every
turn's store audit entries (newest first), and the model already reads from
VITE_MDMA_MODEL.
…eme the scrollbar

- Action-log entries now show the payload detail (field = value, → action id,
  approver), with sensitive values shown as ••• since the store hashes them.
- Assistant bubbles take the full column width so rendered forms aren't cramped;
  user bubbles stay compact. Thread widened to 860px.
- color-scheme is bound to the app theme, so scrollbars and form controls follow
  it instead of the OS (no dark scrollbar under the light UI).
…Vue chat

- ChartRenderer overrides the built-in chart with a real inline-SVG chart
  (bar/line/area/pie) via customizations.components.chart.
- Graph3D is a host-registered custom component (type: custom, name: graph-3d):
  an interactive three.js bar chart whose bar clicks dispatch into the store and
  fire actions.onSelect. Registered via customVariants and advertised to the
  model through buildSystemPrompt({ customComponents }).
- three.js is code-split and loaded on demand, only when a graph-3d renders.
… chat

The 3D scene only initialised once, on mount — but an async custom component
mounted during a streamed re-parse can come up before its data (or layout width)
is ready, leaving an empty black canvas. Now the scene rebuilds whenever the
props change, initialisation is deferred a frame for layout, a placeholder shows
until the scene is ready, and the CSV parser tolerates escaped/;-separated rows.
Match three.js to the demo (0.185).
New Renderers → Vue docs page (install, usage, differences from the React
renderer, theming, customizations, link to the example app), registered in the
docs nav, plus a Vue note in the Theming page.
highlight.js had no mapping for lang="vue", so those blocks rendered as
plaintext. Map vue/html to the XML grammar and register javascript so a Vue
SFC's markup and <script> block are both colored.
Rewrite the Vue docs to describe what the renderer does rather than framing it
as a sibling of the React renderer. Same structure; the 'differences from React'
section becomes a self-contained 'State & reactivity' section.
Local agent run artifacts (plans, handoffs, notes) shouldn't be merged.
@gitsad
gitsad merged commit bbabe35 into main Jul 24, 2026
1 check 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.

2 participants