Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/viewer/src/client/renderers/sgcr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@ is what "diagonal" means. Pass via `SGCROptions` (`{ routing }`, `{ layout }`).
incoming chords can stack arrowheads) the viewer runs `checkInvariants` and **falls back to layered**
if the ring isn't clean. Output is reported as `routing: "octilinear"` (chords are diagonal).

## Annotations (overlay layer)

`placeAnnotations(layout, annotations)` (`annotate.ts`) overlays callouts/badges/icons/notes on a
**frozen** layout — each anchored to a node, an edge midpoint, or a point — placed in the free space
the layout already reserves, reusing the checker's exact predicates so it's accepted only when clear of
every node/edge/label/other annotation, and **deferred** (signalled back) when there's no room rather
than stacked into clutter. Supports toggleable **layers**, **priority**, and compass **preference**.
The executable proof is **P10** (annotation-overlap), checked when `layout.annotations` is present.
Wired into the viewer: a `flow` spec carries `annotations: [...]`, rendered as a pan/zoom overlay with a
per-layer toggle; `addAnnotation`/`removeAnnotation` patch ops add them to a living diagram. See
`docs/superpowers/specs/2026-06-22-sgcr-annotations-design.md`.

## Determinism & order-invariance
- **Deterministic:** no RNG anywhere; all ordering uses stable sorts seeded by id; integer grid.
Same input → byte-identical output (verified on 3000 graphs).
Expand Down
2 changes: 1 addition & 1 deletion plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "termchart",
"displayName": "termchart",
"description": "A live canvas your AI draws on. Instead of walls of text, your agent pushes rich, native visuals to a browser tab / iPad / second screen in real time — React Flow graphs (architecture, sequence, call-graph, ER/class, state machine, PR-review, journeys, recursion trees), Vega-Lite charts (incl. scientific + Big-O), Mantine UI dashboards & product comparisons, deep-code walkthroughs, markdown, and split panes — with animated edges and live status overlays (toasts, progress bars, loaders). Deterministic Mermaid→ASCII/Unicode is the terminal fallback. Ships persona recipes, a showcase gallery, fullscreen panes, and a collapsible sidebar. Adds /termchart commands + skills, backed by the termchart CLI.",
"version": "0.11.4",
"version": "0.12.0",
"author": {
"name": "Ivan Cheung"
},
Expand Down
24 changes: 21 additions & 3 deletions plugin/skills/diagram-recipes/flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ too-big graph never shrinks to an unreadable thumbnail — it opens at a readabl
### Layout engine — `engine:"sgcr"` (opt-in, ungrouped only)

The default layout is dagre. Set `"engine": "sgcr"` on a `flow` spec to use the
**Slotted Grid + Orthogonal Channel Routing** engine, where node–node overlap, edges-over-nodes,
collinear-edge overlap, and arrowhead stacking are impossible *by construction* (see
`packages/viewer/src/client/renderers/sgcr/README.md`). **Scope today**:
**Slotted Grid + Orthogonal Channel Routing** engine, where node–node overlap, edge-over-node,
collinear-edge overlap, label-on-node, and off-/inside-node arrow endpoints are impossible *by
construction* and re-proved from the output geometry (P1–P10; see
`packages/viewer/src/client/renderers/sgcr/README.md`). Deterministic + order-invariant: same graph →
byte-identical layout. **Scope today**:

- **Ungrouped graphs only.** If the spec uses `group` / `groups` / `lanes:true` / `tiers:true`,
the viewer silently falls back to dagre — the push lint emits an `sgcr-skipped-grouped` warning
Expand All @@ -59,6 +61,22 @@ collinear-edge overlap, and arrowhead stacking are impossible *by construction*
on large graphs can exceed the screen. The lint emits an `sgcr-overflow` warning when that
canvas would visibly spill the reference viewport — split into `panes` or trim nodes.

**Routing & layout modes** (opt-in, on the `flow` spec, with `engine:"sgcr"`):

- **`"routing": "octilinear"`** — straighten orthogonal bends into clean diagonals (≈95% fewer bends).
Good for fan-out meshes (microservices, data lineage, neural nets). High-degree nodes pack their
edges to a shared point rather than ballooning the node. Still node-clear by construction.
- **`"layout": "ring"`** — draw a cycle as a loop (nodes on a circle) instead of a line with a
wrap-around back-edge. For state machines / lifecycles / process loops. Provably clean for simple
cycles; the viewer auto-falls-back to the layered layout for general cyclic graphs.

**Annotations** (`"annotations": [...]`, SGCR only) — overlay callouts/badges/notes on toggleable
layers, placed in the diagram's free space, overlap-free (P10), deferred (not stacked) when there's no
room. Each: `{ id, anchor, text, layer?, color?, priority?, prefer? }` where `anchor` is
`{node:"id"}`, `{edge:"id"}` (give that edge an explicit `id`), or `{at:{x,y}}`. Use distinct `layer`
names (e.g. `"risk"`, `"latency"`, `"owner"`) — the viewer shows a per-layer toggle. Example:
`"annotations":[{"id":"r1","anchor":{"node":"pay"},"text":"SLO gate","layer":"risk"}]`.

### `flow` (React Flow)

`content` is `{ nodes:[{id,data:{label},type?}], edges:[{source,target,label?}], direction?, height?, legend? }`.
Expand Down
Loading