Skip to content
Open
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
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ package-lock.json
schema
test/upstream
docs/DOMAIN-DEPLOYMENT-HANDOFF-*.md
ui/vendor/beautiful-mermaid
docs/design/diagrams/*.svg
8 changes: 8 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@
- Lucide, Lucide contributors, ISC: https://github.com/lucide-icons/lucide
- React Markdown and remark-gfm, unified contributors, MIT:
https://github.com/remarkjs/react-markdown and https://github.com/remarkjs/remark-gfm
- beautiful-mermaid, Craft Docs, MIT: https://github.com/lukilabs/beautiful-mermaid.
Vendored with the AXP "kawaii" edits in `ui/vendor/beautiful-mermaid`;
its license sits beside the source. It depends on ELK (Eclipse Layout
Kernel, EPL-2.0: https://github.com/kieler/elkjs) and entities (BSD-2-Clause),
whose texts the UI build collects.
- Pretext (`@chenglou/pretext`), Pretext contributors, MIT:
https://github.com/chenglou/pretext. Measures diagram labels with the real
font and wraps long ones into balanced lines.
- DM Sans and IBM Plex Mono font packages, SIL Open Font License 1.1:
https://fontsource.org/fonts/dm-sans and https://fontsource.org/fonts/ibm-plex-mono

Expand Down
88 changes: 88 additions & 0 deletions docs/design/diagrams.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Diagrams

## What changed

Fenced ` ```mermaid ` blocks in any prose (agent turns, discussion comments)
now render as inline SVG. The renderer is
[beautiful-mermaid](https://github.com/lukilabs/beautiful-mermaid) by Craft
(MIT), vendored at `ui/vendor/beautiful-mermaid` with a handful of surgical
edits that give every diagram the AXP look. Rendering is synchronous and
DOM-free, so the same code draws the review samples in
`docs/design/diagrams/*.svg` from Node.

Open `docs/design/diagrams/mail-task.svg`, `lease.svg` and `review.svg` to see
a flowchart, a state diagram and nested subgraphs.

## The treatment

The goal was "clean and beautiful, and unmistakably ours" without redrawing the
renderer. Each change is a few lines in `renderer.ts` / `styles.ts` / `theme.ts`,
all marked `AXP:` in the source.

- **Leaf arrowheads.** The spec's triangle became a leaf: pointed tip, two
curved sides, a softly concave base where it meets the stem, and a faint
midrib in the page colour. It is the one detail nobody else has, and it
reads at 100% zoom without shouting.
- **Rounded everything.** Rectangles get a 10px radius, `()` rounded nodes
14px, and every polygon vertex (diamonds, hexagons, trapezoids, flags) is
rounded with a quadratic curve clamped to the shorter adjacent edge, so
small shapes stay sane.
- **Edges as drawn lines.** ELK's orthogonal routing is kept, but each bend is
rounded (10px) and strokes have round caps. Connectors are 1.75px instead of
a 1px hairline; boxes 1.5px.
- **Sticker nodes.** A soft drop shadow (`#axp-soft`, 1.5px down, 13% ink) sits
every node on the page.
- **Garden-bed groups.** Subgraphs are rounded and dashed, with a header band
whose top corners follow the outline.
- **Pill labels** on edges.
- **No remote font `@import`.** Upstream pulls Inter from Google Fonts inside
the SVG; the workspace never loads third-party resources, so the style block
now inherits the page's self-hosted font instead.

Colours come from `ui/src/diagram-theme.ts` and mirror the workspace tokens
(paper background, warm charcoal text, sage lines, leaf-green accent).

## How it is wired

- `ui/src/Diagram.tsx` renders one block with `useMemo`, refuses output that
contains anything script-like, and falls back to the source with the parse
error underneath.
- `ui/src/components.tsx` overrides the Markdown `pre` renderer: a
`language-mermaid` code block becomes `<Diagram>`, loaded lazily. The layout
engine (ELK) is 1.5 MB, so it is a separate chunk fetched only when prose
contains a diagram.
- `ui/types/beautiful-mermaid-axp.d.ts` is the type boundary. Vite resolves
`beautiful-mermaid-axp` to the vendored sources; TypeScript resolves it to
this declaration, so the workspace's strict settings apply to our code
without rewriting upstream's (which fails only `noUnusedLocals`).
- `scripts/design/render-diagrams.mts` regenerates the sample SVGs.

## Real text metrics (Pretext)

beautiful-mermaid sizes nodes from a per-character width table calibrated
for Inter and cannot wrap a long label, so a wordy node became a very wide
box. [Pretext](https://github.com/chenglou/pretext) (MIT) measures text with
the page's real font through canvas, off the DOM, and lays out lines itself.
Two hooks were added to the vendored renderer, both no-ops outside a browser:

- `setTextMeasurer`: exact single-line widths, so boxes fit AXP Runde rather
than an estimate of Inter.
- `setLabelWrapper`: before layout, any node label wider than 190px (edge
label: 140px) is broken into lines; a binary search then narrows the width
until one more line would be needed, so the lines come out balanced
("Checkpoint saved with / the bundle and patch") instead of one long and one
short.

`ui/src/diagram-text.ts` implements both with Pretext and installs them from
`Diagram.tsx`. The Node-side sample renderer keeps the estimates. Evaluated
and kept for this one job; it was not adopted for prose (Justif already sets
paragraphs in the DOM) or for the family photo (no text layout there).

## Not done yet

- Sequence, class and ER diagrams render through their own sub-renderers and
have not received the treatment; flowcharts and state diagrams have.
- The ASCII renderer is vendored but unused. It would let `axp inspect` or
the AAMP result emails draw the same diagrams in plain text.
- A "kawaii" dial (blush dots on decision nodes, a sprout on the start node)
was sketched and left out; the leaf arrowhead carries the identity on its own.
10 changes: 10 additions & 0 deletions docs/design/diagrams/lease.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
stateDiagram-v2
[*] --> Connecting
Connecting --> Parked: claim accepted
Parked --> Working: prompt
Working --> Parked: turn settled
Working --> Reconnecting: socket lost
Reconnecting --> Parked: same epoch
Reconnecting --> Stopped: budget revoked
Parked --> Stopped: Ctrl-C
Stopped --> [*]
97 changes: 97 additions & 0 deletions docs/design/diagrams/lease.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions docs/design/diagrams/mail-task.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
graph TD
A[Email arrives] --> B{Sender allowed?}
B -->|no| C[Warn locally]
B -->|yes| D[Save task]
D --> E([Acknowledge by email])
D --> F{Session free?}
F -->|no| G[Queue behind current turn]
G --> F
F -->|yes| H[Start AHP turn]
H --> I[[Agent works in worktree]]
I --> J{Tool needs approval?}
J -->|yes| K[Ask a maintainer in AXP]
K --> I
J -->|no| L[(Checkpoint saved)]
L --> M([Reply with result])
Loading
Loading