> Implementation snapshot, 2026-09-08. This describes the existing prototype, not the target product contract. The [project specification](project-spec.md) governs future development. Local Pi registration is installation-specific; cloning this repository does not configure Pi.

# Existing prototype: operation and limitations

This spike tests one narrow question: can executable templates plus structured input produce more stable terminal-friendly images than unconstrained Mermaid generation?

It is intentionally **not production code**. The local server is registered in Pi as the direct tool `render_visual`; Codex, Claude, and the global skill registry are not configured by this project.

## Boundary

```text
show-me / show-me-gap (choose what to show)
  -> VisualSpec (template + nodes + edges)
  -> pure renderer core (validate + layout + SVG)
  -> adapters
       CLI   -> SVG + PNG
       MCP   -> terminal Mermaid, image content, or both + diagnostics
```

The renderer supports three executable templates:

- `architecture`: stable grouped columns with explicit lanes for backward edges.
- `gap-map`: ordered `intent -> implementation -> gap` columns.
- `roadmap`: dependency-ranked stages, with a deterministic fallback when a cycle is detected.

It also has a composition mode for diagrams that do not fit a template. The first-batch contract has four semantic visual primitives:

- `stack`: horizontal or vertical structure using tokenized gaps.
- `group`: semantic containment around exactly one child composition.
- `card`: the only addressable entity and Relation endpoint.
- `note`: a non-addressable constraint, risk, or conclusion.

Relationships remain a separate `relations` list. Legend is derived automatically. Arbitrary coordinates, pixel sizes, CSS, and more than four layout-container levels are rejected; Card and Note leaves do not add container depth.

It validates generated Mermaid through grok-mermaid. It does not accept agent-authored Mermaid input, call a model, infer business meaning, auto-cluster nodes, configure a client, or publish artifacts.

## Run

Install the locked Node.js dependency with `with-env npm ci`. The renderer uses `grok-mermaid` 0.2.2 (the version used by the validated Pi runtime) to check actual Unicode output and width. Local `rsvg-convert` (librsvg) converts SVG to PNG, including terminal fallback images.

```bash
cd show-me-mcp
with-env npm run render:fixture
with-env npm run render:composition
with-env npm test
```

Run the reusable CLI adapter:

```bash
with-env node bin/render-visual.mjs fixtures/complex-architecture.json artifacts/my-visual
```

Start the newline-delimited JSON-RPC stdio server:

```bash
with-env node bin/mcp-server.mjs
```

The server exposes one tool, `render_visual`, with `{ spec, outputName?, presentation? }`.

- `presentation: "terminal"` returns fenced Mermaid for Pi's built-in Unicode renderer when the terminal checks pass; otherwise it returns PNG with degradation reasons.
- `presentation: "image"` returns the PNG image block (default, backward compatible).
- `presentation: "both"` returns Mermaid and PNG when the terminal checks pass, or just PNG with degradation reasons when they fail.

All modes retain SVG/PNG artifact paths and diagnostics. Mermaid is generated deterministically from the validated VisualSpec; it is not accepted as agent-authored input.

Terminal checks measure actual Unicode width against a renderer-owned 120-column budget. Parsing warnings, rendering failures, nested Stack layouts that would lose structure, or excessive width trigger image fallback. `requestedPresentation` records the caller's choice; `presentation` records what was returned. `mermaidDiagnostics.terminal` reports `width`, `maxColumns`, `warnings`, and `fallbackRecommended`; `degradationReasons` explains the fallback. An unsafe Mermaid candidate is not included in the MCP response. SVG dimensions remain in `diagnostics.canvas` and are not terminal column counts.

After updating server code, restart a Pi session to start a fresh server process. This repair keeps the tool's input schema unchanged.

## Composition mode

```json
{
  "version": "0.1",
  "title": "Composable runtime",
  "composition": {
    "type": "stack",
    "direction": "horizontal",
    "children": [
      {
        "type": "group",
        "title": "Input",
        "child": { "type": "card", "id": "agent", "title": "Agent" }
      },
      { "type": "card", "id": "proof", "title": "Evidence" }
    ]
  },
  "relations": [
    { "from": "agent", "to": "proof", "label": "inspect", "kind": "flow" }
  ]
}
```

## Minimal VisualSpec

```json
{
  "template": "architecture",
  "title": "Request lifecycle",
  "nodes": [
    { "id": "client", "label": "Client", "group": "entry" },
    { "id": "api", "label": "API", "group": "service" }
  ],
  "edges": [
    { "from": "client", "to": "api", "label": "request" }
  ]
}
```

Optional node fields are `detail` and `status`; supported status colors include `aligned`, `partial`, `unmapped`, `contradicted`, `ambiguous`, and `unknown`.

Diagnostics currently report node, edge, and backward-edge counts; overflowing node IDs; canvas dimensions; whether splitting is recommended or performed; and whether the layout degraded.
Composition diagnostics additionally report primitive counts, maximum container depth, and derived-legend state.

## How the skills would call it

`show-me` should select a template and emit only relevant nodes and edges. `show-me-gap` should preserve capability IDs as node IDs, map its semantic states to `status`, and pass evidence summaries as `detail`. The prototype exposes `splitRecommended` and overflow diagnostics but does not implement the target automatic repair loop. Asking an Agent to repair layout is not the target workflow; see [project specification](project-spec.md).

The core in `src/` has no MCP knowledge. A future Pi extension can import it or invoke `bin/render-visual.mjs` without requiring native MCP support.

## Known limits

- Template mode compiles to the same Primitive contract; there is no second layout engine.
- Composition mode supports nested horizontal and vertical regions, but it does not yet optimize arbitrary graph crossings.
- SVG/PNG preserves nested Stack layout. The terminal adapter explicitly falls back to PNG when a Stack directly contains another Stack, rather than flattening it without notice.
- Text measurement is a deterministic character-width estimate, not browser font metrics.
- The renderer recommends splitting but does not split automatically.
- PNG appearance depends on locally installed fonts and librsvg.
- Artifacts use a fixed dark theme and fixed geometry.
- The raw MCP adapter implements only the small protocol surface needed for this spike.
